撤消git rebase

时间:2020-03-06 14:44:16  来源:igfitidea点击:

有人知道如何轻松撤消git rebase吗?

想到的唯一方法是手动进行操作:

  • git签出两个分支的提交父对象
  • 然后从那里创建一个临时分支
  • 手动选择所有提交
  • 用手动创建的分支替换我重新建立基础的分支

在我目前的情况下,这是可行的,因为我可以轻松地发现两个分支的提交(一个是我的东西,另一个是我同事的东西)。

但是,我的方法给我的印象是次优且容易出错(假设我刚刚使用自己的2个分支进行了重新基准化)。

有任何想法吗?

澄清:我说的是在重新部署过程中重播一堆提交的问题。不只是一个

解决方案

最简单的方法是找到分支的头提交,就像在reflog中开始重新建立基础之前一样。

git reflog

并将其重置为当前分支(通常的警告是在使用--hard选项进行重置之前必须绝对确定)。

假设旧的提交是参考日志中的" HEAD @ {5}":

git reset --hard HEAD@{5}

在Windows中,我们可能需要引用以下引用:

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

我们可以通过执行git log HEAD @ {5}(Windows:git log" HEAD @ {5}"")来检查候选旧头的历史记录。

如果尚未对每个分支引用禁用,则应该能够简单地执行" git reflog branchname @ {1}",因为在重新连接到最终头之前,重新配置会先分离分支头。我会仔细检查,尽管最近还没有验证。

默认情况下,针对非裸存储库激活所有引用日志:

[core]
    logAllRefUpdates = true

对于多个提交,请记住任何提交都引用导致该提交的所有历史记录。因此,在Charles的答案中,将"旧提交"读为"最新的旧提交"。如果我们重置为该提交,则导致该提交的所有历史记录将重新出现。这应该做我们想要的。

将分支重置为其旧提示的悬挂提交对象当然是最佳解决方案,因为它无需花费任何精力即可恢复先前的状态。但是,如果我们恰巧丢失了这些提交(例如,因为在此期间我们对存储库进行了垃圾回收,或者这是一个新鲜的克隆),则始终可以再次为分支建立基础。关键是" --onto"开关。

假设我们有一个主题分支,想象中的名为" topic",当" master"的提示是" 0deadbeef"提交时,我们从" master"分支出来。在" topic"分支上的某个时刻,我们做了" gitrebasemaster"。现在我们要撤消此操作。这是如何做:

git rebase --onto 0deadbeef master topic

这将把所有在主主题上的主题提交到主主题上,然后在0deadbeef之上重播。

使用" --onto",我们可以将历史记录重新排列成几乎任何形状。

玩得开心。 :-)

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

git reset --hard ORIG_HEAD

但是,resetrebasemerge都将原始的HEAD指针保存到ORIG_HEAD中,因此,如果自从调整基础以来我们已经执行了任何这些命令,则尝试撤消操作,然后我们将必须使用reflog。

实际上,在执行任何无关紧要的操作之前,我实际上在分支上放置了一个备份标签(大多数rebase是无关紧要的,但是如果看起来很复杂,我会这样做)。

然后,恢复就像git reset --hard BACKUP一样容易。

查尔斯的答案有效,但我们可能需要这样做:

git rebase --abort

重置后进行清理。

否则,我们可能会收到消息"交互式资源库已经开始"。