Update git index before running diff-index · rust-lang/rust@69da9af (original) (raw)
`@@ -143,14 +143,13 @@ pub fn check_path_modifications(
`
143
143
``
144
144
`` /// Returns true if any of the passed paths have changed since the base commit.
``
145
145
`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);
`
148
148
``
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
`+
})
`
154
153
`}
`
155
154
``
156
155
`` /// 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(
`
267
266
`return Err("No upstream commit was found".to_string());
`
268
267
`};
`
269
268
``
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();
`
292
289
`Ok(files)
`
293
290
`}
`
294
291
``
``
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
+
295
312
`/// Returns the files that haven't been added to git yet.
`
296
313
`pub fn get_git_untracked_files(git_dir: Option<&Path>) -> Result<Option<Vec>, String> {
`
297
314
`let mut git = Command::new("git");
`