当git rebase失败时,它会修改冲突的文件,这不是很方便。有没有办法,如何阻止git rebase这样做?
当git rebase失败时,用户显然希望得到一些输出到命令行的冲突行的diff(目标x补丁)。怎么做到这一点?
注意:由于这两个问题,我从第一次学习使用git后就避免使用git rebase。我从目标派生出新的分支并使用git cherry pick -X theirs
(强制樱桃挑选)。之后我使用git diff
和git commit --amend
来解决问题,这不是直截了当的,但对我来说比git rebase更有效。
答案 0 :(得分:1)
您想要的文件位于为合并冲突保留的暂存插槽中的索引中。
当git rebase失败时,它会修改冲突的文件,这不是很方便。有没有办法,如何阻止git rebase这样做?
没有
但它还有更多的东西。 Rebase本质上是一系列git cherry-pick
操作,每个樱桃选择实际上是一个合并 - 一个三向合并,给出两个左/本地/ HEAD
/ {一个不寻常的合并基础{1}}和右/远程/其他/ --ours
提交。
考虑这个“在rebase之前”和“在rebase之后”序列:
--theirs
要从“之前”到“之后”,Git首先检查提交[before rebase]
...--o--*--A--B--C <-- yourbranch
\
D--E <-- target
[after rebase]
...--o--*--A--B--C [mostly abandoned]
\
D--E <-- target
\
A'-B'-C' <-- yourbranch
(作为分离的HEAD)。然后运行E
。
这个挑选操作运行合并,合并基础为提交git cherry-pick <hash-of-A>
,*
或--ours
提交提交HEAD
,{{1提交是E
。
与所有合并一样,每个文件的实际合并都使用三个合并分段插槽在索引中进行。这些编号:插槽1用于合并基础,插槽2用于--theirs
版本,插槽3用于A
版本。
如果合并顺利,最终的合并结果将复制到插槽零,擦除插槽1-3条目,然后Git继续。如果没有,则文件的 work-tree 版本将以您不想要的方式标记。但是,文件的所有其他三个版本仍保留在索引,插槽1(仅编号),插槽2(可通过--ours
提供)和插槽3(可通过{获取)中{1}} git checkout --theirs
git show`:
git checkout --ours
例如。
解决工作树中的合并冲突后,运行git checkout --theirs). You can therefore obtain any or all three versions of the file into the work-tree using
将or
复制到插槽零中,清除插槽1,2和3条目。一旦所有此类文件得到解决,您就可以运行git show :1:file > file.base
git show :2:file > file.head
git checkout --theirs file # overwrite work-tree version
(如果是重新定位,或git add file
,如果挑选),让Git像往常一样提交索引的结果。
对于rebase,下一步是复制commit file
:
git rebase --continue
这种复制就像git cherry-pick --continue
一样,这意味着合并基础是提交B
,...--o--*--A--B--C <-- yourbranch
\
D--E <-- target
\
A' <-- HEAD
提交是提交git cherry-pick
,{{1 commit是commit A
。如果存在合并冲突,那么这些是您将在索引中找到的文件的三个版本。
在解决此冲突并运行--ours
之后,如果提交A'
的选择因冲突而停止,您将获得此信息:
--theirs
现在三个索引版本将来自合并基础B
,git rebase --continue
提交C
和...--o--*--A--B--C <-- yourbranch
\
D--E <-- target
\
A'-B' <-- HEAD
提交B
。< / p>
因此,您希望的文件可用。它们只位于索引中,而不是工作树中。