1#!/usr/bin/env python3 2# Copyright 2020 The Chromium OS 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""" 7Utility to apply diffs between given two upstream commit hashes to current 8workspace. 9 10This utility diffs files between old_commit and new_commit, with hard-coded 11filter rules, and apply the diff to current HEAD with 3-way-merge supported. 12 13This can be used to uprev a libchrome directory when this is not git history for 14git merge to work. 15""" 16 17import argparse 18import subprocess 19import sys 20 21import filters 22import utils 23 24def main(): 25 # Init args 26 parser = argparse.ArgumentParser( 27 description='Copy file from given commits') 28 parser.add_argument( 29 'old_commit', metavar='old_commit', type=str, nargs=1, 30 help='commit hash in upstream branch or browser repository ' 31 'we want to uprev from') 32 parser.add_argument( 33 'new_commit', metavar='new_commit', type=str, nargs=1, 34 help='commit hash in upstream branch or browser repository ' 35 'we want ot uprev to') 36 parser.add_argument( 37 '--dry_run', dest='dry_run', action='store_const', const=True, default=False) 38 parser.add_argument( 39 '--is_browser', dest='is_browser', action='store_const', const=True, default=False, 40 help='is the commit hash in browser repository') 41 arg = parser.parse_args(sys.argv[1:]) 42 43 # Get old and new files. 44 old_files = utils.get_file_list(arg.old_commit[0]) 45 new_files = utils.get_file_list(arg.new_commit[0]) 46 47 if arg.is_browser: 48 old_files = filters.filter_file([], old_files) 49 new_files = filters.filter_file([], new_files) 50 assert filters.filter_file(old_files, []) == [] 51 assert filters.filter_file(new_files, []) == [] 52 53 # Generate a tree object for new files. 54 old_tree = utils.git_mktree(old_files) 55 new_tree = utils.git_mktree(new_files) 56 newroot = utils.git_commit(old_tree, []) 57 squashed = utils.git_commit(new_tree, [newroot]) 58 59 # Generate patch for git am 60 patch = subprocess.check_output(['git', 'format-patch', '--stdout', newroot+b'..'+squashed]) 61 62 if arg.dry_run: 63 print(patch.decode('utf-8')) 64 else: 65 subprocess.run(['git', 'am', '-3'], input=patch) 66 67 68if __name__ == '__main__': 69 main() 70