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

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

  • git checkout 两个分支的提交父级
  • 然后从那里创建一个临时分支
  • 手动挑选所有提交
  • 将我重新建立基础的分支替换为手动创建的分支

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

然而,我的方法给我的印象是次优且容易出错(假设我刚刚用我自己的两个分支进行了重新调整)。

有任何想法吗?

澄清:我说的是变基,在此期间重放了一堆提交。不止一个。

有帮助吗?

解决方案

最简单的方法是找到分支的头提交,因为它就在 rebase 开始之前 转发日志...

git reflog

并将当前分支重置为它(在使用重置之前要绝对确定的通常警告 --hard 选项)。

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

git reset --hard HEAD@{5}

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

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

您只需执行以下操作即可查看候选老头的历史记录 git log HEAD@{5} (视窗: git log "HEAD@{5}").

如果您没有禁用每个分支重新记录,您应该能够简单地执行以下操作 git reflog branchname@{1} 作为变基,在重新连接到最终头之前会分离分支头。我会仔细检查这一点,尽管我最近没有验证这一点。

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

[core]
    logAllRefUpdates = true

其他提示

实际上,rebase 将你的起点保存为 ORIG_HEAD 所以这通常很简单:

git reset --hard ORIG_HEAD

但是,那 reset, rebasemerge 全部保存原来的 HEAD 指针指向 ORIG_HEAD 因此,如果您在尝试撤消变基后执行了任何这些命令,那么您将不得不使用引用日志。

查尔斯的答案有效,但你可能想这样做:

git rebase --abort

后清理 reset.

否则,您可能会收到消息“Interactive rebase already started”.

git reflog 将向您显示 rebase 之前和之后的所有更改,并允许您找到要重置的正确更改。但令我惊讶的是,还没有人在这里提到另一种超级简单的方法:

变基将旧状态保留为 ORIG_HEAD, ,因此您可以通过运行以下命令来恢复上次变基:

git reset --hard ORIG_HEAD

将分支重置为其旧提示的悬空提交对象当然是最好的解决方案,因为它无需花费任何精力即可恢复之前的状态。但是如果你碰巧丢失了这些提交(f.ex.因为您同时对存储库进行了垃圾收集,或者这是一个新的克隆),您始终可以再次对分支进行变基。这其中的关键是 --onto 转变。

假设您有一个主题分支,富有想象力地称为 topic, ,你分支了 master 当尖端 master0deadbeef 犯罪。在某个时刻 topic 分支,你做到了 git rebase master. 。现在您想要撤消此操作。就是这样:

git rebase --onto 0deadbeef master topic

这将进行所有提交 topic 未开启的 master 并在上面重播它们 0deadbeef.

--onto, ,你可以将你的历史重新排列成几乎 任何形状.

玩得开心。:-)

实际上,在执行任何重要操作之前,我在分支上放置了一个备份标记(大多数变基都是微不足道的,但如果它看起来很复杂,我会这样做)。

然后,恢复就像 git reset --hard BACKUP.

以防万一 您已将分支推送到远程存储库 (通常是起源)然后你就完成了成功的变基(没有合并)(git rebase --abort 给出“没有进行中的变基”)你可以轻松地 重置分支 使用命令:

git重置--hard origin/{branchName}

例子:

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is ahead of 'origin/{branchName}' by 135 commits.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

$ ~/work/projects/{ProjectName} $ git reset --hard origin/{branchName}
HEAD is now at 6df5719 "Commit message".

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is up-to-date with 'origin/{branchName}.

nothing to commit, working directory clean

如果您尚未完成变基并且处于中间,则可以执行以下操作:

git rebase --abort

使用 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

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

按照@Allan和@Zearin的解决方案,我希望我可以简单地发表评论,但我没有足够的声誉,所以我使用了以下命令:

而不是做 git rebase -i --abort (注意 -我)我必须简单地做 git rebase --abort (没有-我).

两者同时使用 -i--abort 同时使 Git 向我显示用法/选项列表。

所以我以前和当前使用此解决方案的分支状态是:

matbhz@myPc /my/project/environment (branch-123|REBASE-i)
$ git rebase --abort

matbhz@myPc /my/project/environment (branch-123)
$

如果您成功地针对远程分支重新建立基础但不能 git rebase --abort 您仍然可以采取一些技巧来保存您的工作,并且不必强制推送。假设您当前被错误地重新定位的分支称为 your-branch 并正在追踪 origin/your-branch

  • git branch -m your-branch-rebased # 重命名当前分支
  • git checkout origin/your-branch # 签出已知来源的最新状态
  • git checkout -b your-branch
  • 查看 git log your-branch-rebased, , 相比于 git log your-branch 并定义缺少的提交 your-branch
  • git cherry-pick COMMIT_HASH 对于每一次提交 your-branch-rebased
  • 推动你的改变。请注意,两个当地分支机构与 remote/your-branch 你应该只推 your-branch

假设我将 master 重新设置为我的功能分支,并且我收到了 30 个新提交,这些提交破坏了某些内容。我发现通常删除错误的提交是最简单的。

git rebase -i HEAD~31

最后 31 次提交的交互式变基(如果您选择太多也没有什么坏处)。

只需获取您想要删除的提交并用“d”而不是“pick”标记它们即可。现在,提交已被有效删除,从而撤消变基(如果您仅删除变基时刚刚获得的提交)。

如果您在分支机构,您可以使用:

git reset --hard @{1}

不仅有 HEAD 的参考日志(通过 git reflog),每个分支还有 reflog(通过以下方式获得) git reflog <branch>)。所以,如果你在 master 然后 git reflog master 将列出该分支的所有更改。您可以通过以下方式参考该更改 master@{1}, master@{2}, , ETC。

git rebase 通常会多次更改 HEAD,但当前分支只会更新一次。

@{1} 简单来说就是一个 当前分支的快捷方式, ,所以它等于 master@{1} 如果你在 master.

git reset --hard ORIG_HEAD 如果你使用的话将不起作用 git reset 在互动过程中 rebase.

对于新手/任何害怕进行硬重置的人,您可以从引用日志中签出提交,然后将其保存为新分支。

git reflog

找到开始变基之前的提交。您可能需要进一步向下滚动才能找到它(按 Enter 或 PageDown)。记下 HEAD 编号并替换 57:

git checkout HEAD@{57}

检查分支/提交,如果看起来不错,请使用此 HEAD 创建一个新分支:

git checkout -b new_branch_name

git重置--hard origin/{branchName}

是重置通过 rebase 完成的所有本地更改的正确解决方案。

我通常做的是git reset #commit_hash

到我认为 rebase 没有效果的最后一次提交。

然后 git pull

现在,您的分支应该与 master 完全匹配,并且 rebased 提交不应包含在其中。

现在,人们可以挑选该分支上的提交。

如果你在 git rebase 中弄乱了一些东西,例如 git rebase --abort, ,当您有未提交的文件时,它们将会丢失并且 git reflog 不会有帮助。这发生在我身上,你需要跳出框框思考。如果你像我一样幸运并且使用 IntelliJ Webstorm 那么你可以 right-click->local history 并且无论您使用版本控制软件犯了什么错误,都可以恢复到文件/文件夹的先前状态。再次运行故障保护总是好的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top