Skip to content

Commit dc7d60f

Browse files
committed
fix checking git submodules during a commit hook
1 parent d402830 commit dc7d60f

File tree

3 files changed

+41
-47
lines changed

3 files changed

+41
-47
lines changed

src/bootstrap/src/core/config/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2095,7 +2095,7 @@ impl Config {
20952095
/// Use this rather than `Command::new("git")` in order to support out-of-tree builds.
20962096
pub(crate) fn git(&self) -> Command {
20972097
let mut git = Command::new("git");
2098-
git.current_dir(&self.src);
2098+
git.arg("--git-dir").arg(self.src.join(".git"));
20992099
git
21002100
}
21012101

src/bootstrap/src/lib.rs

+28-32
Original file line numberDiff line numberDiff line change
@@ -520,34 +520,34 @@ impl Build {
520520
return;
521521
}
522522

523-
// check_submodule
524-
let checked_out_hash =
525-
output(Command::new("git").args(["rev-parse", "HEAD"]).current_dir(&absolute_path));
526-
// update_submodules
527-
let recorded = output(
528-
Command::new("git")
529-
.args(["ls-tree", "HEAD"])
530-
.arg(relative_path)
531-
.current_dir(&self.config.src),
532-
);
523+
let mut submodule_git = absolute_path;
524+
submodule_git.push(".git");
525+
let submodule_git = move || {
526+
let mut cmd = Command::new("git");
527+
// We use `--git-dir` instead of `current_dir` since in a commit hook,
528+
// some env var is set that makes `current_dir` not have any effect.
529+
// See <https://github.com/rust-lang/rust/issues/125954>.
530+
cmd.arg("--git-dir").arg(&submodule_git);
531+
cmd
532+
};
533+
534+
// Determine commit checked out in submodule.
535+
let checked_out_hash = output(submodule_git().args(["rev-parse", "HEAD"]));
536+
let checked_out_hash = checked_out_hash.trim_end();
537+
// Determine commit that the submodule *should* have.
538+
let recorded = output(self.config.git().args(["ls-tree", "HEAD"]).arg(relative_path));
533539
let actual_hash = recorded
534540
.split_whitespace()
535541
.nth(2)
536542
.unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
537543

538-
// update_submodule
539-
if actual_hash == checked_out_hash.trim_end() {
544+
if actual_hash == checked_out_hash {
540545
// already checked out
541546
return;
542547
}
543548

544549
println!("Updating submodule {}", relative_path.display());
545-
self.run(
546-
Command::new("git")
547-
.args(["submodule", "-q", "sync"])
548-
.arg(relative_path)
549-
.current_dir(&self.config.src),
550-
);
550+
self.run(self.config.git().args(["submodule", "-q", "sync"]).arg(relative_path));
551551

552552
// Try passing `--progress` to start, then run git again without if that fails.
553553
let update = |progress: bool| {
@@ -590,26 +590,22 @@ impl Build {
590590
// Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
591591
// diff-index reports the modifications through the exit status
592592
let has_local_modifications = !self.run_cmd(
593-
BootstrapCommand::from(
594-
Command::new("git")
595-
.args(["diff-index", "--quiet", "HEAD"])
596-
.current_dir(&absolute_path),
597-
)
598-
.allow_failure()
599-
.output_mode(match self.is_verbose() {
600-
true => OutputMode::PrintAll,
601-
false => OutputMode::PrintOutput,
602-
}),
593+
BootstrapCommand::from(submodule_git().args(["diff-index", "--quiet", "HEAD"]))
594+
.allow_failure()
595+
.output_mode(match self.is_verbose() {
596+
true => OutputMode::PrintAll,
597+
false => OutputMode::PrintOutput,
598+
}),
603599
);
604600
if has_local_modifications {
605-
self.run(Command::new("git").args(["stash", "push"]).current_dir(&absolute_path));
601+
self.run(submodule_git().args(["stash", "push"]));
606602
}
607603

608-
self.run(Command::new("git").args(["reset", "-q", "--hard"]).current_dir(&absolute_path));
609-
self.run(Command::new("git").args(["clean", "-qdfx"]).current_dir(&absolute_path));
604+
self.run(submodule_git().args(["reset", "-q", "--hard"]));
605+
self.run(submodule_git().args(["clean", "-qdfx"]));
610606

611607
if has_local_modifications {
612-
self.run(Command::new("git").args(["stash", "pop"]).current_dir(absolute_path));
608+
self.run(submodule_git().args(["stash", "pop"]));
613609
}
614610
}
615611

src/bootstrap/src/utils/channel.rs

+12-14
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,22 @@ pub struct Info {
3535

3636
impl GitInfo {
3737
pub fn new(omit_git_hash: bool, dir: &Path) -> GitInfo {
38+
let git_dir = dir.join(".git");
3839
// See if this even begins to look like a git dir
39-
if !dir.join(".git").exists() {
40+
if !git_dir.exists() {
4041
match read_commit_info_file(dir) {
4142
Some(info) => return GitInfo::RecordedForTarball(info),
4243
None => return GitInfo::Absent,
4344
}
4445
}
46+
let git = || {
47+
let mut cmd = Command::new("git");
48+
cmd.arg("--git-dir").arg(&git_dir);
49+
cmd
50+
};
4551

4652
// Make sure git commands work
47-
match Command::new("git").arg("rev-parse").current_dir(dir).output() {
53+
match git().arg("rev-parse").output() {
4854
Ok(ref out) if out.status.success() => {}
4955
_ => return GitInfo::Absent,
5056
}
@@ -56,18 +62,10 @@ impl GitInfo {
5662
}
5763

5864
// Ok, let's scrape some info
59-
let ver_date = output(
60-
Command::new("git")
61-
.current_dir(dir)
62-
.arg("log")
63-
.arg("-1")
64-
.arg("--date=short")
65-
.arg("--pretty=format:%cd"),
66-
);
67-
let ver_hash = output(Command::new("git").current_dir(dir).arg("rev-parse").arg("HEAD"));
68-
let short_ver_hash = output(
69-
Command::new("git").current_dir(dir).arg("rev-parse").arg("--short=9").arg("HEAD"),
70-
);
65+
let ver_date =
66+
output(git().arg("log").arg("-1").arg("--date=short").arg("--pretty=format:%cd"));
67+
let ver_hash = output(git().arg("rev-parse").arg("HEAD"));
68+
let short_ver_hash = output(git().arg("rev-parse").arg("--short=9").arg("HEAD"));
7169
GitInfo::Present(Some(Info {
7270
commit_date: ver_date.trim().to_string(),
7371
sha: ver_hash.trim().to_string(),

0 commit comments

Comments
 (0)