#!/usr/bin/env python3 # # Bibisect: This tool may be used to merge ranges of bibisect commits. # # USAGE: # For usage information, please see the README.txt file import sys import subprocess # Helper function to run code in a subprocess. def subrun(arglist): return subprocess.check_output(arglist).decode('utf-8') def justrunit(arglist): print(subrun(arglist)) # There is only one initial branch. initBranch = False # The branch on which we should store our merged commits. branchName = 'mergeranges' # Given a commit hash, create (if necessary) and checkout branchName # at that hash. def init_branch(startpoint): global initBranch, branchName try: justrunit(['git', 'checkout', branchName]) except subprocess.CalledProcessError as e: # If the branch does not exist, we need to create it. justrunit(['git', 'checkout', '-b', branchName, startpoint]) print("Creating branch " + branchName) else: # If the branch already existed, we want to cherry-pick the # 'startpoint' commit. cherry_pick_theirs(startpoint) initBranch = True # Pull a commit into the git repository. def cherry_pick_theirs(revision): try: # Remove all files currently checked-in to git. justrunit(['git', 'rm', '-rf', '.']) except: pass # Check out the files from the given revision. justrunit(['git', 'checkout', revision, '--', '.']) # Reuse the log message and the authorship information when # creating this commit. # # NOTE: Any untracked files in the repository (e.g. helper scripts # such as 'bibisect.sh' or 'run-libreoffice.sh') will be left in # place and not committed to the repository. justrunit(['git', 'commit', '-C', revision]) # Create a tag using the first line of the commit message we just # picked. argsHeadTag = ['git', 'log', '-1', '--pretty=%s', 'HEAD'] tag = subrun(argsHeadTag).rstrip() # Tag our cherry-picked commit. If the tag already exists, replace # it (quietly). justrunit(['git', 'tag', '-f', tag]) # Take input from the 'ranges' file passed-in on the command line. for line in open(sys.argv[1]).readlines(): print(line) # Assemble a list of revisions in the given range. argsRevRevList = ['git', 'rev-list', '--reverse', # We have to modify the range to make it inclusive. line.rstrip().replace("..", "^..")] revisions = [r for r in subrun(argsRevRevList).split('\n') if r.rstrip()] for revision in revisions: if not initBranch: print("init_branch: " + revision) init_branch(revision) else: cherry_pick_theirs(revision) # Tag the latest commit. justrunit(['git', 'tag', '-f', 'latest', subrun(['git', 'rev-parse', 'HEAD']).rstrip()]) print("") print("Mergeranges: script done.")