Skip to content

Commit dd7a743

Browse files
authored
Merge pull request #85 from rust-lang/pa-fix-commit-walking
Only search `src/version` in rust-lang/rust, not subtrees
2 parents 219ca7f + f01adc0 commit dd7a743

File tree

1 file changed

+40
-37
lines changed

1 file changed

+40
-37
lines changed

src/github.rs

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -355,51 +355,48 @@ impl RepositoryClient<'_> {
355355
start: &str,
356356
path: &str,
357357
) -> anyhow::Result<FullCommitData> {
358-
self.start_new_request()?;
359-
self.client.get(true)?;
360-
self.client.url(&format!(
361-
"https://api.github.com/repos/{repo}/commits/{start}",
362-
repo = self.repo
363-
))?;
364-
let resolved_start = self
365-
.client
366-
.without_body()
367-
.send_with_response::<CommitData>()?
368-
.sha;
369-
for page in 1..20 {
358+
const MAX_COMMITS: usize = 200;
359+
const BORS_EMAIL: &str = "bors@rust-lang.org";
360+
361+
let mut commit = start.to_string();
362+
let mut scanned_commits = 0;
363+
for _ in 0..MAX_COMMITS {
364+
scanned_commits += 1;
365+
370366
self.start_new_request()?;
371367
self.client.get(true)?;
372368
self.client.url(&format!(
373-
"https://api.github.com/repos/{repo}/commits?sha={resolved_start}&per_page=100&page={page}&author=bors",
369+
"https://api.github.com/repos/{repo}/commits/{commit}",
374370
repo = self.repo
375371
))?;
376-
let commits = self
372+
373+
let commit_data = self
377374
.client
378375
.without_body()
379-
.send_with_response::<Vec<CommitData>>()?;
380-
for commit in commits {
381-
self.start_new_request()?;
382-
self.client.get(true)?;
383-
self.client.url(&format!(
384-
"https://api.github.com/repos/{repo}/commits/{sha}",
385-
repo = self.repo,
386-
sha = commit.sha,
387-
))?;
388-
let commit = self
389-
.client
390-
.without_body()
391-
.send_with_response::<FullCommitData>()?;
392-
if commit.files.iter().any(|f| f.filename == path) {
393-
return Ok(commit);
394-
}
376+
.send_with_response::<FullCommitData>()?;
377+
378+
// We pick the *first* parent commit to continue walking through the commit graph. In
379+
// a merge commit, the first parent is always the merge base (i.e. the master branch),
380+
// while the second parent is always the branch being merged in.
381+
//
382+
// This is important because we only want bors merge commits for branches merged into
383+
// Rust's master branch, not bors merge commits in subtrees being pulled in.
384+
let Some(parent) = &commit_data.parents.first() else {
385+
break;
386+
};
387+
commit.clone_from(&parent.sha);
388+
389+
if commit_data.commit.author.email != BORS_EMAIL {
390+
continue;
391+
}
392+
if commit_data.files.iter().any(|f| f.filename == path) {
393+
return Ok(commit_data);
395394
}
396395
}
397396

398397
anyhow::bail!(
399-
"Failed to find bors commit touching {:?} in start={} ancestors (scanned {} commits)",
400-
path,
401-
start,
402-
20 * 100,
398+
"Failed to find bors commit touching {path:?} in \
399+
start={start} ancestors (scanned {scanned_commits} commits)"
403400
);
404401
}
405402

@@ -511,15 +508,21 @@ pub(crate) struct CreateTag<'a> {
511508

512509
#[derive(serde::Deserialize)]
513510
pub(crate) struct FullCommitData {
514-
#[allow(unused)]
511+
#[cfg_attr(not(test), allow(unused))]
515512
pub(crate) sha: String,
516513
pub(crate) parents: Vec<CommitParent>,
514+
pub(crate) commit: CommitCommit,
517515
pub(crate) files: Vec<CommitFile>,
518516
}
519517

520518
#[derive(serde::Deserialize)]
521-
pub(crate) struct CommitData {
522-
pub(crate) sha: String,
519+
pub(crate) struct CommitCommit {
520+
pub(crate) author: CommitAuthor,
521+
}
522+
523+
#[derive(serde::Deserialize)]
524+
pub(crate) struct CommitAuthor {
525+
pub(crate) email: String,
523526
}
524527

525528
#[derive(serde::Deserialize)]

0 commit comments

Comments
 (0)