有谁知道如何轻松撤消git rebase?
想到的唯一方法是手动进行:
-
git checkout两个分支的提交父级
-
然后从那里创建一个临时分支
-
cherry-pick所有提交手工
-
用手动创建的分支替换我重新定位的分支
在我目前的情况下,这将是有效的,因为我可以很容易地发现两个分支的提交(一个是我的东西,另一个是我的同事的东西) .
然而,我的方法让我感到不理想和容易出错(假设我刚刚用自己的2个分支进行了重新定位) .
有任何想法吗?
澄清:我正在谈论一个rebase,在此期间重播了一堆提交 . 不仅仅是一个 .
15 回答
最简单的方法是找到分支的头部提交,因为它是在reflog中的rebase开始之前...
并将当前分支重置为它(关于在使用
--hard
选项重置之前绝对确定的常见警告) .假设旧的提交在ref日志中是
HEAD@{5}
:在Windows中,您可能需要引用引用:
您只需执行
git log HEAD@{5}
(Windows:git log "HEAD@{5}"
)即可查看候选旧头的历史记录 .如果你没有禁用每个分支reflogs你应该能够简单地做
git reflog branchname@{1}
,因为rebase在重新连接到最终头之前分离分支头 . 我会仔细检查这个,但我最近没有证实这一点 .默认情况下,为非裸存储库激活所有reflog:
实际上,rebase将你的起点保存到
ORIG_HEAD
所以这通常很简单:但是,
reset
,rebase
和merge
全部将原始HEAD
指针保存到ORIG_HEAD
中,因此,如果您尝试撤消,则必须使用reflog .查尔斯的答案有效,但你可能想这样做:
在
reset
后清理 .否则,您可能会收到消息“
Interactive rebase already started
” .将分支重置为其旧提示的悬空提交对象当然是最佳解决方案,因为它可以在不花费任何精力的情况下恢复之前的状态 . 但是,如果您碰巧丢失了这些提交(f.ex . 因为您在此期间垃圾收集了您的存储库,或者这是一个新的克隆),您可以再次重新绑定该分支 . 关键是
--onto
开关 .假设您有一个富有想象力的主题分支
topic
,当master
的提示是0deadbeef
提交时,您分支master
. 在topic
分支的某个时刻,你做了git rebase master
. 现在你要撤消这个 . 这是如何做:这将使
topic
上的所有提交都不在master
上,并在0deadbeef
之上重播它们 .使用
--onto
,您可以将历史重新排列成几乎任何形状 .玩得开心 . :-)
在我做任何非常重要的操作之前,我实际上在分支上放了一个备份标签(大多数rebase都很简单,但如果它看起来很复杂,我会这样做) .
然后,恢复就像
git reset --hard BACKUP
一样简单 .如果 you had pushed your branch to remote repository (通常它's origin) and then you'已完成一个成功的rebase(没有合并)(
git rebase --abort
给"No rebase in progress")你可以轻松 reset branch 使用命令:例:
我很惊讶这里没有人提到过这个 . Rebase将旧状态保留为
ORIG_HEAD
,因此您可以通过运行以下命令恢复最后一个rebase:如果您尚未完成rebase,并且在其中间,则以下工作:
对于多次提交,请记住任何提交都会引用导致该提交的所有历史记录 . 所以在查尔斯的回答中,将“旧提交”称为“旧提交的最新内容” . 如果重置为该提交,则会再次出现导致该提交的所有历史记录 . 这应该做你想要的 .
使用
reflog
对我不起作用 .对我有用的东西类似于here所述 . 打开以重新命名的分支命名的.git / logs / refs中的文件,找到包含"rebase finsihed"的行,如下所示:
签出该行上列出的第二个提交 .
一旦确认,这包含了我失去的变化,我分支并松了一口气 .
根据@Allan和@Zearin的解决方案,我希望我可以简单地做一个评论,但我没有足够的声誉,所以我使用了以下命令:
而不是做
git rebase -i --abort
(注意 -i )我不得不做git rebase --abort
( without -i ) .同时使用
-i
和--abort
会导致Git向我显示使用/选项列表 .因此,此解决方案的先前和当前分支状态为:
如果你成功地反对远程分支并且不能
git rebase --abort
你仍然可以做一些技巧来保存你的工作并且没有强制推动 . 假设您当前的分支是错误地重新命名为your-branch
并正在跟踪origin/your-branch
git branch -m your-branch-rebased
#重命名当前分支git checkout origin/your-branch
#checkout到原始已知的最新状态git checkout -b your-branch
检查
git log your-branch-rebased
,与git log your-branch
进行比较并定义your-branch
中缺少的提交在
your-branch-rebased
中每次提交git cherry-pick COMMIT_HASH
推动您的更改 . 请注意,两个本地分支与
remote/your-branch
相关联,您应该只推送your-branch
假设我将master重新绑定到我的功能分支,并且我得到了30个新的提交,它们会破坏某些东西 . 我发现通常最简单的方法就是删除糟糕的提交 .
最近31次提交的交互式rebase(如果选择的方式太多则不会受到影响) .
只需要删除你想要删除的提交,并用“d”而不是“pick”标记它们 . 现在删除了提交,有效地删除了rebase(如果只删除了刚刚进行rebased时提交的提交) .
如果你在git rebase中混淆了一些东西,例如
git rebase --abort
,虽然您有未提交的文件,但它们将丢失且git reflog
无效 . 这发生在我身上,你需要在这里开箱即思考 . 如果你像我一样幸运并使用IntelliJ Webstorm那么你可以right-click->local history
并且可以恢复到文件/文件夹的先前状态,无论你使用版本控制软件犯了什么错误 . 另一个故障安全运行总是好的 .要取消,您可以输入以下命令: