From 6c1363abda9efe5b54459beab000cb01736f7c51 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Wed, 26 Jul 2023 10:03:59 +0200 Subject: [PATCH 1/4] Check for intersecion of backout commits and upstream PR commits instead subset. Since backout can map to multiple bugs, it might not be a subset of upstream PR commits. --- sync/upstream.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sync/upstream.py b/sync/upstream.py index 5be649532..87d814db3 100644 --- a/sync/upstream.py +++ b/sync/upstream.py @@ -629,8 +629,9 @@ def remove_complete_backouts(commits: Iterable[Commit]) -> Sequence[Commit]: if commit.is_backout: backed_out_commits, _ = commit.wpt_commits_backed_out() backed_out = {item.sha1 for item in backed_out_commits} - if backed_out.issubset(commits_remaining): - commits_remaining -= backed_out + intersecion = backed_out.intersection(commits_remaining) + if len(intersecion) > 0: + commits_remaining -= intersecion continue commits_remaining.add(commit.sha1) From 0988b0219f0a50fbfadcaaf6c0380db6b951248d Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Wed, 26 Jul 2023 10:06:40 +0200 Subject: [PATCH 2/4] Fix fixture for backout to work with multiple revisions. Mercurial fails to back out if there're uncommitted changes, that's why we need to shelve changes in between. --- test/conftest.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/test/conftest.py b/test/conftest.py index 1867ad77b..f658b9968 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -173,7 +173,9 @@ def setup(self): self.init() with open(os.path.join(self.working_tree, ".hg", "hgrc"), "w") as f: f.write("""[ui] -username=test""") +username=test +[extensions] +shelve=""") def __getattr__(self, name): def call(self, *args): @@ -349,12 +351,23 @@ def inner(revs, bugs, message=None, bookmarks="mozilla/autoland"): if isinstance(bugs, int): bugs = [bugs] * len(revs) assert len(bugs) == len(revs) - msg = [b"Backed out %i changesets (bug %d) for test, r=backout" % (len(revs), bugs[0]), b""] + msg = [] + all_bugs_msgs = [] for rev, bug in zip(revs, bugs): hg_gecko_upstream.backout("--no-commit", rev) - msg.append(b"Backed out changeset %s (Bug %d)" % (rev[:12].encode("ascii"), bug)) + # Shelve the changes so we can perform the next backout. + hg_gecko_upstream.shelve() + bug_msg = b'bug %d' % bug + msg.append(b"Backed out changeset %s (%s)" % (rev[:12].encode("ascii"), bug_msg)) + all_bugs_msgs.append(bug_msg) + bugs_msg = b", ".join(all_bugs_msgs) + if len(bugs) > 1: + title = [b"Backed out %i changesets (%s) for test, r=backout" % (len(revs), bugs_msg)] + msg = title + msg if message is None: message = b"\n".join(msg) + for _ in revs: + hg_gecko_upstream.unshelve() return hg_commit(hg_gecko_upstream, message, bookmarks) return inner From 2a218f788298ce8bf7a7b31bdeffe506dbbfba61 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Wed, 26 Jul 2023 10:08:19 +0200 Subject: [PATCH 3/4] Add test for backout of multiple bugs. --- test/test_upstream.py | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/test_upstream.py b/test/test_upstream.py index 77ab33ee9..3a3274471 100644 --- a/test/test_upstream.py +++ b/test/test_upstream.py @@ -173,6 +173,57 @@ def test_create_partial_backout_reland(git_gecko, git_wpt, upstream_gecko_commit sync.wpt_commits[1].metadata["gecko-commit"] == relanding_rev +def test_create_backout_of_multiple_bugs(git_gecko, git_wpt, upstream_gecko_commit, + upstream_gecko_backout): + bug = 1234 + test_changes = {"README": b"Change README\n"} + rev = upstream_gecko_commit(test_changes=test_changes, bug=bug, + message=b"Change README") + + update_repositories(git_gecko, git_wpt, wait_gecko_commit=rev) + upstream.gecko_push(git_gecko, git_wpt, "autoland", rev, + raise_on_error=True) + + syncs = upstream.UpstreamSync.for_bug(git_gecko, git_wpt, bug) + + bug_2 = 5678 + test_changes_2 = {"OTHER": b"Add other file\n"} + rev_2 = upstream_gecko_commit(test_changes=test_changes_2, bug=bug_2, + message=b"Add other") + + update_repositories(git_gecko, git_wpt, wait_gecko_commit=rev_2) + upstream.gecko_push(git_gecko, git_wpt, "autoland", rev_2, + raise_on_error=True) + + syncs_2 = upstream.UpstreamSync.for_bug(git_gecko, git_wpt, bug_2) + + backout_rev = upstream_gecko_backout([rev_2, rev], [bug_2, bug]) + + update_repositories(git_gecko, git_wpt, wait_gecko_commit=backout_rev) + upstream.gecko_push(git_gecko, git_wpt, "autoland", backout_rev, raise_on_error=True) + + syncs = upstream.UpstreamSync.for_bug(git_gecko, git_wpt, bug) + syncs_2 = upstream.UpstreamSync.for_bug(git_gecko, git_wpt, bug_2) + + assert list(syncs.keys()) == ["incomplete"] + assert len(syncs["incomplete"]) == 1 + sync = syncs["incomplete"].pop() + assert sync.status == "incomplete" + assert sync.process_name.seq_id == 0 + assert len(sync.gecko_commits) == 0 + assert len(sync.upstreamed_gecko_commits) == 1 + assert len(sync.wpt_commits) == 1 + + assert list(syncs_2.keys()) == ["incomplete"] + assert len(syncs_2["incomplete"]) == 1 + sync_2 = syncs_2["incomplete"].pop() + assert sync_2.status == "incomplete" + assert sync_2.process_name.seq_id == 0 + assert len(sync_2.gecko_commits) == 0 + assert len(sync_2.upstreamed_gecko_commits) == 1 + assert len(sync_2.wpt_commits) == 1 + + def test_land_pr(env, git_gecko, git_wpt, hg_gecko_upstream, upstream_gecko_commit): bug = 1234 test_changes = {"README": b"Change README\n"} From 149e73550f1cc6a1eaf9961a5c5a5d127d70c492 Mon Sep 17 00:00:00 2001 From: Alexandra Borovova Date: Wed, 26 Jul 2023 14:24:09 +0200 Subject: [PATCH 4/4] Don't stop processing backed out commits if it was applied to one sync. --- sync/upstream.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sync/upstream.py b/sync/upstream.py index 87d814db3..b49f4765c 100644 --- a/sync/upstream.py +++ b/sync/upstream.py @@ -687,9 +687,9 @@ def updates_for_backout(git_gecko: Repo, sync = syncs.pop() assert isinstance(sync, UpstreamSync) if commit in sync.gecko_commits: - # This commit was already processed - backed_out_commit_shas = set() - return {}, {} + # This commit was already processed for this sync + backed_out_commit_shas.remove(backed_out_commit.sha1) + continue if backed_out_commit in sync.upstreamed_gecko_commits: backed_out_commit_shas.remove(backed_out_commit.sha1) assert sync.bug is not None