commit.rs

 1use crate::Oid;
 2use anyhow::{anyhow, Result};
 3use collections::HashMap;
 4use std::path::Path;
 5use std::process::Command;
 6
 7#[cfg(windows)]
 8use std::os::windows::process::CommandExt;
 9
10pub fn get_messages(working_directory: &Path, shas: &[Oid]) -> Result<HashMap<Oid, String>> {
11    if shas.is_empty() {
12        return Ok(HashMap::default());
13    }
14
15    const MARKER: &str = "<MARKER>";
16
17    let mut command = Command::new("git");
18
19    command
20        .current_dir(working_directory)
21        .arg("show")
22        .arg("-s")
23        .arg(format!("--format=%B{}", MARKER))
24        .args(shas.iter().map(ToString::to_string));
25
26    #[cfg(windows)]
27    command.creation_flags(windows::Win32::System::Threading::CREATE_NO_WINDOW.0);
28
29    let output = command
30        .output()
31        .map_err(|e| anyhow!("Failed to start git blame process: {}", e))?;
32
33    anyhow::ensure!(
34        output.status.success(),
35        "'git show' failed with error {:?}",
36        output.status
37    );
38
39    Ok(shas
40        .iter()
41        .cloned()
42        .zip(
43            String::from_utf8_lossy(&output.stdout)
44                .trim()
45                .split_terminator(MARKER)
46                .map(|str| str.trim().replace("<", "&lt;").replace(">", "&gt;")),
47        )
48        .collect::<HashMap<Oid, String>>())
49}