pub(crate) fn read_working_tree_file(path: &str) -> std::io::Result<String> {
std::fs::read_to_string(path)
}
pub(crate) fn read_git_show_file(
cwd: Option<&std::path::Path>,
head: &str,
path: &str,
) -> std::io::Result<String> {
let object = format!("{head}:{path}");
let mut command = std::process::Command::new("git");
command.args(["show", &object]);
if let Some(cwd) = cwd {
command.current_dir(cwd);
}
let output = command.output()?;
if !output.status.success() {
return Err(std::io::Error::other(format!(
"git show {object} failed: {}",
String::from_utf8_lossy(&output.stderr)
)));
}
String::from_utf8(output.stdout)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_util::init_repo_with_committed_file;
use pretty_assertions::assert_eq;
#[test]
fn should_read_committed_content_when_working_tree_is_dirty() {
let dir = tempfile::TempDir::new().expect("create tempdir");
let committed = "fn foo(a: i32) -> i32 {\n a\n}\n";
init_repo_with_committed_file(dir.path(), committed);
std::fs::write(
dir.path().join("src/lib.rs"),
"fn foo(a: i32) -> i32 {\n a + 999\n}\n",
)
.expect("dirty the working tree");
let actual = read_git_show_file(Some(dir.path()), "HEAD", "src/lib.rs")
.expect("git show should succeed for a committed file");
assert_eq!(committed, actual);
}
}