撤消git rebase

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

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

  • git签出两个分支的提交父
  • 然后从那里创build一个临时分支
  • 手工挑选所有的承诺
  • replace我通过手动创build的分支重新分配的分支

在我目前的情况下,这是可行的,因为我可以很容易地发现来自两个分支(一个是我的东西,另一个是我的同事的东西)的承诺。

但是,我的方法让我觉得不够理想,容易出错(假设我刚刚在自己的分支机构中重新组build了两个分支机构)。

有任何想法吗?

澄清:我正在谈论重新发布一堆提交重新发布。 不只是一个。

最简单的方法是find分支的头部提交,因为它是在reblog开始之前立即进行的。

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 log "HEAD@{5}"

如果你没有禁用每个分支reflogs,你应该能够简单地执行git reflog branchname@{1}作为rebase分离分支头,然后重新附加到最后的头。 我会仔细检查这一点,虽然我最近还没有证实这一点。

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

 [core] logAllRefUpdates = true 

实际上,rebase将你的出发点保存到ORIG_HEAD所以这通常就像下面这样简单:

 git reset --hard ORIG_HEAD 

但是, resetreset rebasemerge都会将原始HEAD指针保存到ORIG_HEAD因此,如果自从您尝试撤销重新绑定之后执行了任何这些命令,则必须使用reflog。

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

 git rebase --abort 

reset后清理。

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

将分支重置为旧尖端的悬挂提交对象当然是最好的解决scheme,因为它恢复了以前的状态而不费力气。 但是如果你碰巧丢失了那些提交(f.ex.因为你同时收集了你的仓库,或者这是一个新的克隆),你总是可以重新分支分支。 关键是这个--onto开关。

假设你有一个想象力上被称为topic的主题分支,那么当master的提示是0deadbeef提交时,你0deadbeefmaster 。 在topic分支的某个时候,你做了git rebase master 。 现在你想撤消这个。 就是这样:

 git rebase --onto 0deadbeef master topic 

这将采取topic上的所有提交不在master ,并在0deadbeef上重播它们。

使用 – --onto ,你可以重新安排你的历史几乎任何形状

玩的开心。 🙂

实际上,在我做任何不重要的操作之前,我在分支上放置了一个备份标签(大部分的rebase是微不足道的,但如果看上去复杂的话,我会这么做)。

然后,恢复就像git reset --hard BACKUP一样简单。

如果你还没有完成rebase,在它的中间,以下工作:

 git rebase --abort 

如果你已经推动你的分支到远程仓库 (通常是原产地),然后你做了一个成功的git rebase --abort (没有合并)( git rebase --abort给出“没有rebase进行中”),你可以轻松地重置分支使用命令:

git reset –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 

对于多个提交,请记住任何提交引用了所有提交的历史logging。 所以在查尔斯的回答中,把“旧承诺”看作是“旧承诺中最新的承诺”。 如果您重置为该提交,那么导致该提交的所有历史将重新出现。 这应该做你想要的。

使用reflog没有为我工作。

对我来说,工作类似于这里所描述的。 打开重build分支后命名的.git / logs / refs文件,find包含“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和@Zarin的解决scheme之后,我希望我可以简单地做一个评论,但是我没有足够的声望,所以我使用了下面的命令:

而不是做git rebase -i --abort (注意-i )我不得不简单地做git rebase --abort没有 -i )。

同时使用-i--abort会导致Git显示一个使用/选项列表。

所以我以前和当前分支机构的这个解决scheme的状态是:

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

如果你成功地改组了远程分支机构,并且不能再git rebase --abort那么你仍然可以做一些技巧来保存你的工作,而不必强行推送。 假设你当前被错误your-branch称为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丢失的提交
  • git cherry-pick COMMIT_HASH your-branch-rebased提交的每一个提交
  • 推送您的更改。 请注意,两个本地分支与remote/your-branch ,你应该只推送your-branch

比方说,我把主人重新绑定到我的function分支,我得到了30个新的提交,这些提交破坏了一些东西。 我发现通常删除坏提交是最简单的。

 git rebase -i HEAD~31 

最后31次提交的交互式重新分配(如果你select的方式太多,它不会受到伤害)。

只需要提交你想摆脱,并标记为“D”而不是“挑”。 现在提交被有效地删除了rebase(如果你只删除刚刚获得提交时提交)。

如果你在git rebase中搞乱了某些东西,例如git rebase --abort ,而你的文件git reflog will not help符合,它们将会丢失,而git reflog will not help 。 这发生在我身上,你需要在这个框外思考。 如果你像我一样幸运,使用IntelliJ Webstorm,你可以right-click->local history ,无论你使用版本控制软件犯了什么错误,都可以恢复到以前的文件/文件夹状态。 另一个故障安全运行总是很好的。

为了取消,您可以input以下命令:

 git -c core.quotepath=false rebase --abort