diff options
| author | Jakub Beránek <berykubik@gmail.com> | 2025-04-10 12:11:24 +0200 |
|---|---|---|
| committer | Jakub Beránek <berykubik@gmail.com> | 2025-04-20 09:35:42 +0200 |
| commit | 40058519bae2c4921e5a1cf5db42c0e9861b156f (patch) | |
| tree | 726e3e98997ddefec473924ccf46cd537e1f5597 /src/bootstrap | |
| parent | e9f3e3abda4ad922f09707702057bd13fc7bbd4a (diff) | |
Use `--author-date-order` when looking up upstream commits to support subtree synces
Diffstat (limited to 'src/bootstrap')
| -rw-r--r-- | src/bootstrap/src/core/config/tests.rs | 71 | ||||
| -rw-r--r-- | src/bootstrap/src/utils/tests/git.rs | 10 |
2 files changed, 79 insertions, 2 deletions
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 04e328c8b1b..96ac8a6d52f 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -858,6 +858,7 @@ fn test_local_changes_in_previous_upstream() { ctx.create_branch("feature"); ctx.modify("d"); ctx.commit(); + assert_eq!( ctx.check_modifications(&["a"], CiEnv::None), PathFreshness::LastModifiedUpstream { upstream: sha } @@ -914,3 +915,73 @@ fn test_local_changes_negative_path() { ); }); } + +#[test] +fn test_local_changes_subtree_that_used_bors() { + // Here we simulate a very specific situation related to subtrees. + // When you have merge commits locally, we should ignore them w.r.t. the artifact download + // logic. + // The upstream search code currently uses a simple heuristic: + // - Find commits by bors (or in general an author with the merge commit e-mail) + // - Find the newest such commit + // This should make it work even for subtrees that: + // - Used bors in the past (so they have bors merge commits in their history). + // - Use Josh to merge rustc into the subtree, in a way that the rustc history is the second + // parent, not the first one. + // + // In addition, when searching for modified files, we cannot simply start from HEAD, because + // in this situation git wouldn't find the right commit. + // + // This test checks that this specific scenario will resolve to the right rustc commit, both + // when finding a modified file and when finding a non-existent file (which essentially means + // that we just lookup the most recent upstream commit). + // + // See https://github.com/rust-lang/rust/issues/101907#issuecomment-2697671282 for more details. + git_test(|ctx| { + ctx.create_upstream_merge(&["a"]); + + // Start unrelated subtree history + ctx.run_git(&["switch", "--orphan", "subtree"]); + ctx.modify("bar"); + ctx.commit(); + // Now we need to emulate old bors commits in the subtree. + // Git only has a resolution of one second, which is a problem, since our git logic orders + // merge commits by their date. + // To avoid sleeping in the test, we modify the commit date to be forcefully in the past. + ctx.create_upstream_merge(&["subtree/a"]); + ctx.run_git(&["commit", "--amend", "--date", "Wed Feb 16 14:00 2011 +0100", "--no-edit"]); + + // Merge the subtree history into rustc + ctx.switch_to_branch("main"); + ctx.run_git(&["merge", "subtree", "--allow-unrelated"]); + + // Create a rustc commit that modifies a path that we're interested in (`x`) + let upstream_1 = ctx.create_upstream_merge(&["x"]); + // Create another bors commit + let upstream_2 = ctx.create_upstream_merge(&["a"]); + + ctx.switch_to_branch("subtree"); + + // Create a subtree branch + ctx.create_branch("subtree-pr"); + ctx.modify("baz"); + ctx.commit(); + // We merge rustc into this branch (simulating a "subtree pull") + ctx.merge("main", "committer <committer@foo.bar>"); + + // And then merge that branch into the subtree (simulating a situation right before a + // "subtree push") + ctx.switch_to_branch("subtree"); + ctx.merge("subtree-pr", "committer <committer@foo.bar>"); + + // And we want to check that we resolve to the right commits. + assert_eq!( + ctx.check_modifications(&["x"], CiEnv::None), + PathFreshness::LastModifiedUpstream { upstream: upstream_1 } + ); + assert_eq!( + ctx.check_modifications(&["nonexistent"], CiEnv::None), + PathFreshness::LastModifiedUpstream { upstream: upstream_2 } + ); + }); +} diff --git a/src/bootstrap/src/utils/tests/git.rs b/src/bootstrap/src/utils/tests/git.rs index 735dafb3f29..99e0793af46 100644 --- a/src/bootstrap/src/utils/tests/git.rs +++ b/src/bootstrap/src/utils/tests/git.rs @@ -53,12 +53,14 @@ impl GitCtx { modified_files: &[&str], author: &str, ) -> String { + let current_branch = self.get_current_branch(); + self.create_branch(branch); for file in modified_files { self.modify(file); } self.commit(); - self.switch_to_branch("main"); + self.switch_to_branch(¤t_branch); self.merge(branch, author); self.run_git(&["branch", "-d", branch]); self.get_current_commit() @@ -68,12 +70,16 @@ impl GitCtx { self.run_git(&["rev-parse", "HEAD"]) } + pub fn get_current_branch(&self) -> String { + self.run_git(&["rev-parse", "--abbrev-ref", "HEAD"]) + } + pub fn merge(&self, branch: &str, author: &str) { self.run_git(&["merge", "--no-commit", "--no-ff", branch]); self.run_git(&[ "commit".to_string(), "-m".to_string(), - "Merge of {branch}".to_string(), + format!("Merge of {branch} into {}", self.get_current_branch()), "--author".to_string(), author.to_string(), ]); |
