撤消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
但是, reset
, reset
rebase
和merge
都会将原始HEAD
指针保存到ORIG_HEAD
因此,如果自从您尝试撤销重新绑定之后执行了任何这些命令,则必须使用reflog。
查尔斯的答案有用,但你可能想这样做:
git rebase --abort
reset
后清理。
否则,您可能会收到消息“ Interactive rebase already started
”。
将分支重置为旧尖端的悬挂提交对象当然是最好的解决scheme,因为它恢复了以前的状态而不费力气。 但是如果你碰巧丢失了那些提交(f.ex.因为你同时收集了你的仓库,或者这是一个新的克隆),你总是可以重新分支分支。 关键是这个--onto
开关。
假设你有一个想象力上被称为topic
的主题分支,那么当master
的提示是0deadbeef
提交时,你0deadbeef
了master
。 在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