• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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# for py2/py3 compatibility
7from __future__ import print_function
8
9import argparse
10import os
11import sys
12import re
13
14from search_related_commits import git_execute
15
16GIT_OPTION_HASH_ONLY = '--pretty=format:%H'
17GIT_OPTION_NO_DIFF = '--quiet'
18GIT_OPTION_ONELINE = '--oneline'
19
20def describe_commit(git_working_dir, hash_to_search, one_line=False):
21  if one_line:
22    return git_execute(git_working_dir, ['show',
23                                         GIT_OPTION_NO_DIFF,
24                                         GIT_OPTION_ONELINE,
25                                         hash_to_search]).strip()
26  return git_execute(git_working_dir, ['show',
27                                       GIT_OPTION_NO_DIFF,
28                                       hash_to_search]).strip()
29
30
31def get_followup_commits(git_working_dir, hash_to_search):
32  cmd = ['log', '--grep=' + hash_to_search, GIT_OPTION_HASH_ONLY,
33         'remotes/origin/main'];
34  return git_execute(git_working_dir, cmd).strip().splitlines()
35
36def get_merge_commits(git_working_dir, hash_to_search):
37  merges = get_related_commits_not_on_main(git_working_dir, hash_to_search)
38  false_merges = get_related_commits_not_on_main(
39    git_working_dir, 'Cr-Branched-From: ' + hash_to_search)
40  false_merges = set(false_merges)
41  return ([merge_commit for merge_commit in merges
42      if merge_commit not in false_merges])
43
44def get_related_commits_not_on_main(git_working_dir, grep_command):
45  commits = git_execute(git_working_dir, ['log',
46                                          '--all',
47                                          '--grep=' + grep_command,
48                                          GIT_OPTION_ONELINE,
49                                          '--decorate',
50                                          '--not',
51                                          'remotes/origin/main',
52                                          GIT_OPTION_HASH_ONLY])
53  return commits.splitlines()
54
55def get_branches_for_commit(git_working_dir, hash_to_search):
56  branches = git_execute(git_working_dir, ['branch',
57                                           '--contains',
58                                           hash_to_search,
59                                           '-a']).strip()
60  branches = branches.splitlines()
61  return map(str.strip, branches)
62
63def is_lkgr(branches):
64  return 'remotes/origin/lkgr' in branches
65
66def get_first_canary(branches):
67  canaries = ([currentBranch for currentBranch in branches if
68    currentBranch.startswith('remotes/origin/chromium/')])
69  canaries.sort()
70  if len(canaries) == 0:
71    return 'No Canary coverage'
72  return canaries[0].split('/')[-1]
73
74def get_first_v8_version(branches):
75  version_re = re.compile("remotes/origin/[0-9]+\.[0-9]+\.[0-9]+")
76  versions = filter(lambda branch: version_re.match(branch), branches)
77  if len(versions) == 0:
78    return "--"
79  version = versions[0].split("/")[-1]
80  return version
81
82def print_analysis(git_working_dir, hash_to_search):
83  print('1.) Searching for "' + hash_to_search + '"')
84  print('=====================ORIGINAL COMMIT START===================')
85  print(describe_commit(git_working_dir, hash_to_search))
86  print('=====================ORIGINAL COMMIT END=====================')
87  print('2.) General information:')
88  branches = get_branches_for_commit(git_working_dir, hash_to_search)
89  print('Is LKGR:         ' + str(is_lkgr(branches)))
90  print('Is on Canary:    ' + str(get_first_canary(branches)))
91  print('First V8 branch: ' + str(get_first_v8_version(branches)) + \
92      ' (Might not be the rolled version)')
93  print('3.) Found follow-up commits, reverts and ports:')
94  followups = get_followup_commits(git_working_dir, hash_to_search)
95  for followup in followups:
96    print(describe_commit(git_working_dir, followup, True))
97
98  print('4.) Found merges:')
99  merges = get_merge_commits(git_working_dir, hash_to_search)
100  for currentMerge in merges:
101    print(describe_commit(git_working_dir, currentMerge, True))
102    print('---Merged to:')
103    mergeOutput = git_execute(git_working_dir, ['branch',
104                                                '--contains',
105                                                currentMerge,
106                                                '-r']).strip()
107    print(mergeOutput)
108  print('Finished successfully')
109
110if __name__ == '__main__':  # pragma: no cover
111  parser = argparse.ArgumentParser('Tool to check where a git commit was'
112 ' merged and reverted.')
113
114  parser.add_argument('-g', '--git-dir', required=False, default='.',
115                        help='The path to your git working directory.')
116
117  parser.add_argument('hash',
118                      nargs=1,
119                      help='Hash of the commit to be searched.')
120
121  args = sys.argv[1:]
122  options = parser.parse_args(args)
123
124  sys.exit(print_analysis(options.git_dir, options.hash[0]))
125