如果当前提交是合并提交,为什么git rebase -i HEAD~~
在我可以修改的提交中不包含它?
rebase
的文档在哪里说合并提交无法修改?
这是一个显示我的意思的简单设置:
git init test_git
cd test_git
touch a
git add a
git commit -m "added a"
git branch feature
git checkout feature
echo "version 1" >a
git commit -a -m "version 1"
git checkout master
echo "version 2" >a
git commit -a -m "version 2"
git merge feature
echo "version 3" >a
git commit -a -m "resolved merge"
git rebase -i HEAD~~
此时,我收到了这条消息的文本编辑器:
pick 6746909 version 2
pick 830dbd0 version 1
# Rebase 3848032..d7c0f38 onto 3848032
当前(合并)提交是d7c0f38,它甚至在评论中提到。但它并不是我实际选择/编辑/压缩/等等的提交。
答案 0 :(得分:4)
因为git rebase
默认情况下不会保留合并。这可以使用--preserve-merges
关闭,但文档说明了......
这在内部使用--interactive机器,但明确地将它与--interactive选项结合使用通常不是一个好主意,除非你知道你在做什么(见下面的BUGS)。
git rebase
的原因是在另一次提交之前真正重放你的提交,因此合并被消除了。为了说明原因,我已经复制了你的回购。
$ git log --oneline --graph --decorate
* 5eb2e82 (HEAD -> master) resolved merge
|\
| * 42cfeab (feature) version 1
* | d6a71b8 version 2
|/
* 267627b added a
当我跑git rebase -i HEAD~~
时,我看到了这一点:
pick d6a71b8 version 2
pick 42cfeab version 1
# Rebase 267627b..5eb2e82 onto 267627b (2 commands)
注意最后一位,"到267627b"这是"添加了"承诺。这两个提交,"版本1"和"版本2"将修补#34;添加一个"。结果将是线性的,不需要合并。
由于分支,甚至还存在必须解决的冲突。两个提交都改变了#34;添加了一个",所以无论他们做了什么顺序,他们都会发生冲突。
冲突得到解决,这就是结果。
* d6a71b8 (HEAD -> master) version 2
* 267627b added a
"版本1"转变吗?解决冲突意味着"版本1"不再有任何更改,因此rebase删除了空提交。这样做是为了避免重新引入可能已经合并的提交。您可以使用--keep-empty
关闭此行为,尽管没有什么理由。
如果您确实要保留合并,我建议首先在master上重新设置功能分支,然后合并 并强制合并 。让我们说你有这个。
A - B - C - G - H [master]
\
D - E - F [feature]
首先,在主人身上使用rebase功能。
git checkout feature
git rebase master
A - B - C - G - H [master]
\
D1 - E1 - F1 [feature]
这会产生线性历史记录,功能现在位于master之上,任何冲突都必须解决,并且功能可以使用master中的所有更新进行测试。
一旦测试了功能,它就可以与master合并。由于master没有新的更改,通常合并会快进,导致这种情况发生。
A - B - C - G - H - D1 - E1 - F1 [feature]
[master]
现在很难看出哪些更改是功能的一部分,是未来调试的重要环境。相反,我们希望保证合并提交--no-ff
。
git checkout master
git merge --no-ff feature
结果是这样的:
A - B - C - G - H ------------ I [master]
\ /
D1 - E1 - F1 [feature]
历史是线性的,并且它也清楚什么提交作为一个分支一起完成,并且合并提交可以用来解释分支。
这是我合并功能分支的常规过程。