Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion crates/prek/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,12 @@ pub(crate) async fn has_worktree_diff(path: &Path) -> Result<bool, Error> {
pub(crate) async fn diff_worktree(path: &Path) -> Result<Vec<u8>, Error> {
let output = git_cmd()?
.arg("diff")
.hidden_args(["--no-ext-diff", "--no-textconv", "--ignore-submodules"])
.hidden_args([
"--full-index",
"--no-ext-diff",
"--no-textconv",
"--ignore-submodules",
])
.arg("--")
.arg(path)
// This diff is only used as a best-effort before/after snapshot of
Expand Down
57 changes: 57 additions & 0 deletions crates/prek/tests/skipped_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,63 @@ fn modifying_hook_uses_clean_baseline_diff_detection() -> Result<()> {
Ok(())
}

#[test]
fn binary_diff_snapshots_use_full_object_ids() -> Result<()> {
let context = TestContext::new();
let cwd = context.work_dir();
let status = git_cmd(cwd)
.args(["init", "--object-format=sha1"])
.status()?;
assert!(
status.success(),
"initializing SHA-1 repository should succeed"
);

context.write_pre_commit_config(indoc::indoc! {r#"
repos:
- repo: local
hooks:
- id: write-first
name: write-first
language: system
entry: python3 -c "from pathlib import Path; Path('binary.dat').write_bytes(b'variant-20663\n')"
pass_filenames: false
priority: 0
- id: write-second
name: write-second
language: system
entry: python3 -c "from pathlib import Path; Path('binary.dat').write_bytes(b'variant-30375\n')"
pass_filenames: false
priority: 1
"#});

// The two replacement blobs have distinct SHA-1s whose first seven
// hexadecimal digits are both `4b8e34c`.
cwd.child(".gitattributes")
.write_str("binary.dat -diff\n")?;
cwd.child("binary.dat").write_str("original\n")?;
context.git_add(".");

let status = git_cmd(cwd).args(["config", "core.abbrev", "7"]).status()?;
assert!(status.success(), "setting core.abbrev should succeed");

let output = context.run().output()?;
assert!(
!output.status.success(),
"both hooks should modify the file"
);

let stdout = String::from_utf8_lossy(&output.stdout);
assert_eq!(
stdout.matches("files were modified by this hook").count(),
2,
"both binary rewrites should produce distinct snapshots.\n\
stdout:\n{stdout}"
);

Ok(())
}

#[test]
fn all_files_with_existing_unstaged_changes_uses_snapshot_baseline() -> Result<()> {
let context = TestContext::new();
Expand Down
Loading