From 7732cedde87d26e93d7b882001e41e32c85ef54f Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 21 Feb 2021 02:08:47 -0500 Subject: [PATCH] git-rb-catchup: add option to automatically stop at last failing rebase --- .bin/git-rb-catchup | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/.bin/git-rb-catchup b/.bin/git-rb-catchup index bb6b910..3414c02 100755 --- a/.bin/git-rb-catchup +++ b/.bin/git-rb-catchup @@ -29,7 +29,7 @@ def rebase(target): return False -def rebase_bisect(lbranch, rbranch, behind): +def rebase_bisect(lbranch, rbranch, behind, leave_rebase=False): """Try to rebase branch as close to |rbranch| as possible.""" def attempt(pos): target = f'{rbranch}~{pos}' @@ -43,20 +43,32 @@ def rebase_bisect(lbranch, rbranch, behind): print('OK' if ret else 'failed') return ret - #"min" is the latest branch commit while "max" is where we're now. - min = 0 - max = behind + # "pmin" is the latest branch position while "pmax" is where we're now. + pmin = 0 + pmax = behind old_mid = None + first_fail = 0 while True: - mid = min + (max - min) // 2 - if mid == old_mid or mid < min or mid >= max: + mid = pmin + (pmax - pmin) // 2 + if mid == old_mid or mid < pmin or mid >= pmax: break if attempt(mid): - max = mid + pmax = mid else: - min = mid + first_fail = max(first_fail, mid) + pmin = mid old_mid = mid - print('Done') + + if pmin or pmax: + last_target = f'{rbranch}~{first_fail}' + if leave_rebase: + print('Restarting', last_target) + result = git(['rebase', last_target], check=False) + print(result.stdout.strip()) + else: + print('Found first failure', last_target) + else: + print('All caught up!') def get_ahead_behind(lbranch, rbranch): @@ -92,6 +104,10 @@ def get_parser(): '--skip-initial-rebase-latest', dest='initial_rebase', action='store_false', default=True, help='skip initial rebase attempt onto the latest branch') + parser.add_argument( + '--leave-at-last-failed-rebase', dest='leave_rebase', + action='store_true', default=False, + help='leave tree state at last failing rebase') parser.add_argument( 'branch', nargs='?', help='branch to rebase onto') @@ -130,7 +146,7 @@ def main(argv): print('OK!') return 0 print('failed; falling back to bisect') - rebase_bisect(lbranch, rbranch, behind) + rebase_bisect(lbranch, rbranch, behind, leave_rebase=opts.leave_rebase) if __name__ == '__main__': -- 2.39.5