From 5a9b9a385f3ab90d225ae82b735ba92280d73b6d Mon Sep 17 00:00:00 2001 From: binarycat Date: Sun, 8 Sep 2024 16:57:22 -0400 Subject: [PATCH] bootstrap: handle worktrees in warn_old_master_branch fixes #130111 --- src/bootstrap/src/core/sanity.rs | 10 +---- src/tools/build_helper/src/git.rs | 62 +++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index dbc712adadf3e..10f7c2e13642e 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -378,13 +378,5 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake cmd_finder.must_have(s); } - // this warning is useless in CI, - // and CI probably won't have the right branches anyway. - if !build_helper::ci::CiEnv::is_ci() { - if let Err(e) = warn_old_master_branch(&build.config.git_config(), &build.config.src) - .map_err(|e| e.to_string()) - { - eprintln!("unable to check if upstream branch is old: {e}"); - } - } + warn_old_master_branch(&build.config.git_config(), &build.config.src); } diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs index cc48a8964a372..bda0c6340a7ae 100644 --- a/src/tools/build_helper/src/git.rs +++ b/src/tools/build_helper/src/git.rs @@ -167,21 +167,20 @@ pub fn get_git_untracked_files( /// /// This can result in formatting thousands of files instead of a dozen, /// so we should warn the user something is wrong. -pub fn warn_old_master_branch( - config: &GitConfig<'_>, - git_dir: &Path, -) -> Result<(), Box> { - use std::time::Duration; - const WARN_AFTER: Duration = Duration::from_secs(60 * 60 * 24 * 10); - let updated_master = updated_master_branch(config, Some(git_dir))?; - let branch_path = git_dir.join(".git/refs/remotes").join(&updated_master); - match std::fs::metadata(branch_path) { - Ok(meta) => { - if meta.modified()?.elapsed()? > WARN_AFTER { - eprintln!("warning: {updated_master} has not been updated in 10 days"); - } else { - return Ok(()); +pub fn warn_old_master_branch(config: &GitConfig<'_>, git_dir: &Path) { + if crate::ci::CiEnv::is_ci() { + // this warning is useless in CI, + // and CI probably won't have the right branches anyway. + return; + } + // this will be overwritten by the actual name, if possible + let mut updated_master = "the upstream master branch".to_string(); + match warn_old_master_branch_(config, git_dir, &mut updated_master) { + Ok(branch_is_old) => { + if !branch_is_old { + return; } + // otherwise fall through and print the rest of the warning } Err(err) => { eprintln!("warning: unable to check if {updated_master} is old due to error: {err}") @@ -189,7 +188,38 @@ pub fn warn_old_master_branch( } eprintln!( "warning: {updated_master} is used to determine if files have been modified\n\ - warning: if it is not updated, this may cause files to be needlessly reformatted" + warning: if it is not updated, this may cause files to be needlessly reformatted" ); - Ok(()) +} + +pub fn warn_old_master_branch_( + config: &GitConfig<'_>, + git_dir: &Path, + updated_master: &mut String, +) -> Result> { + use std::time::Duration; + *updated_master = updated_master_branch(config, Some(git_dir))?; + let branch_path = git_dir.join(".git/refs/remotes").join(&updated_master); + const WARN_AFTER: Duration = Duration::from_secs(60 * 60 * 24 * 10); + let meta = match std::fs::metadata(&branch_path) { + Ok(meta) => meta, + Err(err) => { + let gcd = git_common_dir(&git_dir)?; + if branch_path.starts_with(&gcd) { + return Err(Box::new(err)); + } + std::fs::metadata(Path::new(&gcd).join("refs/remotes").join(&updated_master))? + } + }; + if meta.modified()?.elapsed()? > WARN_AFTER { + eprintln!("warning: {updated_master} has not been updated in 10 days"); + Ok(true) + } else { + Ok(false) + } +} + +fn git_common_dir(dir: &Path) -> Result { + output_result(Command::new("git").arg("-C").arg(dir).arg("rev-parse").arg("--git-common-dir")) + .map(|x| x.trim().to_string()) }