| #!/usr/bin/env python |
| # Copyright 2015 the V8 project authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import argparse |
| import os |
| import sys |
| import re |
| |
| 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): |
| cmd = ['log', '--grep=' + hash_to_search, GIT_OPTION_HASH_ONLY, |
| 'remotes/origin/master']; |
| return git_execute(git_working_dir, cmd).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) |
| false_merges = set(false_merges) |
| return ([merge_commit for merge_commit in merges |
| if merge_commit not in false_merges]) |
| |
| def get_related_commits_not_on_master(git_working_dir, grep_command): |
| commits = git_execute(git_working_dir, ['log', |
| '--all', |
| '--grep=' + grep_command, |
| GIT_OPTION_ONELINE, |
| '--decorate', |
| '--not', |
| 'remotes/origin/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() |
| return map(str.strip, branches) |
| |
| def is_lkgr(branches): |
| return 'remotes/origin/lkgr' in branches |
| |
| def get_first_canary(branches): |
| canaries = ([currentBranch for currentBranch in branches if |
| currentBranch.startswith('remotes/origin/chromium/')]) |
| canaries.sort() |
| if len(canaries) == 0: |
| return 'No Canary coverage' |
| return canaries[0].split('/')[-1] |
| |
| def get_first_v8_version(branches): |
| version_re = re.compile("remotes/origin/[0-9]+\.[0-9]+\.[0-9]+") |
| versions = filter(lambda branch: version_re.match(branch), branches) |
| if len(versions) == 0: |
| return "--" |
| version = versions[0].split("/")[-1] |
| return version |
| |
| 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 '2.) General information:' |
| branches = get_branches_for_commit(git_working_dir, hash_to_search) |
| print 'Is LKGR: ' + str(is_lkgr(branches)) |
| print 'Is on Canary: ' + str(get_first_canary(branches)) |
| print 'First V8 branch: ' + str(get_first_v8_version(branches)) + \ |
| ' (Might not be the rolled version)' |
| 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' |
| |
| 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('hash', |
| nargs=1, |
| help='Hash of the commit to be searched.') |
| |
| args = sys.argv[1:] |
| options = parser.parse_args(args) |
| |
| sys.exit(print_analysis(options.git_dir, options.hash[0])) |