Skip to content

Commit bdc3ed5

Browse files
committed
bootstrap: use git merge-base for LLVM CI download logic
1 parent 4a07b2b commit bdc3ed5

File tree

2 files changed

+28
-19
lines changed

2 files changed

+28
-19
lines changed

src/bootstrap/llvm.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::util::{self, exe, output, t, up_to_date};
2424
use crate::{CLang, GitRepo, Kind};
2525

2626
use build_helper::ci::CiEnv;
27+
use build_helper::git::get_git_merge_base;
2728

2829
#[derive(Clone)]
2930
pub struct LlvmResult {
@@ -128,13 +129,19 @@ pub fn prebuilt_llvm_config(
128129
/// This retrieves the LLVM sha we *want* to use, according to git history.
129130
pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
130131
let llvm_sha = if is_git {
132+
// We proceed in 2 steps. First we get the closest commit that is actually upstream. Then we
133+
// walk back further to the last bors merge commit that actually changed LLVM. The first
134+
// step will fail on CI because only the `auto` branch exists; we just fall back to `HEAD`
135+
// in that case.
136+
let closest_upstream =
137+
get_git_merge_base(Some(&config.src)).unwrap_or_else(|_| "HEAD".into());
131138
let mut rev_list = config.git();
132139
rev_list.args(&[
133140
PathBuf::from("rev-list"),
134141
format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
135142
"-n1".into(),
136143
"--first-parent".into(),
137-
"HEAD".into(),
144+
closest_upstream.into(),
138145
"--".into(),
139146
config.src.join("src/llvm-project"),
140147
config.src.join("src/bootstrap/download-ci-llvm-stamp"),

src/tools/build_helper/src/git.rs

+20-18
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,22 @@ pub fn rev_exists(rev: &str, git_dir: Option<&Path>) -> Result<bool, String> {
7878
/// We will then fall back to origin/master in the hope that at least this exists.
7979
pub fn updated_master_branch(git_dir: Option<&Path>) -> Result<String, String> {
8080
let upstream_remote = get_rust_lang_rust_remote(git_dir)?;
81-
let upstream_master = format!("{upstream_remote}/master");
82-
if rev_exists(&upstream_master, git_dir)? {
83-
return Ok(upstream_master);
81+
for upstream_master in [format!("{upstream_remote}/master"), format!("origin/master")] {
82+
if rev_exists(&upstream_master, git_dir)? {
83+
return Ok(upstream_master);
84+
}
8485
}
8586

86-
// We could implement smarter logic here in the future.
87-
Ok("origin/master".into())
87+
Err(format!("Cannot find any suitable upstream master branch"))
88+
}
89+
90+
pub fn get_git_merge_base(git_dir: Option<&Path>) -> Result<String, String> {
91+
let updated_master = updated_master_branch(git_dir)?;
92+
let mut git = Command::new("git");
93+
if let Some(git_dir) = git_dir {
94+
git.current_dir(git_dir);
95+
}
96+
Ok(output_result(git.arg("merge-base").arg(&updated_master).arg("HEAD"))?.trim().to_owned())
8897
}
8998

9099
/// Returns the files that have been modified in the current branch compared to the master branch.
@@ -94,20 +103,13 @@ pub fn get_git_modified_files(
94103
git_dir: Option<&Path>,
95104
extensions: &Vec<&str>,
96105
) -> Result<Option<Vec<String>>, String> {
97-
let Ok(updated_master) = updated_master_branch(git_dir) else {
98-
return Ok(None);
99-
};
100-
101-
let git = || {
102-
let mut git = Command::new("git");
103-
if let Some(git_dir) = git_dir {
104-
git.current_dir(git_dir);
105-
}
106-
git
107-
};
106+
let merge_base = get_git_merge_base(git_dir)?;
108107

109-
let merge_base = output_result(git().arg("merge-base").arg(&updated_master).arg("HEAD"))?;
110-
let files = output_result(git().arg("diff-index").arg("--name-only").arg(merge_base.trim()))?
108+
let mut git = Command::new("git");
109+
if let Some(git_dir) = git_dir {
110+
git.current_dir(git_dir);
111+
}
112+
let files = output_result(git.arg("diff-index").arg("--name-only").arg(merge_base.trim()))?
111113
.lines()
112114
.map(|s| s.trim().to_owned())
113115
.filter(|f| {

0 commit comments

Comments
 (0)