1
0
mirror of https://github.com/j178/prek.git synced 2026-03-24 01:20:26 +02:00

Support refs to trees (#1449)

* Support refs to trees

* Add test

* Add fallback

* style

* fixup
This commit is contained in:
Jules Tamagnan
2026-01-21 19:00:12 -08:00
committed by GitHub
parent 41e2b73246
commit 1ea64fcb4a
2 changed files with 77 additions and 9 deletions

View File

@@ -117,15 +117,31 @@ pub(crate) async fn get_changed_files(
new: &str,
root: &Path,
) -> Result<Vec<PathBuf>, Error> {
let output = git_cmd("get changed files")?
.arg("diff")
.arg("--name-only")
.arg("--diff-filter=ACMRT")
.arg("--no-ext-diff") // Disable external diff drivers
.arg("-z") // Use NUL as line terminator
.arg(format!("{old}...{new}"))
.arg("--")
.arg(root)
let build_cmd = |range: String| -> Result<Cmd, Error> {
let mut cmd = git_cmd("get changed files")?;
cmd.arg("diff")
.arg("--name-only")
.arg("--diff-filter=ACMRT")
.arg("--no-ext-diff") // Disable external diff drivers
.arg("-z") // Use NUL as line terminator
.arg(range)
.arg("--")
.arg(root);
Ok(cmd)
};
// Try three-dot syntax first (merge-base diff), which works for commits
let output = build_cmd(format!("{old}...{new}"))?
.check(false)
.output()
.await?;
if output.status.success() {
return Ok(zsplit(&output.stdout)?);
}
// Fall back to two-dot syntax, which works with both commits and trees
let output = build_cmd(format!("{old}..{new}"))?
.check(true)
.output()
.await?;

View File

@@ -2932,3 +2932,55 @@ fn expands_tilde_in_prek_home() -> Result<()> {
Ok(())
}
#[test]
fn run_with_tree_object_as_ref() -> Result<()> {
let context = TestContext::new();
context.init_project();
context.configure_git_author();
let cwd = context.work_dir();
context.write_pre_commit_config(indoc::indoc! {r"
repos:
- repo: local
hooks:
- id: echo-files
name: echo files
entry: echo
language: system
pass_filenames: true
"});
// Create initial commit
cwd.child("file1.txt").write_str("hello")?;
context.git_add(".");
context.git_commit("Initial commit");
// Create some changes and stage them
cwd.child("file2.txt").write_str("world")?;
context.git_add("file2.txt");
// Get the tree object from the staged changes
let tree_output = Command::new("git")
.arg("write-tree")
.current_dir(cwd)
.output()
.expect("Failed to run git write-tree");
let tree_sha = String::from_utf8_lossy(&tree_output.stdout)
.trim()
.to_string();
// Run prek with tree object as to-ref (should work with .. syntax)
cmd_snapshot!(context.filters(), context.run()
.arg("--from-ref").arg("HEAD")
.arg("--to-ref").arg(&tree_sha), @r"
success: true
exit_code: 0
----- stdout -----
echo files...............................................................Passed
----- stderr -----
");
Ok(())
}