Skip to content

Commit 6248f9d

Browse files
authored
Unrolled build for #148500
Rollup merge of #148500 - Kobzol:git-update-inex, r=jieyouxu Update git index before running diff-index Discussed in https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/tidy.3A.20strange.20number.20of.20modified.20files/with/553714742. This is apparently the cause of `x test tidy` printing weird number of formatted files, and also of sometimes quirky behavior of finding the files modified from a base commit.
2 parents 11339a0 + 69da9af commit 6248f9d

File tree

1 file changed

+46
-29
lines changed

1 file changed

+46
-29
lines changed

src/build_helper/src/git.rs

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,13 @@ pub fn check_path_modifications(
143143

144144
/// Returns true if any of the passed `paths` have changed since the `base` commit.
145145
pub fn has_changed_since(git_dir: &Path, base: &str, paths: &[&str]) -> bool {
146-
let mut git = Command::new("git");
147-
git.current_dir(git_dir);
146+
run_git_diff_index(Some(git_dir), |cmd| {
147+
cmd.args(["--quiet", base, "--"]).args(paths);
148148

149-
git.args(["diff-index", "--quiet", base, "--"]).args(paths);
150-
151-
// Exit code 0 => no changes
152-
// Exit code 1 => some changes were detected
153-
!git.status().expect("cannot run git diff-index").success()
149+
// Exit code 0 => no changes
150+
// Exit code 1 => some changes were detected
151+
!cmd.status().expect("cannot run git diff-index").success()
152+
})
154153
}
155154

156155
/// Returns the latest upstream commit that modified `target_paths`, or `None` if no such commit
@@ -267,31 +266,49 @@ pub fn get_git_modified_files(
267266
return Err("No upstream commit was found".to_string());
268267
};
269268

270-
let mut git = Command::new("git");
271-
if let Some(git_dir) = git_dir {
272-
git.current_dir(git_dir);
273-
}
274-
let files = output_result(git.args(["diff-index", "--name-status", merge_base.trim()]))?
275-
.lines()
276-
.filter_map(|f| {
277-
let (status, name) = f.trim().split_once(char::is_whitespace).unwrap();
278-
if status == "D" {
279-
None
280-
} else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| {
281-
// If there is no extension, we allow the path if `extensions` is empty
282-
// If there is an extension, we allow it if `extension` is empty or it contains the
283-
// extension.
284-
extensions.is_empty() || extensions.contains(&ext.to_str().unwrap())
285-
}) {
286-
Some(name.to_owned())
287-
} else {
288-
None
289-
}
290-
})
291-
.collect();
269+
let files = run_git_diff_index(git_dir, |cmd| {
270+
output_result(cmd.args(["--name-status", merge_base.trim()]))
271+
})?
272+
.lines()
273+
.filter_map(|f| {
274+
let (status, name) = f.trim().split_once(char::is_whitespace).unwrap();
275+
if status == "D" {
276+
None
277+
} else if Path::new(name).extension().map_or(extensions.is_empty(), |ext| {
278+
// If there is no extension, we allow the path if `extensions` is empty
279+
// If there is an extension, we allow it if `extension` is empty or it contains the
280+
// extension.
281+
extensions.is_empty() || extensions.contains(&ext.to_str().unwrap())
282+
}) {
283+
Some(name.to_owned())
284+
} else {
285+
None
286+
}
287+
})
288+
.collect();
292289
Ok(files)
293290
}
294291

292+
/// diff-index can return outdated information, because it does not update the git index.
293+
/// This function uses `update-index` to update the index first, and then provides `func` with a
294+
/// command prepared to run `git diff-index`.
295+
fn run_git_diff_index<F, T>(git_dir: Option<&Path>, func: F) -> T
296+
where
297+
F: FnOnce(&mut Command) -> T,
298+
{
299+
let git = || {
300+
let mut git = Command::new("git");
301+
if let Some(git_dir) = git_dir {
302+
git.current_dir(git_dir);
303+
}
304+
git
305+
};
306+
307+
// We ignore the exit code, as it errors out when some files are modified.
308+
let _ = output_result(git().args(["update-index", "--refresh", "-q"]));
309+
func(git().arg("diff-index"))
310+
}
311+
295312
/// Returns the files that haven't been added to git yet.
296313
pub fn get_git_untracked_files(git_dir: Option<&Path>) -> Result<Option<Vec<String>>, String> {
297314
let mut git = Command::new("git");

0 commit comments

Comments
 (0)