我有以下情况:
$ git --version
git version 2.7.3.windows.1
$ git log --graph --oneline
* 83e3254 version 1.1
* 34188af merge of feature into master
|\
| * 784ba31 awesome change
|/
* 6eec273 added file1
* 84d80a5 added version file
Run Code Online (Sandbox Code Playgroud)
要在新目录中重现此问题
rm -rf .git
git init
echo version 1.0 > version.txt
git add version.txt
git commit -m "added version file"
echo file1 > file1
git add file1
git commit -m "added file1"
git checkout -b feature
echo awesome change >> file1 && git commit -am "awesome change"
git checkout master
git merge --no-ff --no-commit feature
echo "small fixup" >> file1
git commit -am "merge of feature into master"
echo version 1.1 > version.txt
git commit -am "version 1.1"
Run Code Online (Sandbox Code Playgroud)
现在我看到这个功能适用于1.1版本.所以我这样做了:
git rebase --preserve-merges -i master~3
Run Code Online (Sandbox Code Playgroud)
用这个作为git-rebase-todo
pick 6eec273 added file1
pick 83e3254 version 1.1
pick 784ba31 awesome change
pick 34188af merge of feature into master
Run Code Online (Sandbox Code Playgroud)
得到了这个:
$ git log --graph --oneline
* 34188af merge of feature into master
|\
| * 784ba31 awesome change
|/
* 6eec273 added file1
* 84d80a5 added version file
Run Code Online (Sandbox Code Playgroud)
83e3254发生了什么?我错过了什么吗?当我需要保留合并时,我应该在todofile中使用34188af吗?
这可能与变形机制的记录不完善有关.从git rebase文档:
Run Code Online (Sandbox Code Playgroud)-p --preserve-merges通过重放合并提交引入的提交来重新创建合并提交,而不是展平历史记录.不保留合并冲突解决方案或手动修改合并提交.
这在
--interactive内部使用机器,但明确地将它与--interactive选项结合起来通常不是一个好主意, 除非你知道你在做什么(见下面的BUGS).
在-i和--interactive选项是同义的.
我们来看看BUGS部分:
显示的待办事项列表
--preserve-merges --interactive不代表修订图的拓扑.编辑提交和重写他们的提交消息应该可以正常工作,但尝试重新提交提交往往会产生违反直觉的结果.例如,尝试重新排列
Run Code Online (Sandbox Code Playgroud)1 --- 2 --- 3 --- 4 --- 5至
Run Code Online (Sandbox Code Playgroud)1 --- 2 --- 4 --- 3 --- 5通过移动"选择4"线将导致以下历史记录:
Run Code Online (Sandbox Code Playgroud)3 / 1 --- 2 --- 4 --- 5
Melebius的答案是正确的(并且被否决);它与交互式rebase尝试将提交重播为一系列樱桃小贴士的方式有关。由于合并实际上并不是挑剔的,因此保留合并模式使用秘密辅助通道1来确定如何重新执行合并,并且该辅助通道取决于提交顺序。
但是,重新执行合并还有另一个问题。通过运行重做合并git merge。这是您的原始合并:
git checkout master
git merge --no-ff --no-commit feature
echo "small fixup" >> file1 # DANGER WILL ROBINSON
git commit -am "merge of feature into master"
Run Code Online (Sandbox Code Playgroud)
(请注意我的补充说明)。此“小修正”不是两个输入的一部分:它是通过--no-commit功能手动添加的,并且是通过手动操作添加的。有时称为“邪恶合并”:
当git rebase -p“重播”的合并,它这样做没有 --no-commit,然后自动移动上到下一个线性化的承诺。因此,即使您保留提交顺序并因此获得了正确的重新建立历史记录,像这样故意引入的任何更改都将丢失。
这是有文档记录的,请参见引用的文本,其中指出:
合并冲突解决方案或手动修订以合并提交不会保留。
-但我认为该句子必须使用粗体闪烁的72点字体或类似内容。:-)
1这并不是真的很秘密:只需查看交互式rebase代码即可。使用文件查看器或编辑器,查看$(git --exec-path)/git-rebase--interactive。搜索字符串“ preserv”(在保留或保留中),并观察该函数pick_one_preserving_merges以及pick_one如果$rewritten存在命名目录的情况下调用该函数的代码。的的使用$rewritten目录是相当复杂的,虽然(它适用于合并保留和非合并保留互动底垫,并依赖于一个事实,即没有对--preserve或-p选项,最初的“待办事项”列表中没有实际的合并,因此简单地使它们变平)。
| 归档时间: |
|
| 查看次数: |
1106 次 |
| 最近记录: |