 Chromium Code Reviews
 Chromium Code Reviews Issue 1341303002:
  [Release] Distinguish between merges and follow-up CLs  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 1341303002:
  [Release] Distinguish between merges and follow-up CLs  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| Index: tools/release/mergeinfo.py | 
| diff --git a/tools/release/mergeinfo.py b/tools/release/mergeinfo.py | 
| index bf07e9f94af9ed47c959fbd58384b9ae21679649..a41719697fdc73c6f6338084f4739bd21b43cda0 100755 | 
| --- a/tools/release/mergeinfo.py | 
| +++ b/tools/release/mergeinfo.py | 
| @@ -7,29 +7,110 @@ import argparse | 
| import os | 
| import sys | 
| -from subprocess import call | 
| - | 
| -def print_analysis(gitWorkingDir, hashToSearch): | 
| - print '1.) Info' | 
| - git_execute(gitWorkingDir, ['status']) | 
| - print '2.) Searching for "' + hashToSearch + '"' | 
| - print '=====================ORIGINAL COMMIT START=====================' | 
| - git_execute(gitWorkingDir, ['show', hashToSearch]) | 
| +from search_related_commits import git_execute | 
| + | 
| +GIT_OPTION_HASH_ONLY = '--pretty=format:%H' | 
| +GIT_OPTION_NO_DIFF = '--quiet' | 
| +GIT_OPTION_ONELINE = '--oneline' | 
| + | 
| +def describe_commit(git_working_dir, hash_to_search, one_line=False): | 
| + if one_line: | 
| + return git_execute(git_working_dir, ['show', | 
| + GIT_OPTION_NO_DIFF, | 
| + GIT_OPTION_ONELINE, | 
| + hash_to_search]).strip() | 
| + return git_execute(git_working_dir, ['show', | 
| + GIT_OPTION_NO_DIFF, | 
| + hash_to_search]).strip() | 
| + | 
| + | 
| +def get_followup_commits(git_working_dir, hash_to_search): | 
| + return git_execute(git_working_dir, ['log', | 
| + '--grep='+hash_to_search, | 
| 
Michael Achenbach
2015/10/01 08:24:18
nit: space around +
 
Michael Achenbach
2015/10/01 08:24:18
How often does it happen that developers use the f
 
Michael Hablich
2015/10/01 10:33:25
Done.
 
Michael Hablich
2015/10/01 10:33:25
As far as I have seen the most prominent form is r
 | 
| + GIT_OPTION_HASH_ONLY, | 
| + 'master']).strip().splitlines() | 
| + | 
| +def get_merge_commits(git_working_dir, hash_to_search): | 
| + merges = get_related_commits_not_on_master(git_working_dir, hash_to_search) | 
| + false_merges = get_related_commits_not_on_master( | 
| + git_working_dir, 'Cr-Branched-From: ' + hash_to_search) | 
| + return list(set(merges) - set(false_merges)) | 
| 
Michael Achenbach
2015/10/01 08:24:18
you might loose the original order while going thr
 
Michael Hablich
2015/10/01 10:33:25
Done.
 | 
