Github cherrry-pick 工具。 解决在一个分支提交一个Commit 需要提交到其它分支的需要。特别是在分支超级多的情况下。
#!/usr/bin/python3# Filename: git_cherry.py# Apply a commit for all branch in a git repo.# :param workspace: The git repo dict.# :param cherry_pick_name: The cherry-pick commit id.# :param pattern_branch: The regex pattern, for filter which you want to apply cherry-pick branch.# :param filter_branch_names: the branch name's which you don't want to apply cherry-pick. This is a list.# Notes: value must be full branch name.## use example:# [workspace] [cherry_pick_name] [pattern_branch] [filter_branch_names]# python3 git_cherry.py ./ e350he "remotes" "remotes/origin/master"## @Author: Alex Liu# @Email: quenlenliu@Gmail.com#import subPRocessimport osimport sysdef get_all_branch(pattern): """ Get all branch which match the pattern in current work direction. :param pattern: str :return: list """ (status, output) = subprocess.getstatusoutput("git branch -a | grep /"" + pattern + "/"") branch_list = output.splitlines() result = [] for str in branch_list: str = str[2:].split(' ')[0] result.append(str) return resultdef checkout_branch(branch_name=""): """ Checkout and pull a branch. If branch name is a remote branch, its content must be like this "remotes/origin/master" In this case: this will try to checkout a local branch if without has a local branch and track remotes branch. if already has a local branch, just checkout it and pull from this remotes branch. if branch is a local branch: checkout it and pull it. :param branch_name: :return: """ branch_detail = branch_name.split('/') if len(branch_detail) == 3: (status, output) = subprocess.getstatusoutput("git checkout -t " + branch_name) print(output) if status != 0: (status, output) = subprocess.getstatusoutput("git checkout " + branch_detail[2]) print(output) subprocess.getstatusoutput("git pull " + branch_detail[1] + " " + branch_detail[2]) print(branch_name + ": " + str(status) + " " + output) else: (status, output) = subprocess.getstatusoutput("git checkout " + branch_name) print(branch_name + ": " + str(status) + " " + output) subprocess.getstatusoutput("git pull ") return 0def apply_cherry_pick(cherry_pick_name): (status, output) = subprocess.getstatusoutput("git cherry-pick " + cherry_pick_name) print(str(status) + " " + output) return statusdef submit_branch(branch_name): branch_detail = branch_name.split('/') if len(branch_detail) == 3: (status, output) = subprocess.getstatusoutput("git push " + branch_detail[1] + " " + branch_detail[2]) print(branch_name + ": " + str(status) + " " + output) return status return -1def is_status_ok(status=0): if status == 0: return True else: # return true now, don's check return Truedef apply_patch_for_all_branch(workspace="", cherry_pick_name="", pattern_branch="remotes", filter_branch_names=[]): """ Apply a patch for branches in a git repo. :param workspace: the dir of the git repo. Type: str :param pattern_branch: the dest branch pattern. Type: str :param cherry_pick_name: the commit id which your want apply for other branch. Type: str :param filter_branch_names: The branch names which you do not want applied branch. Type: list. :return: """ print("--------------------------------------") print("------- Start apply cherry-pick ------") os.chdir(workspace) print("Workspace: " + os.getcwd()) cherry_pick_commit = cherry_pick_name print("Apply cherry-pick for All branch : " + cherry_pick_commit) print("Filter Branches: " + str(filter_branch_names)) print("Pattern Branch: " + pattern_branch) all_branches = get_all_branch(pattern_branch) print("Check Branches: ") print(all_branches) for branch_name in all_branches: if branch_name not in filter_branch_names: print("/n/n") print("Start Apply Branch --------------: " + branch_name) status = checkout_branch(branch_name) if is_status_ok(status): status = apply_cherry_pick(cherry_pick_commit) if is_status_ok(status): status = submit_branch(branch_name) if is_status_ok(status): print("Apply pick for branch " + branch_name + " Success") else: print("Apply pick for branch " + branch_name + " Error") return else: print("Apply pick for branch " + branch_name + " Error") return else: print("Apply pick for branch " + branch_name + " Error") return print("------- End apply cherry-pick ---------") print("---------------------------------------")def execute(): workspace = sys.argv[1] cherry_pick_name = sys.argv[2] pattern_branch = sys.argv[3] filter_branch_names = sys.argv[4:] apply_patch_for_all_branch(workspace, cherry_pick_name, pattern_branch, filter_branch_names)if __name__ == "__main__": execute()新闻热点
疑难解答