Skip to content

Commit 8395e9b

Browse files
committed
add fallback logic to git_upstream_merge_base
Signed-off-by: onur-ozkan <[email protected]>
1 parent fd17dea commit 8395e9b

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

src/build_helper/src/git.rs

+48-25
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,38 @@ pub fn get_closest_merge_commit(
123123
config: &GitConfig<'_>,
124124
target_paths: &[PathBuf],
125125
) -> Result<String, String> {
126-
let mut git = Command::new("git");
126+
// The need of `--first-parent` is inconsistent. It's sometimes required, sometimes not.
127+
// See https://github.com/rust-lang/rust/issues/101907#issuecomment-2677860377 for more
128+
// context.
129+
//
130+
// FIXME: This is so hacky, is there a more sane way to fix this problem?
131+
let result = match get_closest_merge_commit_impl(git_dir, config, target_paths, true) {
132+
// If the commit is empty, it's most likely because the first parent isn't from rust-lang/rust.
133+
// Fall back to the regular traversal.
134+
Ok(commit) if commit.is_empty() => {
135+
get_closest_merge_commit_impl(git_dir, config, target_paths, false)
136+
}
137+
result => result,
138+
};
127139

128-
if let Some(git_dir) = git_dir {
129-
git.current_dir(git_dir);
130-
}
140+
return result;
141+
142+
fn get_closest_merge_commit_impl(
143+
git_dir: Option<&Path>,
144+
config: &GitConfig<'_>,
145+
target_paths: &[PathBuf],
146+
follow_first_parent_only: bool,
147+
) -> Result<String, String> {
148+
let mut git = Command::new("git");
149+
150+
if let Some(git_dir) = git_dir {
151+
git.current_dir(git_dir);
152+
}
131153

132-
let channel = include_str!("../../ci/channel");
154+
let channel = include_str!("../../ci/channel");
133155

134-
let merge_base = {
135-
if CiEnv::is_ci() &&
156+
let merge_base = {
157+
if CiEnv::is_ci() &&
136158
// FIXME: When running on rust-lang managed CI and it's not a nightly build,
137159
// `git_upstream_merge_base` fails with an error message similar to this:
138160
// ```
@@ -141,28 +163,29 @@ pub fn get_closest_merge_commit(
141163
// ```
142164
// Investigate and resolve this issue instead of skipping it like this.
143165
(channel == "nightly" || !CiEnv::is_rust_lang_managed_ci_job())
144-
{
145-
git_upstream_merge_base(config, git_dir).unwrap()
146-
} else {
147-
// For non-CI environments, ignore rust-lang/rust upstream as it usually gets
148-
// outdated very quickly.
149-
"HEAD".to_string()
166+
{
167+
git_upstream_merge_base(config, git_dir).unwrap()
168+
} else {
169+
// For non-CI environments, ignore rust-lang/rust upstream as it usually gets
170+
// outdated very quickly.
171+
"HEAD".to_string()
172+
}
173+
};
174+
175+
git.args(["rev-list", &format!("--author={}", config.git_merge_commit_email), "-n1"]);
176+
177+
if follow_first_parent_only {
178+
git.arg("--first-parent");
150179
}
151-
};
152180

153-
git.args([
154-
"rev-list",
155-
&format!("--author={}", config.git_merge_commit_email),
156-
"-n1",
157-
"--first-parent",
158-
&merge_base,
159-
]);
181+
git.arg(merge_base);
160182

161-
if !target_paths.is_empty() {
162-
git.arg("--").args(target_paths);
163-
}
183+
if !target_paths.is_empty() {
184+
git.arg("--").args(target_paths);
185+
}
164186

165-
Ok(output_result(&mut git)?.trim().to_owned())
187+
Ok(output_result(&mut git)?.trim().to_owned())
188+
}
166189
}
167190

168191
/// Returns the files that have been modified in the current branch compared to the master branch.

0 commit comments

Comments
 (0)