Skip to main content

git_pincer/commands/
file.rs

1//! Git-free single-file mode: parse a conflict-marked file and write the resolution back in place.
2
3use std::path::PathBuf;
4
5use anyhow::{Context, Result};
6use clap::Args;
7
8use crate::app::{FileEntry, FileMerge, Session};
9use crate::i18n::{tr, tr_f};
10use crate::merge::parse_conflict_file;
11use crate::ui::{self, Outcome};
12
13/// file 子命令参数。
14#[derive(Debug, Args)]
15pub struct FileArgs {
16    /// 带 `<<<<<<< / ======= / >>>>>>>` 冲突标记的文件路径
17    pub path: PathBuf,
18}
19
20/// 运行单文件冲突解决。
21pub fn run(args: FileArgs, light: bool) -> Result<()> {
22    let text = std::fs::read_to_string(&args.path)
23        .with_context(|| format!("failed to read {}", args.path.display()))?;
24    let result = parse_conflict_file(&text)?;
25    println!(
26        "[git-pincer] {}",
27        tr_f("file.parsed", &[("n", &result.conflicts.to_string())])
28    );
29
30    let display = args.path.display().to_string();
31    let merge = FileMerge::from_result(display.clone(), result, text.ends_with('\n'));
32    let mut session = Session::new(vec![FileEntry::Text(merge)], "file".to_owned());
33
34    let outcome = ui::run_session(
35        &mut session,
36        &mut |_path: &str, bytes: &[u8]| {
37            std::fs::write(&args.path, bytes)?;
38            Ok(())
39        },
40        light,
41    )?;
42    match outcome {
43        Outcome::Completed => println!(
44            "[git-pincer] {}",
45            tr_f("file.written", &[("path", &display)])
46        ),
47        Outcome::Quit => println!("[git-pincer] {}", tr("file.exited")),
48    }
49    Ok(())
50}