From 5d6a5015772a8931d2eae1a7c3fa5266bd4b114f Mon Sep 17 00:00:00 2001 From: Douglas Raillard Date: Tue, 6 Feb 2024 14:57:10 +0000 Subject: [PATCH] tools/batch-rebase: Fix cherry picking in some scenarios FIX Sometimes cherry-picking of an entire range fails where cherry picking each commit individually works, so do that instead. --- tools/batch-rebase/src/batch_rebase/main.py | 35 ++++++++++----------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/tools/batch-rebase/src/batch_rebase/main.py b/tools/batch-rebase/src/batch_rebase/main.py index a87109031..0095660bc 100755 --- a/tools/batch-rebase/src/batch_rebase/main.py +++ b/tools/batch-rebase/src/batch_rebase/main.py @@ -362,16 +362,12 @@ def _do_cherry_pick(repo, conf, persistent_tags, tags_suffix): else: raise ValueError(f'base or nr-commits need to be set on topic "{name}"') - range_ref = 'refs/remotes/{remote}/{base}..refs/remotes/{remote}/{tip}'.format( - remote=remote, - base=base, - tip=tip - ) - - nr_commits = int( - git(['rev-list', '--count', range_ref], capture=True) - ) + range_base = f'refs/remotes/{remote}/{base}' + range_tip = f'refs/remotes/{remote}/{tip}' + range_ref = f'{range_base}..{range_tip}' + range_sha1s = git(['rev-list', range_ref], capture=True).splitlines() + nr_commits = len(range_sha1s) info('Cherry-picking topic "{name}" from {remote} ({nr_commits} commits)\nremote: {remote}\nbase: {base}\ntip: {tip}\n'.format( name=name, remote=remote, @@ -381,7 +377,7 @@ def _do_cherry_pick(repo, conf, persistent_tags, tags_suffix): )) - if not cherry_pick_ref(repo, range_ref): + if not cherry_pick_ref(repo, range_sha1s): # Save the current state for later resumption conf['resume'] = { 'conflict-topic': name, @@ -398,8 +394,7 @@ def _do_cherry_pick(repo, conf, persistent_tags, tags_suffix): {repo} 2. Finish cherry picking the topic and fix any - remaining conflicts using: - git -C {repo} cherry-pick --continue + remaining conflicts. 3. Run: batch-rebase resume {repo} @@ -420,14 +415,16 @@ def _do_cherry_pick(repo, conf, persistent_tags, tags_suffix): return (False, persistent_refs) -def cherry_pick_ref(repo, ref): +def cherry_pick_ref(repo, refs): git = make_git_func(repo) - try: - git(['cherry-pick', '--', ref]) - # There is a conflict - except subprocess.CalledProcessError: - # Let Git rerere do its job - return rerere_autocommit(repo) + for ref in refs: + try: + git(['cherry-pick', '--', ref]) + # There is a conflict + except subprocess.CalledProcessError: + # Let Git rerere do its job + if not rerere_autocommit(repo): + return False return True -- GitLab