Git:同时提交到多个分支

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7259135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 11:44:51  来源:igfitidea点击:

Git: Commit to multiple branches at the same time

gitbranch

提问by Kit Ho

I want to make a single commit on different branches at the same time, since, in my project, I have different branches for different clients.

我想同时在不同的分支上进行一次提交,因为在我的项目中,我为不同的客户提供了不同的分支。

Say, I have made a new feature commit on Branch A. Can I also make this commit on Branch B, Branch C and D at the same time as well? Is there any short cut command for this? This is very troublesome to checkout one branch, and cherrypick the commit everytime, sometime, if the commit is necessary on many branches, it would be a nightmare for me.

比如说,我在分支 A 上提交了一个新功能。我是否也可以同时在分支 B、分支 C 和 D 上进行这个提交?是否有任何快捷命令?签出一个分支非常麻烦,而且每次都选择提交,有时,如果需要在多个分支上提交,这对我来说将是一场噩梦。

Any simple bash script for this operation?

此操作有任何简单的 bash 脚本吗?

There is a similar questionin there. but rebasing is not that I want.

里面有一个类似的问题。但变基不是我想要的。

回答by spoutnik

The cherry-pick feature will do the job and will only apply the last commit:

挑选功能将完成这项工作,并且只会应用最后一次提交:

Considering branches A, B

考虑分支 A、B

git checkout A
git commit -m "Fixed the bug x"
git checkout B
git cherry-pick A

hope this helps!

希望这可以帮助!

回答by Kit Ho

Since there is no typical answer for my question, I have written a simple script to automate this process. Feel free to comment this code.

由于我的问题没有典型的答案,我编写了一个简单的脚本来自动化这个过程。请随意评论此代码。

#!/bin/bash
BRANCHES=(
master_branch
develop_branch
testing_branch
)
ORIGINALBRANCH=`git status | head -n1 | cut -c13-`
git commit -m 
CHERRYCOMMIT=`git log -n1 | head -n1 | cut -c8-`
for BRANCH in "${BRANCHES[@]}";
do
    git stash;
    git checkout $BRANCH;
    git cherry-pick $CHERRYCOMMIT;
    git checkout $ORIGINALBRANCH;
    git stash pop;
done

回答by Philip Oakley

Something you might want to have a look at: git stashyour changes, git commit, git checkoutanother branch, git stash apply, git commit, etc.

您可能想要查看的内容:git stash您的更改、git commitgit checkout另一个分支git stash applygit commit、 等。

See the man pages.

请参阅手册页

回答by rangalo

I think you can write a post-commit hook to merge or cherry-pick with the other branches. But it will of course not be a single commit.

我认为您可以编写一个 post-commit hook 来与其他分支合并或挑选。但这当然不会是一次提交。

Hook will automatize what you want to achieve.

Hook 将自动化您想要实现的目标。

http://git-scm.com/docs/githooks

http://git-scm.com/docs/githooks

回答by PraveenMak

Maybe this will help some people,

也许这会帮助一些人,

I used the "Kit Ho"s method above and added it to .gitconfig as alias.

我使用了上面“Kit Ho”的方法并将其添加到 .gitconfig 作为别名。

; commitall commits to the current branch as well the all the branches mentionedin BRANCHES array var as shown below.
commitall = "!f()  { \
    BRANCHES=( \
    branches1 \
    branches2 \
    );  \
    usage() \
    { \
        echo \"Usage: git commitall -m 'JIRA: BRANCHNAME:<comment to check in>'\"; \
        exit 1; \
    }; \
    OPTIND=1; \
    DFNs=\"\"; \
    while getopts \"h:m:\" opt; \
    do \
        case \"$opt\" in \
            h) \
            usage; \
            ;; \
            m)  export Comment=$OPTARG; \
            ;; \
        esac; \
    done; \
    ORIGINALBRANCH=`git symbolic-ref HEAD|cut -d/ -f3- `; \
    echo \"Current branch is $ORIGINALBRANCH \" ; \
    echo $Comment | grep \"^JIRA: $ORIGINALBRANCH:\"  > /dev/null 2>&1 ; \
    if [ $? -ne 0 ]; then \
        usage; \
    fi; \
    LOGMSG=`git log -1 --pretty=%B --grep=\"JIRA: $ORIGINALBRANCH:\" `; \
    MSG='commit first time in this branch is a success' ; \
    if [ \"$LOGMSG\" == \"\" ]; then \
        git commit -m \"$Comment\"; \
    else \
        git commit -a --amend -C HEAD; \
        MSG='commit with amend succeeded' ; \
    fi; \
    if [ $? -ne 0 ]; then \
        echo \"git commit failed!\"; \
        exit 1; \
    else \
        echo \"$MSG\" ; \
    fi; \
    CHERRYCOMMIT=`git log -n1 | head -n 1 | cut -c8- ` ; \
    if [ \"$CHERRYCOMMIT\" == \"\" ]; then \
        echo \"'git log -n1 | head -n 1 | cut -c8-' no commits for this branch\"; \
        exit 1; \
    fi; \
    echo \"found this commit -> $CHERRYCOMMIT for current branch\"; \
    stashes=`git stash list | grep \"WIP on $ORIGINALBRANCH\" ` ; \
    for BRANCH in \"${BRANCHES[@]}\"; do \
        if [ \"$stashes\" ]; then \
            git stash; \
        fi;\
        git checkout $BRANCH; \
        if [ $? -ne 0 ]; then \
            echo \"git checkout $BRANCH failed!\"; \
            exit 1; \
        fi; \
        git cherry-pick $CHERRYCOMMIT; \
        git checkout $ORIGINALBRANCH; \
        if [ \"$stashes\" ]; then \
            git stash pop; \
        fi; \
    done; \
    }; \
f"

