-
Notifications
You must be signed in to change notification settings - Fork 0
/
fix.py
executable file
·100 lines (74 loc) · 2.42 KB
/
fix.py
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
92
93
94
95
96
97
98
99
100
#!/usr/bin/env python
# Fixes/verifies the javascript repo
#
# Run from within a checkout
#
# USAGE: fix.py ../damage.txt fix
# fix.py ../damage.txt check
import subprocess
import re
import sys
def read_damage(filename):
with open(filename) as fd:
return [line.rstrip() for line in fd.readlines()]
def find_commit_name_pairs(lines):
"""Parses a line from damage.txt that looks like this:
+ dce420b8...7b3df5c7 [email protected] -> [email protected] (forced update)
"""
pattern = re.compile(r'^ \+ ([^.]*)\.\.\.[^ ]* ([^ ]*) -> .*')
result = []
for line in lines:
if not line:
continue
m = pattern.match(line)
if not m:
raise Exception("Failed to match line: '" + line + "'")
result.append((m.group(1), m.group(2)))
return result
def find_branches():
"""Finds all branches in the origin remote."""
pattern = re.compile(r'remotes/origin/(.*)')
output = subprocess.check_output(['git', 'branch', '-a'])
branches = []
for line in output.splitlines():
m = pattern.search(line)
if m:
branches.append(m.group(1))
return set(branches)
def find_tags():
"""Finds all tags."""
output = subprocess.check_output(['git', 'tag', '-l'])
tags = [line.rstrip() for line in output.splitlines()]
return set(tags)
def fix_branch(commit, ref):
subprocess.check_call(['git', 'checkout', ref])
subprocess.check_call(['git', 'reset', '--hard', commit])
def fix_tag(commit, ref):
subprocess.check_call(['git', 'tag', '-f', ref, commit])
def run_fix(pairs, branches, tags):
for commit, ref in pairs:
if ref in branches:
fix_branch(commit, ref)
elif ref in tags:
fix_tag(commit, ref)
else:
raise Exception("Unknown ref " + ref)
def rev_parse(ref):
output = subprocess.check_output(['git', 'rev-parse', '--short', ref])
return output.rstrip()
def run_check(pairs):
for commit, ref in pairs:
actual = rev_parse(ref)
if actual != commit:
raise Exception("actual didn't match: %s vs %s" % (actual, commit))
def main(args):
command = args[2]
lines = read_damage(args[1])
pairs = find_commit_name_pairs(lines)
branches = find_branches()
tags = find_tags()
if command == 'fix':
run_fix(pairs, branches, tags)
elif command == 'check':
run_check(pairs)
main(sys.argv)