• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# coding=utf-8
3#
4# Copyright (c) 2022-2024 Huawei Device Co., Ltd.
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import logging
18import os
19import re
20import sys
21import git
22
23logging.basicConfig(stream=sys.stdout, level=logging.INFO)
24
25LINTER_PATH = 'ets2panda/linter'
26
27merge_re = re.compile(r'Merge pull request !')
28revert_re = re.compile(r'This reverts commit (.+)\.')
29cherry_pick_re = re.compile(r'\(cherry picked from commit (.+)\)')
30
31
32def get_branch_map(repo, branch_name, path):
33    result = {}
34
35    commits = list(repo.iter_commits(branch_name, path))
36    commits.reverse()
37    for commit in commits:
38        msg = commit.message
39        if merge_re.search(msg) is not None:
40            continue
41
42        revert_match = revert_re.search(msg)
43        if revert_match is not None:
44            sha = revert_match.group(1)
45            if sha in result:
46                del result[sha]
47                continue
48
49        cherry_pick_match = cherry_pick_re.search(msg)
50        sha = commit.hexsha if cherry_pick_match is None else cherry_pick_match.group(1)
51        if sha not in result:
52            result[sha] = commit
53        else:
54            raise Exception(f'Duplicate commit {sha}')
55
56    return result
57
58
59def print_complement(of, to):
60    logging.info('-' * 40)
61    for sha in to:
62        if sha not in of:
63            commit = to[sha]
64            logging.info('{}\n\n{}', commit.hexsha, commit.message.strip('\n'))
65            logging.info('-' * 40)
66
67
68def main():
69    if len(sys.argv) != 3:
70        logging.info('Usage:\n{} first_branch_name second_branch_name', sys.argv[0])
71        return -1
72
73    first_branch_name = sys.argv[1]
74    second_branch_name = sys.argv[2]
75
76    repo = git.Repo(os.getcwd() + '/../..')
77    first_branch_map = get_branch_map(repo, first_branch_name, LINTER_PATH)
78    second_branch_map = get_branch_map(repo, second_branch_name, LINTER_PATH)
79
80    logging.info('Commits in `{}`, but not in `{}`:\n', first_branch_name, second_branch_name)
81    print_complement(second_branch_map, first_branch_map)
82
83    logging.info('\n')
84    logging.info('=' * 80)
85    logging.info('\n')
86
87    logging.info('Commits in `{}`, but not in `{}`:\n', second_branch_name, first_branch_name)
88    print_complement(first_branch_map, second_branch_map)
89
90    return 0
91
92if __name__ == '__main__':
93    sys.exit(main())
94