Skip to content
Snippets Groups Projects

pkg-merge: Always submit a new MR, even with conflicts

Merged Emanuele Aina requested to merge wip/em/pkg-merge-always-submit-mr into apertis/v2022dev2
All threads resolved!
@@ -12,14 +12,13 @@ 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')
def ensure_branch(name: str, fallbacks: list) -> str:
if parse_ref(f'origin/{name}'):
return name
for b in fallbacks:
for b in [name, *fallbacks]:
commit = parse_ref(f'origin/{b}')
if commit:
print(f'Setting branch {name} to point to {b} ({commit:.7})')
@@ -43,7 +42,7 @@ def existing_upstream_branches(upstream: str):
def get_matching_downstream_branch(downstream: str, upstream: str):
if re.search(r'(dev[0-9]|pre)$', downstream):
return downstream
return ensure_branch(downstream, [])
else:
if upstream.endswith('-security'):
return ensure_branch(f'{downstream}-security', [f'{downstream}-updates', downstream])
@@ -76,41 +75,55 @@ 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"Submit {proposed_branch} for merging into {downstream_branch} the updates from {upstream_branch}")
git("branch", proposed_branch, upstream_branch)
push_this_merge_request()
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()
Loading