Git将修补程序合并到多个分支

时间:2012-05-25 21:04:51

标签: git branching-and-merging merge-conflict-resolution

我一直试图围绕git分支模型。我一直在寻找http://nvie.com/posts/a-successful-git-branching-model/的一些想法和来自Subversion的一件事我真的很期待在一个地方做一个改变并将它合并到需要它的所有分支。在Subversion中,我们最终做了很多代码副本。

但是我仍然没有完全理解这一点。这是我所拥有的标准类型的工作流程,它总是会产生冲突。

# create new version branch
git checkout master
git checkout -b v3
vim pom.xml  # change branch version to "3.1-SNAPSHOT"
git commit -a
git checkout master
vim pom.xml  # change master version to "4.0-SNAPSHOT"
git commit -a

所以主人处于4.0-SNAPSHOT,分支处于3.1-SNAPSHOT。

我不想在分支上创建修补程序并将其移动到主干。

git checkout v3
git checkout -b hotfix
vim file.txt  # make a bugfix change
git commit -a
git checkout v3
git merge hotfix  # this works fine
git checkout master
git merge hotfix  # this has a conflict since both branches have changed the version

我明白为什么会发生这种情况并且有意义。有没有更好的方法呢?

我读到了关于樱桃挑选的内容,我测试过并且确实有效:

git checkout v3
git cherry-pick a518b0b75eaf28868
git checkout master
git cherry-pick a518b0b75eaf28868

但是,这似乎不是处理此问题的“正确”方法。有什么建议吗?

4 个答案:

答案 0 :(得分:19)

如果你想获得超级技术,你可以从一个共同的祖先创建修补程序:

git merge-base v3 master
git checkout -b hotfix <whatever you got from merge-base>
# make your fix
git checkout v3 && git merge --no-ff hotfix
git checkout master && git merge --no-ff hotfix

        v3--------v3 (hotfixed)
       /         /
ancestor----hotfix
       \         \
        master----master (hotfixed)

--no-ff标志突出显示Git将创建合并提交,将hotfix分支标签保留在修补程序提示处,而不是将标签拉到v3或{{ 1}}。 (您可以省略该标志并获得相同的行为,因为master分支有一个提交不在hotfixmaster。更多信息in the docs。)< / p>

就个人而言,我认为这太过分了。我会选择gahooa:在有意义的分支上制作修补程序,然后根据你希望分支相互关联的方式进行合并或挑选。

答案 1 :(得分:11)

真的,你的答案取决于你是否希望你的树基于相同的历史...例如,4.0基于最新的3.X + 4.0中的所有变化......

就个人而言,一旦您决定为新版本启动新分支,我不建议您这样做。在给定的时间点,软件采取不同的方向,所以你的分支也应该。

这使git cherry-pick成为理想的解决方案。在任何分支最有意义的情况下进行更改,然后将其选择到旧版本。这与检出旧分支并且手动应用相同更改并进行新提交相同。它保持清洁和重点。

Git merge或rebase将尝试将分支历史集成在一起,每个都以他们自己的方式,我怀疑你在向后移植错误修复时不想要等...

答案 2 :(得分:1)

在这种情况下,您正在使用分支“4.0”并且必须对“3.1”进行修复,您可以在提交“3.1”后重新设置“4.0”:

确保您在功能分支4.0上:

git checkout 4.0

保存当前工作,以便查看其他分支:

git stash  
git checkout 3.1  

进行编辑和提交:

git commit -a -m "bug fix"  
git checkout 4.0  

取回您的更改:

git stash apply  

更改4.0,使其成为“3.1”当前头部的分支:

git rebase "3.1"

答案 3 :(得分:0)

I've been struggling with this question, too, and I think if you're willing to change your versioning strategy a little (i.e., depart from the -SNAPSHOT versions that Maven encourages), this could be solved by using a fixed version (like SNAPSHOT or 0.0.0-SNAPSHOT) on master (or whatever your development branch is). (The SNAPSHOT suffix is important, if you're using Maven, since Maven treats SNAPSHOT-versioned artifacts differently than others.)

In fact, I think you'd want to institute a policy of only ever changing the version number on your production branch (the one from which you build releases) or on branches which are for release purposes only (e.g., changing version numbers) and which you never intend to merge back to the development branch.

I haven't actually used this strategy yet, but was just thinking about it, and I think I'll start trying it.