Rollup merge of #126255 - RalfJung:bootstrap-submodules, r=onur-ozkan

fix checking git submodules during a commit hook

Fixes https://github.com/rust-lang/rust/issues/125954
The one thing that still puzzles me is why this only is a problem with worktrees.

r? `@onur`
This commit is contained in:
Matthias Krüger 2024-06-17 20:34:49 +02:00 committed by GitHub
commit dcda37573f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 20 deletions

View File

@ -520,10 +520,12 @@ pub(crate) fn update_submodule(&self, relative_path: &Path) {
return; return;
} }
// check_submodule let submodule_git = || helpers::git(Some(&absolute_path));
let checked_out_hash =
output(helpers::git(Some(&absolute_path)).args(["rev-parse", "HEAD"])); // Determine commit checked out in submodule.
// update_submodules let checked_out_hash = output(submodule_git().args(["rev-parse", "HEAD"]));
let checked_out_hash = checked_out_hash.trim_end();
// Determine commit that the submodule *should* have.
let recorded = let recorded =
output(helpers::git(Some(&self.src)).args(["ls-tree", "HEAD"]).arg(relative_path)); output(helpers::git(Some(&self.src)).args(["ls-tree", "HEAD"]).arg(relative_path));
let actual_hash = recorded let actual_hash = recorded
@ -531,8 +533,7 @@ pub(crate) fn update_submodule(&self, relative_path: &Path) {
.nth(2) .nth(2)
.unwrap_or_else(|| panic!("unexpected output `{}`", recorded)); .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
// update_submodule if actual_hash == checked_out_hash {
if actual_hash == checked_out_hash.trim_end() {
// already checked out // already checked out
return; return;
} }
@ -581,26 +582,22 @@ pub(crate) fn update_submodule(&self, relative_path: &Path) {
// Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
// diff-index reports the modifications through the exit status // diff-index reports the modifications through the exit status
let has_local_modifications = !self.run_cmd( let has_local_modifications = !self.run_cmd(
BootstrapCommand::from(helpers::git(Some(&absolute_path)).args([ BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"]))
"diff-index", .allow_failure()
"--quiet", .output_mode(match self.is_verbose() {
"HEAD", true => OutputMode::PrintAll,
])) false => OutputMode::PrintOutput,
.allow_failure() }),
.output_mode(match self.is_verbose() {
true => OutputMode::PrintAll,
false => OutputMode::PrintOutput,
}),
); );
if has_local_modifications { if has_local_modifications {
self.run(helpers::git(Some(&absolute_path)).args(["stash", "push"])); self.run(submodule_git().args(["stash", "push"]));
} }
self.run(helpers::git(Some(&absolute_path)).args(["reset", "-q", "--hard"])); self.run(submodule_git().args(["reset", "-q", "--hard"]));
self.run(helpers::git(Some(&absolute_path)).args(["clean", "-qdfx"])); self.run(submodule_git().args(["clean", "-qdfx"]));
if has_local_modifications { if has_local_modifications {
self.run(helpers::git(Some(&absolute_path)).args(["stash", "pop"])); self.run(submodule_git().args(["stash", "pop"]));
} }
} }

View File

@ -501,6 +501,16 @@ pub fn git(source_dir: Option<&Path>) -> Command {
if let Some(source_dir) = source_dir { if let Some(source_dir) = source_dir {
git.current_dir(source_dir); git.current_dir(source_dir);
// If we are running inside git (e.g. via a hook), `GIT_DIR` is set and takes precedence
// over the current dir. Un-set it to make the current dir matter.
git.env_remove("GIT_DIR");
// Also un-set some other variables, to be on the safe side (based on cargo's
// `fetch_with_cli`). In particular un-setting `GIT_INDEX_FILE` is required to fix some odd
// misbehavior.
git.env_remove("GIT_WORK_TREE")
.env_remove("GIT_INDEX_FILE")
.env_remove("GIT_OBJECT_DIRECTORY")
.env_remove("GIT_ALTERNATE_OBJECT_DIRECTORIES");
} }
git git