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 1428651ddfeb623db642b9401d50cbb7bafb1763..862c5e1d5ee33e71c2274a4f5b76b282122e277f 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()