| + | 
| +def get_related_commits_not_on_master(git_working_dir, grep_command): | 
| + commits = git_execute(git_working_dir, ['log', | 
| + '--all', | 
| 
Michael Achenbach
2015/10/01 08:24:18
nit: indentation
 
Michael Hablich
2015/10/01 10:33:25
Done.
 | 
| + '--grep=' + grep_command, | 
| + GIT_OPTION_ONELINE, | 
| + '--decorate', | 
| + '--not', | 
| + 'master', | 
| + GIT_OPTION_HASH_ONLY]) | 
| + return commits.splitlines() | 
| + | 
| +def get_branches_for_commit(git_working_dir, hash_to_search): | 
| + branches = git_execute(git_working_dir, ['branch', | 
| + '--contains', | 
| + hash_to_search, | 
| + '-a']).strip() | 
| + branches = branches.splitlines() | 
| + branches = [ current.strip() for current in branches] | 
| 
Michael Achenbach
2015/10/01 08:24:18
3 in 1:
return map(str.strip, branches.splitlines(
 
Michael Hablich
2015/10/01 10:33:25
Did a mixture because I like it a little bit more
 
Michael Achenbach
2015/10/01 10:40:29
ok - 2 in 1 :)
 | 
| + return branches | 
| + | 
| +def is_rolled(git_working_dir, hash_to_search): | 
| + branches = get_branches_for_commit(git_working_dir, hash_to_search) | 
| + return 'remotes/origin/roll' in branches | 
| + | 
| +def is_lkgr(git_working_dir, hash_to_search): | 
| + branches = get_branches_for_commit(git_working_dir, hash_to_search) | 
| + return 'remotes/origin/lkgr' in branches | 
| + | 
| +def get_first_canary(git_working_dir, hash_to_search): | 
| + branches = get_branches_for_commit(git_working_dir, hash_to_search) | 
| + canaries = ([currentBranch for currentBranch in branches if | 
| + currentBranch.startswith('remotes/origin/chromium/')]) | 
| + canaries.sort() | 
| 
Michael Achenbach
2015/10/01 08:24:18
or put sorted() around the call above...
 
Michael Hablich
2015/10/01 10:33:25
I don't want to nest the list operation above even
 | 
| + if len(canaries) == 0: | 
| + return 'No Canary coverage' | 
| + return canaries[0].split('/')[-1] | 
| + | 
| +def print_analysis(git_working_dir, hash_to_search): | 
| + print '1.) Searching for "' + hash_to_search + '"' | 
| + print '=====================ORIGINAL COMMIT START===================' | 
| + print describe_commit(git_working_dir, hash_to_search) | 
| print '=====================ORIGINAL COMMIT END=====================' | 
| - print '#####################FOUND MERGES & REVERTS START#####################' | 
| - git_execute(gitWorkingDir, ["log",'--all', '--grep='+hashToSearch]) | 
| - print '#####################FOUND MERGES & REVERTS END#####################' | 
| + | 
| + print '2.) General information:' | 
| + print 'Is rolled: ' + str(is_rolled(git_working_dir, hash_to_search)) | 
| + print 'Is LKGR: ' + str(is_lkgr(git_working_dir, hash_to_search)) | 
| + print 'Is on Canary: ' + ( | 
| + str(get_first_canary(git_working_dir, hash_to_search))) | 
| + print '3.) Found follow-up commits, reverts and ports:' | 
| + followups = get_followup_commits(git_working_dir, hash_to_search) | 
| + for followup in followups: | 
| + print describe_commit(git_working_dir, followup, True) | 
| + | 
| + print '4.) Found merges:' | 
| + merges = get_merge_commits(git_working_dir, hash_to_search) | 
| + for currentMerge in merges: | 
| + print describe_commit(git_working_dir, currentMerge, True) | 
| + print '---Merged to:' | 
| + mergeOutput = git_execute(git_working_dir, ['branch', | 
| + '--contains', | 
| + currentMerge, | 
| + '-r']).strip() | 
| + print mergeOutput | 
| print 'Finished successfully' | 
| -def git_execute(workingDir, commands): | 
| - return call(["git", '-C', workingDir] + commands) | 
| +if __name__ == '__main__': # pragma: no cover | 
| + parser = argparse.ArgumentParser('Tool to check where a git commit was' | 
| + ' merged and reverted.') | 
| -if __name__ == "__main__": # pragma: no cover | 
| - parser = argparse.ArgumentParser('Tool to check where a git commit was merged and reverted.') | 
| - parser.add_argument("-g", "--git-dir", required=False, default='.', | 
| - help="The path to your git working directory.") | 
| + parser.add_argument('-g', '--git-dir', required=False, default='.', | 
| + help='The path to your git working directory.') | 
| - parser.add_argument('hash', nargs=1, help="Hash of the commit to be searched.") | 
| + parser.add_argument('hash', | 
| + nargs=1, | 
| + help='Hash of the commit to be searched.') | 
| args = sys.argv[1:] | 
| options = parser.parse_args(args) |