diff --git a/crates/prek/src/store.rs b/crates/prek/src/store.rs index 53bcb2b99..a124fc71d 100644 --- a/crates/prek/src/store.rs +++ b/crates/prek/src/store.rs @@ -372,8 +372,13 @@ impl Store { config_paths: impl Iterator, ) -> Result<(), Error> { let mut tracked = self.tracked_configs()?; + let mut changed = false; for config_path in config_paths { - tracked.insert(config_path.to_path_buf()); + changed |= tracked.insert(config_path.to_path_buf()); + } + + if !changed { + return Ok(()); } let tracking_file = self.config_tracking_file(); diff --git a/crates/prek/tests/run.rs b/crates/prek/tests/run.rs index 9c04a7057..7dea66541 100644 --- a/crates/prek/tests/run.rs +++ b/crates/prek/tests/run.rs @@ -1,4 +1,5 @@ use std::path::Path; +use std::time::SystemTime; use anyhow::Result; use assert_cmd::assert::OutputAssertExt; @@ -75,6 +76,49 @@ fn run_basic() -> Result<()> { Ok(()) } +#[test] +fn run_does_not_rewrite_unchanged_config_tracking_file() -> Result<()> { + let context = TestContext::new(); + context.init_project(); + + context.write_pre_commit_config(indoc::indoc! {r#" + repos: + - repo: local + hooks: + - id: noop + name: Noop + language: system + entry: "true" + always_run: true + "#}); + context.git_add("."); + + context.run().arg("--all-files").assert().success(); + + let tracking_file = context.home_dir().child("config-tracking.json"); + tracking_file.assert(predicate::path::is_file()); + let original_content = fs_err::read_to_string(tracking_file.path())?; + + fs_err::OpenOptions::new() + .write(true) + .open(tracking_file.path())? + .set_modified(SystemTime::UNIX_EPOCH)?; + let original_modified = fs_err::metadata(tracking_file.path())?.modified()?; + + context.run().arg("--all-files").assert().success(); + + assert_eq!( + fs_err::read_to_string(tracking_file.path())?, + original_content + ); + assert_eq!( + fs_err::metadata(tracking_file.path())?.modified()?, + original_modified + ); + + Ok(()) +} + #[test] fn run_glob_patterns_with_multiple_hooks() -> Result<()> { let context = TestContext::new();