about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-06-17 20:34:49 +0200
committerGitHub <noreply@github.com>2024-06-17 20:34:49 +0200
commitdcda37573f8cdce048d683ad2bf448da132ae7e3 (patch)
tree3670b43d5a520f6db5cf4531d759ebe298c93309 /src
parent11380368dc53d0b2fc3a627408818eff1973ce9a (diff)
parente3e71404ca9b1c441cbea0c74ab780695ac52907 (diff)
downloadrust-dcda37573f8cdce048d683ad2bf448da132ae7e3.tar.gz
rust-dcda37573f8cdce048d683ad2bf448da132ae7e3.zip
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`
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/src/lib.rs37
-rw-r--r--src/bootstrap/src/utils/helpers.rs10
2 files changed, 27 insertions, 20 deletions
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 @@ impl Build {
             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 @@ impl Build {
             .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 @@ impl Build {
         // 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