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