假设我想从发布分支合并到主分支,并且发布分支中有一些我不想包含在主分支中的提交。有没有办法进行合并,以便不会合并其中一个或多个提交?
到目前为止,我的策略是执行以下操作(在掌握中):
git merge --no-commit release-branch
# Resolve conflicts and apply reverse patch of the commits that I don't want included
git commit # Edit commit message so that it lists the commits that have been reverse-patched
有更好的方法吗?
答案 0 :(得分:105)
我找到了一个适合我的解决方案in the Pro Git book。
假设您要排除文件config.php
。
在分支A:
在同一目录中创建一个名为.gitattributes
的文件,使用以下行:config.php merge=ours
。这告诉git在合并文件时使用什么策略。在这种情况下,它始终保持您的版本,即。您正在合并的分支上的版本。
添加.gitattributes
文件并提交
在分支B上:重复步骤1-2
立即尝试合并。您的文件应保持不变。
答案 1 :(得分:43)
创建一个新分支,以交互方式重新分支该分支并删除您不想要的提交,然后将其合并。
如果没有重新划分,你不能从分支的中间进行更改,但是当它在后来的合并中看到相同的变化时会发生正确的事情(例如,从樱桃采摘和什么不是)。
答案 2 :(得分:14)
如果您有支持分支,您可以在其中修复错误并构建新版本。在master上你有下一个版本,你也经常建立新的版本。
每次构建新版本时,都要更改某个文件中的版本,提交新文件,创建标记并推送。现在,从 support 到 master 的合并将始终在包含版本信息的文件中发生冲突。
如果包含版本信息仅的文件包含版本信息,您可以使用fcurella的答案。但如果它确实也可能包含可合并信息(pom.xml,gradle.properties,MANIFEST.MF,...),则必须执行一些额外的操作。
让我们使用以下示例
C---D*---E---F* support
/
A---B---G---H*---I master
其中明星提交仅包含因合并期间应忽略的版本更改而发生的更改。
要将支持合并到 master 而不会因版本构建而发生合并冲突,您可以执行以下任一操作:
git checkout master
git merge C
git merge D -s ours
git merge E
git merge F -s ours
使用-s ours
参数,我们告诉git只记录合并而不改变工作区。这与to the --record-only
option of svn相当。
以上将导致以下布局
-------------C---D*---E---F* support
/ \ \ \ \
A---B---G---H*---I---J---K----L---M master
git checkout master
git merge support -s ours --no-commit
git cherry-pick C E --no-commit
git commit -m 'merged support into master'
首先我们开始合并,但只记录我们正在合并,而不改变工作空间而不进行合并提交。然后,我们正在挑选合并的提交,再次没有提交。最后我们正在进行合并。
以上将导致以下布局
C---D*---E---F* support
/ \
A---B---G---H*---I---J master
甚至可以自动采摘樱桃。
git checkout master
git merge support -s ours --no-commit
for id in `git log support --reverse --not HEAD --format="%H [%an] %s" |
grep -v "bump version" |
sed "s/\(\w*\)\s.*/\1/g"`
do
git cherry-pick --no-commit $id
done
git commit -m 'merged support into master'
答案 3 :(得分:4)
这不能直接完成的原因是每个提交都包含指向父提交的链接(通常只有一个提交但有几个用于合并)。这样,如果你有一个提交(通过它的SHA1总和),整个历史也是固定的,因为父母也包含他们的父母的链接,等等。因此,在历史记录中省略补丁的唯一方法是编写一个新补丁。新创建的分支上的git rebase -i可能是实现这一目标的最简单方法。
答案 4 :(得分:2)
也可以修改.git / info / attributes文件,并将其保存在.git文件夹中,而不是添加全部的.gitattribute文件,最终需要将它们添加到源代码控制中。
答案 5 :(得分:2)
主要问题是:您希望如何表示要跳过的提交?
不幸的是没有。 2在历史图表中无法表达。
没有。 1是可能的,但我永远不会这样做:合并提交可以包含更改。 - 通常,合并提交指向两个或多个分支的合并结果:在这些分支中开发的所有内容应该在合并之后的代码中(即在合并提交指向的代码中)。此提交中没有其他内容。
但令人惊讶的是,您可以更改整个代码库并将其表示为合并。合并的效果是双重的:它合并历史树和它应合并两个代码库。前者确实如此(否则没有人称之为合并),后者可能会失败,例如:当合并冲突出现并且错误地解决时(然后代码库没有正确合并)。
其他一些答案表明这种隐藏。我推荐使用显式方式:merge plus revert commits。
答案 6 :(得分:1)
如果您只想排除最后的一些提交,您只需提交一个特定的提交号:
git checkout partlyMergedFrom
git whatchanged
--> find the commit hash up to where you want to merge
git checkout partlyMergedInto
git merge e40a0e384f58409fe3c864c655a8d252b6422bfc
git whatchanged
--> check that you really got all the changes you want to have