如何轻松撤消git重基?冗长的手动方法是:

签出两个分支的提交父级创建并签出临时分支手工挑选所有提交重置故障的重基分支以指向临时分支

在我目前的情况下,这是可行的,因为我可以很容易地发现两个分支的提交(一个是我的东西,另一个是同事的东西)。然而,我的方法给我的印象是次优且容易出错(假设我刚刚用自己的两个分支重新建立了基础)。

澄清:我所说的是一个重基,在重基过程中,多次提交被重复,而不仅仅是一次。


当前回答

最简单的方法是找到分支的头部提交,因为它在reflog中的rebase开始之前。。。

git reflog

并将当前分支重置为它(通常需要注意的是,在使用--hard选项重设种子之前要绝对确定)。

假设ref日志中的旧提交是HEAD@{2}:

git reset --hard HEAD@{2}

在Windows中,您可能需要引用引用:

git reset --hard "HEAD@{2}"

您可以通过执行git-log head@{2}(Windows:git-log“head@{2}”)来检查候选旧标头的历史记录。

如果您没有禁用每个分支的reflog,您应该能够简单地执行gitreflog branchname@{1},因为在重新连接到最终头之前,rebase会分离分支头。我会再次检查这个,尽管我最近没有验证过。

默认情况下,为非裸存储库激活所有reflog:

[core]
    logAllRefUpdates = true

其他回答

最简单的方法是找到分支的头部提交,因为它在reflog中的rebase开始之前。。。

git reflog

并将当前分支重置为它(通常需要注意的是,在使用--hard选项重设种子之前要绝对确定)。

假设ref日志中的旧提交是HEAD@{2}:

git reset --hard HEAD@{2}

在Windows中,您可能需要引用引用:

git reset --hard "HEAD@{2}"

您可以通过执行git-log head@{2}(Windows:git-log“head@{2}”)来检查候选旧标头的历史记录。

如果您没有禁用每个分支的reflog,您应该能够简单地执行gitreflog branchname@{1},因为在重新连接到最终头之前,rebase会分离分支头。我会再次检查这个,尽管我最近没有验证过。

默认情况下,为非裸存储库激活所有reflog:

[core]
    logAllRefUpdates = true

对于多次提交,请记住,任何提交都引用导致该提交的所有历史记录。因此,在查尔斯的回答中,将“旧承诺”读为“旧承诺中的最新承诺”。如果您重置为该提交,那么导致该提交的所有历史记录都将重新出现。这应该是你想要的。

将分支重置为其旧提示的悬空提交对象当然是最好的解决方案,因为它可以恢复以前的状态,而无需花费任何精力。但是,如果您碰巧丢失了这些提交(例如,因为您同时垃圾收集了存储库,或者这是一个新的克隆),您可以再次重新设置分支的基础。这一点的关键是--on开关。

假设你有一个想象中的主题分支,称为topic,当master的提示是0deadbeef提交时,你分支了master。在主题分支的某个时刻,您完成了git rebase master。现在您要撤消此操作。以下是操作方法:

git rebase --onto 0deadbeef master topic

这将接收所有关于主题的提交,但这些提交不在主控上,并在0个标题的顶部回放它们。

有了--on,你可以将你的历史重新整理成任何形状。

玩得开心。:-)

使用reflog对我不起作用。

对我有用的东西与这里描述的相似。在.git/logs/refs中打开以重新基于分支命名的文件,找到包含“rebase finsihed”的行,类似于:

5fce6b51 88552c8f Kris Leech <me@example.com> 1329744625 +0000  rebase finished: refs/heads/integrate onto 9e460878

签出行中列出的第二个提交。

git checkout 88552c8f

一旦确认这包含了我丢失的变化,我就分支起来,松了一口气。

git log
git checkout -b lost_changes

实际上,rebase将您的起点保存到ORIG_HEAD,因此这通常很简单:

git reset --hard ORIG_HEAD

然而,reset、rebase和merge都会将原始HEAD指针保存到ORIG_HEAD中,因此,如果您在尝试撤消rebase之后执行了这些命令,则必须使用reflog。