summaryrefslogtreecommitdiff
path: root/bibisect/mergeranges
blob: eed6ae93cef533915ef621385e678b2384456010 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/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.")