Home | History | Annotate | Download | only in release
      1 #!/usr/bin/env python
      2 # Copyright 2015 the V8 project authors. All rights reserved.
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 import argparse
      7 import os
      8 import sys
      9 
     10 from search_related_commits import git_execute
     11 
     12 GIT_OPTION_HASH_ONLY = '--pretty=format:%H'
     13 GIT_OPTION_NO_DIFF = '--quiet'
     14 GIT_OPTION_ONELINE = '--oneline'
     15 
     16 def describe_commit(git_working_dir, hash_to_search, one_line=False):
     17   if one_line:
     18     return git_execute(git_working_dir, ['show',
     19                                          GIT_OPTION_NO_DIFF,
     20                                          GIT_OPTION_ONELINE,
     21                                          hash_to_search]).strip()
     22   return git_execute(git_working_dir, ['show',
     23                                        GIT_OPTION_NO_DIFF,
     24                                        hash_to_search]).strip()
     25 
     26 
     27 def get_followup_commits(git_working_dir, hash_to_search):
     28   return git_execute(git_working_dir, ['log',
     29                                        '--grep=' + hash_to_search,
     30                                        GIT_OPTION_HASH_ONLY,
     31                                        'master']).strip().splitlines()
     32 
     33 def get_merge_commits(git_working_dir, hash_to_search):
     34   merges = get_related_commits_not_on_master(git_working_dir, hash_to_search)
     35   false_merges = get_related_commits_not_on_master(
     36     git_working_dir, 'Cr-Branched-From: ' + hash_to_search)
     37   false_merges = set(false_merges)
     38   return ([merge_commit for merge_commit in merges
     39       if merge_commit not in false_merges])
     40 
     41 def get_related_commits_not_on_master(git_working_dir, grep_command):
     42   commits = git_execute(git_working_dir, ['log',
     43                                           '--all',
     44                                           '--grep=' + grep_command,
     45                                           GIT_OPTION_ONELINE,
     46                                           '--decorate',
     47                                           '--not',
     48                                           'master',
     49                                           GIT_OPTION_HASH_ONLY])
     50   return commits.splitlines()
     51 
     52 def get_branches_for_commit(git_working_dir, hash_to_search):
     53   branches = git_execute(git_working_dir, ['branch',
     54                                            '--contains',
     55                                            hash_to_search,
     56                                            '-a']).strip()
     57   branches = branches.splitlines()
     58   return map(str.strip, branches)
     59 
     60 def is_lkgr(git_working_dir, hash_to_search):
     61   branches = get_branches_for_commit(git_working_dir, hash_to_search)
     62   return 'remotes/origin/lkgr' in branches
     63 
     64 def get_first_canary(git_working_dir, hash_to_search):
     65   branches = get_branches_for_commit(git_working_dir, hash_to_search)
     66   canaries = ([currentBranch for currentBranch in branches if
     67     currentBranch.startswith('remotes/origin/chromium/')])
     68   canaries.sort()
     69   if len(canaries) == 0:
     70     return 'No Canary coverage'
     71   return canaries[0].split('/')[-1]
     72 
     73 def print_analysis(git_working_dir, hash_to_search):
     74   print '1.) Searching for "' + hash_to_search + '"'
     75   print '=====================ORIGINAL COMMIT START==================='
     76   print describe_commit(git_working_dir, hash_to_search)
     77   print '=====================ORIGINAL COMMIT END====================='
     78   print '2.) General information:'
     79   print 'Is LKGR: ' + str(is_lkgr(git_working_dir, hash_to_search))
     80   print 'Is on Canary: ' + (
     81     str(get_first_canary(git_working_dir, hash_to_search)))
     82   print '3.) Found follow-up commits, reverts and ports:'
     83   followups = get_followup_commits(git_working_dir, hash_to_search)
     84   for followup in followups:
     85     print describe_commit(git_working_dir, followup, True)
     86 
     87   print '4.) Found merges:'
     88   merges = get_merge_commits(git_working_dir, hash_to_search)
     89   for currentMerge in merges:
     90     print describe_commit(git_working_dir, currentMerge, True)
     91     print '---Merged to:'
     92     mergeOutput = git_execute(git_working_dir, ['branch',
     93                                                 '--contains',
     94                                                 currentMerge,
     95                                                 '-r']).strip()
     96     print mergeOutput
     97   print 'Finished successfully'
     98 
     99 if __name__ == '__main__':  # pragma: no cover
    100   parser = argparse.ArgumentParser('Tool to check where a git commit was'
    101  ' merged and reverted.')
    102 
    103   parser.add_argument('-g', '--git-dir', required=False, default='.',
    104                         help='The path to your git working directory.')
    105 
    106   parser.add_argument('hash',
    107                       nargs=1,
    108                       help='Hash of the commit to be searched.')
    109 
    110   args = sys.argv[1:]
    111   options = parser.parse_args(args)
    112 
    113   sys.exit(print_analysis(options.git_dir, options.hash[0]))
    114