Cherry-pick 工具

2 篇文章 0 订阅
1 篇文章 0 订阅

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 subprocess
import os
import sys


def 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 result


def 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 0


def apply_cherry_pick(cherry_pick_name):
    (status, output) = subprocess.getstatusoutput("git cherry-pick " + cherry_pick_name)
    print(str(status) + " " + output)
    return status


def 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 -1


def is_status_ok(status=0):
    if status == 0:
        return True
    else:
        # return true now, don's check
        return True


def 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()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值