Skip to content

Commit 36aedda

Browse files
committed
Added a check for non-merged commits ahead of commits marked as ready to merge on a branch.
- Legacy-Id: 11776
1 parent 21c33f0 commit 36aedda

1 file changed

Lines changed: 50 additions & 6 deletions

File tree

bin/mergeready

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ def pipe(cmd, inp=None):
127127
def split_loginfo(line):
128128
try:
129129
parts = line.split()
130-
rev = parts[0][1:]
131-
who = parts[2]
130+
rev = parts[0][1:]
131+
who = parts[2]
132132
date = parts[4]
133133
time = parts[5]
134134
tz = parts[6]
@@ -155,6 +155,7 @@ head = int(svn_info['Revision'])
155155
cachefn = os.path.join(os.environ.get('HOME', '.'), '.mergeinfo')
156156

157157
if os.path.exists(cachefn):
158+
note("Reading mergeinfo cache file %s" % cachefn)
158159
with open(cachefn, "r") as file:
159160
cache = json.load(file)
160161
else:
@@ -165,6 +166,7 @@ mergeinfo = cache[repo] if repo in cache else {}
165166

166167
merged_revs = {}
167168
write_cache = False
169+
note("Getting svn:mergeinfo for current branch")
168170
for line in pipe('svn propget svn:mergeinfo .').splitlines():
169171
if line in mergeinfo:
170172
merged = mergeinfo[line]
@@ -194,7 +196,11 @@ if write_cache:
194196
with open(cachefn, "w") as file:
195197
json.dump(cache, file, indent=2, sort_keys=True)
196198

197-
def get_list(repo, filename):
199+
def get_changeset_list_from_file(repo, filename):
200+
"""
201+
This is used to read changesets to hold or merge from the ready-for-merge
202+
and hold-for-merge files.
203+
"""
198204
list = []
199205
note("Reading list from '%s'" % filename)
200206
with open(filename) as file:
@@ -240,7 +246,7 @@ def get_ready_commits(repo, tree):
240246
type, path = line[:4], line[5:]
241247
branch = '/'.join(path.split('/')[1:4])
242248
elif re.search("(?i)((commit|branch) ready (for|to) merge)", line):
243-
if not (rev in merged_revs and branch == merged_revs[rev]):
249+
if not rev in merged_revs:
244250
note(" %s %s: %s@%s" % (when.strftime("%Y-%m-%d %H:%MZ"), who, branch, rev))
245251
list += [(rev, repo, branch),]
246252
elif rev in merged_revs and not branch == merged_revs[rev]:
@@ -252,16 +258,19 @@ def get_ready_commits(repo, tree):
252258

253259
return list
254260

255-
ready = get_list(repo, 'ready-for-merge')
256-
hold = get_list(repo, 'hold-for-merge')
261+
ready = get_changeset_list_from_file(repo, 'ready-for-merge')
262+
hold = get_changeset_list_from_file(repo, 'hold-for-merge')
257263
ready += get_ready_commits(repo, 'personal')
258264
ready += get_ready_commits(repo, 'branch/amsl')
259265
ready += get_ready_commits(repo, 'branch/iola')
260266

261267
ready_commits = {}
268+
all_commits = {}
262269
not_passed = {}
270+
branches = set()
263271
for entry in ready:
264272
rev, repo, branch = entry
273+
branches.add(branch)
265274
# Get the time, committer, and commit message
266275
cmd = 'svn log -v -r %s %s/%s/' % (rev, repo, branch)
267276
if opt_verbose > 1:
@@ -292,11 +301,46 @@ for entry in ready:
292301
merge_path = os.path.join(*path.split(os.path.sep)[:4])
293302
if not (rev, repo, merge_path) in hold:
294303
output_line = "%s %-24s ^/%s@%s" % (when.strftime("%Y-%m-%d_%H:%MZ"), who+":", merge_path, rev)
304+
all_commits[when] = (rev, repo, branch, who, merge_path)
295305
if unittest == 'passed':
296306
ready_commits[when] = output_line
297307
else:
298308
not_passed[when] = output_line
299309

310+
unmerged_branch_commits = {}
311+
for branch in branches:
312+
note("Fetching commit information for branch %s" % branch)
313+
commits = []
314+
cmd = 'svn log -v -r 0:HEAD --stop-on-copy %s/%s/' % (repo, branch)
315+
commit_log = pipe(cmd)
316+
for line in commit_log.splitlines()[3:]:
317+
if re.search('^r[0-9]+ ', line):
318+
rev, who, when = split_loginfo(line)
319+
if not rev in merged_revs:
320+
commits.append(rev)
321+
commits.sort()
322+
unmerged_branch_commits[branch] = commits
323+
324+
keys = all_commits.keys()
325+
keys.sort()
326+
# Check that we don't have holes in the commit list -- commits not mentioned
327+
# as ready for merge, and not already merged, earlier than a waiting commit.
328+
unmerged = False
329+
for key in keys:
330+
(rev, repo, branch, who, merge_path) = all_commits[key]
331+
i = unmerged_branch_commits[branch].index(rev)
332+
if not i == 0:
333+
unmerged = True
334+
sys.stderr.write("There are unmerged commits ahead of r%s on branch %s:\n" % (rev, branch))
335+
for j in range(0,i):
336+
sys.stderr.write(" %s:\n" % unmerged_branch_commits[branch][j])
337+
commit_comment = pipe("svn log -c %s ^/" % unmerged_branch_commits[branch][j]).splitlines()[3:-1]
338+
for l in commit_comment:
339+
sys.stderr.write(" %s\n" % l)
340+
del unmerged_branch_commits[branch][j]
341+
sys.stderr.write("\n")
342+
del unmerged_branch_commits[branch][0]
343+
300344
keys = not_passed.keys()
301345
keys.sort()
302346
if len(keys) > 0:

0 commit comments

Comments
 (0)