我修改了而不是解决交互式rebase中的冲突。我可以撤消吗?

时间:2017-01-03 08:38:11

标签: git amend git-merge-conflict

我正在做一个很大的交互式rebase,我正在编辑8个提交。这是通过git commit --amend完成的。我的问题是,有一次我遇到了合并冲突,我没有注意到,所以我继续天真地修改和git rebase --continue - ing。显然我现在已经将多个提交修改为一个,并且在完成rebase之后大约有4个提交已经消失了。这些更改已修改为其他提交。

有什么方法可以撤消这些修改,或者重新申请已经失效的提交?

当然;一个解决方案就是回去再做一次rebase,但是我在rebase中做了很多编辑,所以我很想不必重新完成我的所有工作。我是如何陷入这种困境的另一个故事。

Git树示例:

在rebase之前:A-B-C-D-E-F

在rebase之后:A-B-C-F(C现在修改了D和E)

3 个答案:

答案 0 :(得分:3)

是的,你可以。

通常情况下,我会马上回去重做所有内容,但我能理解这个问题 - 听起来你已经投入了大量的时间进入rebase,所以似乎没有邀请再做一遍。< / p>

我假设您示例中F的内容正是您希望最终结果的内容,您只是错过了DE提交。

你可以做的是:

git checkout C             # "git status" should be empty right now
git checkout F .
git reset .
git add only-changes-from-D ; git commit -m D
git add only-changes-from-E ; git commit -m E
git add -A ; git commit -m F

git checkout F . ; git reset .使得您的工作目录包含F,但您的HEAD仍指向C,索引中没有任何内容。 git status现在会显示CF之间的完全差异。

现在,您可以使用自己喜欢的添加/提交工具(我喜欢git gui)并选择最初属于D的所有更改,并提交。重复E。之后,只有来自F的更改;你可以一次添加和提交它们。当然,如果EF之间有更多,则必须冲洗并重复。

这样做的好处是您实际上不需要更改任何内容。最终结果将是F,但您将根据需要获得一些中间提交。

答案 1 :(得分:3)

您所做的每一次提交,修改与否,仍然“在那里”,并且它们都可以通过reflog找到。这是因为git commit --amend 实际上 原样。

提交你没有制作(即,如果索引中存在冲突的状态以便git commit拒绝提交)当然不会保存。< / p>

使用git reflog(或git reflog HEAD)查找每次提交。您可能希望将原始哈希ID保存在文件中以进行剪切和粘贴,因为命名它们的简单方法HEAD@{3}等等都是相对的,并且会不断变换。 (即,每次调整HEAD时,HEAD@{3}现在是HEAD@{4}HEAD@{5},很快HEAD@{7},最后是HEAD@{198},augh !:-))

您还可以使用名称ORIG_HEAD立即恢复原始链(如果您没有运行任何其他命令)。也就是说,当您运行git rebase -i然后执行所有编辑,修改提交等等,最后完成时,会发生的事情是git rebase将原始分支提示保存在名称{{ 1}}。您可以将新分支或标记名称指向该原始提交,然后使用ORIG_HEADnamename~1等来引用原始(预先变更)承诺:

name~2

现在git tag oops ORIG_HEAD 提交oopsF提交oops~1,依此类推。

您可以E任何提交,git show从中获取文件,git checkout <commit-id> -- <path>将该提交应用为您当前位置的增量,依此类推。

答案 2 :(得分:2)

在重新定位/修改提交后,原始提交仍在此处。虽然如果它无法通过分支到达,但它不会出现在git log

我认为在git reflog的帮助下,你可以设法做你想做的事。

git reflog //identify the hash of the commits you want, look for your commit --amend that you want to undo git checkout B git cherry-pick hash-of-commit-C-as-resolved-during-rebase-but-before-amending git cherry-pick hash-of-commit-C-after-amending-with-D git cherry-pick hash-of-commit-C-after-amending-with-E git cherry-pick F