From 5e3ffb237385bc1dbdff739521b14fb5c25d30ee Mon Sep 17 00:00:00 2001 From: Emanuele Aina <emanuele.aina@collabora.com> Date: Sat, 13 Mar 2021 23:48:22 +0100 Subject: [PATCH] pkg-merge-upstream-to-downstream: Streamline the loop Refactor the code to reduce the amount of state carried across loop iterations and to reduce the nesting of conditionals, so that it's hopefully easier to understand and modify. Signed-off-by: Emanuele Aina <emanuele.aina@collabora.com> --- .../apertis-pkg-merge-upstream-to-downstreams | 67 +++++++++++-------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/package-source-builder/overlay/usr/bin/apertis-pkg-merge-upstream-to-downstreams b/package-source-builder/overlay/usr/bin/apertis-pkg-merge-upstream-to-downstreams index 1428651..862c5e1 100755 --- a/package-source-builder/overlay/usr/bin/apertis-pkg-merge-upstream-to-downstreams +++ b/package-source-builder/overlay/usr/bin/apertis-pkg-merge-upstream-to-downstreams @@ -12,6 +12,7 @@ from sh.contrib import git from sh import apertis_pkg_merge_updates import re from pathlib import Path +from functools import partial def parse_ref(ref: str) -> str: return git('rev-parse', '-q', '--verify', ref + '^{commit}', _ok_code=[0, 1]).strip('\n') @@ -74,41 +75,51 @@ def main(): local_suffix = args.local_suffix for upstream_branch in existing_upstream_branches(upstream): - # Mapping of downstream reference to proposed updates - known_refs = {} for downstream in downstreams: downstream_branch = get_matching_downstream_branch(downstream, upstream_branch) - # Skip branch not set if not downstream_branch: - continue + print(f"No branch for downstream {downstream}, skipping") + continue print(f"Looking at {downstream_branch} <- {upstream_branch}") - git.checkout(downstream_branch) - ref = git("rev-parse", "HEAD").rstrip() - known = known_refs.get(ref) - - if known == None: - print("New target, doing merge") - proposed_branch = f"proposed-updates/{upstream_branch}/{ref[0:8]}" - git.checkout("-B", proposed_branch) - apertis_pkg_merge_updates(f"--downstream={downstream_branch}", f"--upstream={upstream_branch}", f"--local-version-suffix={local_suffix}", _fg=True) - o = git('diff', '--quiet', f"HEAD..{downstream_branch}", _ok_code=[0,1]) - if o.exit_code == 1: - print("Merge done, pushing") - push_merge_request(args.project_url, proposed_branch, upstream_branch, downstream_branch) - known_refs[ref] = proposed_branch - else: - print("No merge required, skipping") - known_refs[ref] = "" - else: - if known == "": - print("Known target ref, Nothing required, skipping") - continue - # Check out known pre-pushed merge, and push that as an MR to the target - print("Known target, pushing merge request") - push_merge_request(args.project_url, known, upstream_branch, downstream_branch) + if git("merge-base", "--is-ancestor", upstream_branch, downstream_branch, _ok_code=[0,1]).exit_code == 0: + print(f"Upstream branch {upstream_branch} already merged into {downstream_branch}, no merge required") + continue + + ref = git("rev-parse", downstream_branch).rstrip() + proposed_branch = f"proposed-updates/{upstream_branch}/{ref[0:8]}" + + push_this_merge_request = partial(push_merge_request, args.project_url, proposed_branch, upstream_branch, downstream_branch) + + # check if we have a proposed branch from a previous iteration + if git("rev-parse", "--verify", proposed_branch, _ok_code=[0, 128]).strip(): + # handle the case where two downstreams are at the same commit and have + # the same upstream, so they should share the proposed branch + # for instance, if both v2021 and v2020 are at rev badf00d and are based + # on buster: + # 1. process v2021 and create proposed-updates/debian/buster/badf00d, + # submit a MR from proposed-updates/debian/buster/badf00d + # to apertis/v2021 + # 1. process v2020 and re-use proposed-updates/debian/buster/badf00d to + # submit a MR from proposed-updates/debian/buster/badf00d + # to apertis/v2020 + print(f"Reusing branch {proposed_branch} to be merged into {downstream_branch}") + push_this_merge_request() + continue + + print(f"Attempt merging {upstream_branch} into {downstream_branch} via {proposed_branch}") + git("checkout", "--force", "-B", "tmp", downstream_branch) + apertis_pkg_merge_updates(f"--downstream={downstream_branch}", f"--upstream={upstream_branch}", f"--local-version-suffix={local_suffix}", _fg=True) + o = git('diff', '--quiet', f"HEAD..{downstream_branch}", _ok_code=[0,1]) + if o.exit_code == 0: + print(f"No merge required for {downstream_branch}, skipping ") + continue + + print("Merge done, pushing {proposed_branch} to update the existing MR") + git("branch", "--force", proposed_branch, "HEAD") + push_this_merge_request() if __name__ == '__main__': main() -- GitLab