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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
#!/usr/bin/env python3
# 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.
# for py2/py3 compatibility
from __future__ import print_function
import argparse
import sys
import re
from subprocess import Popen, PIPE
GIT_OPTION_HASH_ONLY = '--pretty=format:%H'
GIT_OPTION_NO_DIFF = '--quiet'
GIT_OPTION_ONELINE = '--oneline'
def git_execute(working_dir, args, verbose=False):
command = ["git", "-C", working_dir] + args
if verbose:
print("Git working dir: " + working_dir)
print("Executing git command:" + str(command))
p = Popen(args=command, stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = p.communicate()
if p.returncode != 0:
raise Exception(err)
output = output.decode('utf-8')
if verbose:
print("Git return value: " + output)
return output
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/main'];
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_main(git_working_dir, hash_to_search)
false_merges = get_related_commits_not_on_main(
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_main(git_working_dir, grep_command):
commits = git_execute(git_working_dir, ['log',
'--all',
'--grep=' + grep_command,
GIT_OPTION_ONELINE,
'--decorate',
'--not',
'remotes/origin/main',
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 {branch.strip() for branch in 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 = [branch for branch in branches if version_re.match(branch)]
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]))
|