File: mergeinfo.py

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (140 lines) | stat: -rwxr-xr-x 5,486 bytes parent folder | download | duplicates (12)
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]))