回答by Native_Mobile_Arch_Dev

To simultaneously push to multiple branches, simply install & configure SourceTreeand select "Push" and the branches you wish to deploy to. enter image description here

要同时推送到多个分支,只需安装和配置SourceTree并选择“推送”和您希望部署到的分支。 在此处输入图片说明

回答by harald

No, I don't think you can do this. Your best option would be to commit to one of your branches (or a master branch) and then either merge the commit into the others one by one, or cherry-pick the commit into each of the other branches.

不,我认为你不能这样做。您最好的选择是提交到您的一个分支(或主分支),然后将提交一一合并到其他分支,或者将提交挑选到其他每个分支中。

回答by panda

I don't think there is a way to that. Maybe you need to write a bash script for it or make a different repo for different branches.

我不认为有办法做到这一点。也许您需要为它编写一个 bash 脚本或为不同的分支制作不同的 repo。

回答by zoresvit

You can also do nice automation using some Python:

您还可以使用一些 Python 进行出色的自动化:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Populate specified or latest commit across all branches in the repository.

"""

import os
import re
import sys
import sh


git = sh.git.bake(_cwd=os.curdir)

if len(sys.argv) > 1:
    if '-h' in sys.argv or '--help' in sys.argv:
        print('Usage: git-populate.py [commit] [-h|--help]')
        sys.exit(0)
    else:
        commit = sys.argv[1]
else:
    # By default choose latest commit.
    git_log = git('--no-pager', 'log', '-n', '1', '--no-color').stdout
    commit = re.search(r'[a-f0-9]{40}', git_log).group()

print('Commit to be populated: {0:.6s}'.format(commit))

git_branch = git.branch('-a', '--no-color').stdout
source_branch = re.search(r'\*\s(\w+)$', git_branch, re.MULTILINE).group(1)
print('Source branch: {0}'.format(source_branch))

branches = re.findall(r'remotes/\w+/([\w-]+)$', git_branch, re.MULTILINE)
# Exclude current branch from target branches.
branches = [i for i in branches if i != source_branch]
print('Target branches: {0}'.format(branches))


print('Stashing local changes')
git_stash = git.stash().stdout

for branch in branches:
    print('Ading commit {0:.6s} to branch {1}'.format(commit, branch))
    git.checkout(branch)
    try:
        result = git('cherry-pick', commit)
    except sh.ErrorReturnCode_1:
        # Ignore diplicate cherry pick and discard changes.
        git.reset()


git.checkout(source_branch)
print('Return to branch {0}'.format(source_branch))

if not git_stash.startswith('No local changes to save'):
    print('Restoring local changes')
    git.stash.pop()

回答by Martin Gerhardy

It might depend on how you are going to push your commits. I mean you always have the chance to push into multiple branches with one git pushcommand.

这可能取决于您将如何推送您的提交。我的意思是你总是有机会用一个git push命令推送到多个分支。

Do the following .git/configsettings to ensure that the masterbranch will always be pushed to the foobarbranch, too.

执行以下.git/config设置以确保master分支也将始终推送到foobar分支。

[remote "origin"]
        url = [email protected]:mgerhardy/example.git
        fetch = +refs/heads/*:refs/remotes/origin/*
        push = refs/heads/master:refs/heads/master
        push = refs/heads/master:refs/heads/foobar 

But the problem here might be that if these two branches diverged, you can't push to them. You still could reorganize your code that you client detection is based on the branch you are building. That way you could maintain dozens of clients and always keep all the branches in sync.

但这里的问题可能是,如果这两个分支出现分歧,您就无法向它们推送。您仍然可以重新组织您的客户端检测基于您正在构建的分支的代码。这样您就可以维护数十个客户端并始终保持所有分支同步。