diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index abf407ea91e..449d8c128ec 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -520,10 +520,12 @@ pub(crate) fn update_submodule(&self, relative_path: &Path) { return; } - // check_submodule - let checked_out_hash = - output(helpers::git(Some(&absolute_path)).args(["rev-parse", "HEAD"])); - // update_submodules + let submodule_git = || helpers::git(Some(&absolute_path)); + + // Determine commit checked out in submodule. + 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 = output(helpers::git(Some(&self.src)).args(["ls-tree", "HEAD"]).arg(relative_path)); let actual_hash = recorded @@ -531,8 +533,7 @@ pub(crate) fn update_submodule(&self, relative_path: &Path) { .nth(2) .unwrap_or_else(|| panic!("unexpected output `{}`", recorded)); - // update_submodule - if actual_hash == checked_out_hash.trim_end() { + if actual_hash == checked_out_hash { // already checked out 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). // diff-index reports the modifications through the exit status let has_local_modifications = !self.run_cmd( - BootstrapCommand::from(helpers::git(Some(&absolute_path)).args([ - "diff-index", - "--quiet", - "HEAD", - ])) - .allow_failure() - .output_mode(match self.is_verbose() { - true => OutputMode::PrintAll, - false => OutputMode::PrintOutput, - }), + BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"])) + .allow_failure() + .output_mode(match self.is_verbose() { + true => OutputMode::PrintAll, + false => OutputMode::PrintOutput, + }), ); 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(helpers::git(Some(&absolute_path)).args(["clean", "-qdfx"])); + self.run(submodule_git().args(["reset", "-q", "--hard"])); + self.run(submodule_git().args(["clean", "-qdfx"])); if has_local_modifications { - self.run(helpers::git(Some(&absolute_path)).args(["stash", "pop"])); + self.run(submodule_git().args(["stash", "pop"])); } } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 13d1346b3d9..4b6dc45b436 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -501,6 +501,16 @@ pub fn git(source_dir: Option<&Path>) -> Command { if let Some(source_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