撤消 git rebase
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/134882/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Undoing a git rebase
提问by webmat
Does anybody know how to easily undo a git rebase?
有人知道如何轻松撤消 git rebase 吗?
The only way that comes to mind is to go at it manually:
想到的唯一方法是手动进行:
- git checkout the commit parent to both of the branches
- then create a temp branch from there
- cherry-pick all commits by hand
- replace the branch in which I rebased by the manually-created branch
- git checkout 提交父级到两个分支
- 然后从那里创建一个临时分支
- 手工挑选所有提交
- 用手动创建的分支替换我重新定位的分支
In my current situation this is gonna work because I can easily spot commits from both branches (one was my stuff, the other was my colleague's stuff).
在我目前的情况下,这是可行的,因为我可以轻松地发现两个分支的提交(一个是我的东西,另一个是我同事的东西)。
However my approach strikes me as suboptimal and error-prone (let's say I had just rebased with 2 of my own branches).
然而,我的方法让我觉得不理想且容易出错(假设我刚刚用我自己的 2 个分支重新定位)。
Any ideas?
有任何想法吗?
Clarification: I'm talking about a rebase during which a bunch of commits were replayed. Not only one.
澄清:我说的是 rebase,在此期间重放了一堆提交。不止一个。
回答by CB Bailey
The easiest way would be to find the head commit of the branch as it was immediately before the rebase started in the reflog...
最简单的方法是找到分支的头部提交,因为它是在reflog 中rebase 开始之前的那一刻......
git reflog
and to reset the current branch to it (with the usual caveats about being absolutely sure before reseting with the --hard
option).
并将当前分支重置为它(通常的警告是在使用--hard
选项重置之前绝对确定)。
Suppose the old commit was HEAD@{5}
in the ref log:
假设旧提交HEAD@{5}
在引用日志中:
git reset --hard HEAD@{5}
In Windows, you may need to quote the reference:
在 Windows 中,您可能需要引用参考:
git reset --hard "HEAD@{5}"
You can check the history of the candidate old head by just doing a git log HEAD@{5}
(Windows:git log "HEAD@{5}"
).
您只需执行git log HEAD@{5}
( Windows:) 即可查看候选老头的历史记录git log "HEAD@{5}"
。
If you've not disabled per branch reflogs you should be able to simply do git reflog branchname@{1}
as a rebase detaches the branch head before reattaching to the final head. I would double check this, though as I haven't verified this recently.
如果你没有禁用每个分支的引用日志,你应该能够简单地做,git reflog branchname@{1}
因为 rebase 在重新连接到最终头之前分离分支头。我会仔细检查这个,虽然我最近没有验证过。
Per default, all reflogs are activated for non-bare repositories:
默认情况下,非裸存储库的所有引用日志都被激活:
[core]
logAllRefUpdates = true
回答by Pat Notz
Actually, rebase saves your starting point to ORIG_HEAD
so this is usually as simple as:
实际上,rebase 可以保存您的起点,ORIG_HEAD
因此这通常很简单:
git reset --hard ORIG_HEAD
However, the reset
, rebase
and merge
all save your original HEAD
pointer into ORIG_HEAD
so, if you've done any of those commands since the rebase you're trying to undo then you'll have to use the reflog.
但是,reset
,rebase
和merge
所有将您的原始HEAD
指针保存到ORIG_HEAD
so 中,如果您在尝试撤消变基后执行了这些命令中的任何一个,那么您将不得不使用引用日志。
回答by Allan
Charles's answer works, but you may want to do this:
查尔斯的回答有效,但您可能想要这样做:
git rebase --abort
to clean up after the reset
.
后清理reset
。
Otherwise, you may get the message “Interactive rebase already started
”.
否则,您可能会收到消息“ Interactive rebase already started
”。
回答by Aristotle Pagaltzis
Resetting the branch to the dangling commit object of its old tip is of course the best solution, because it restores the previous state without expending any effort. But if you happen to have lost those commits (f.ex. because you garbage-collected your repository in the meantime, or this is a fresh clone), you can always rebase the branch again. The key to this is the --onto
switch.
将分支重置为其旧提示的悬空提交对象当然是最好的解决方案,因为它无需花费任何努力即可恢复先前的状态。但是,如果您碰巧丢失了这些提交(例如,因为您在此期间对存储库进行了垃圾收集,或者这是一个新的克隆),您可以随时重新重新设置分支。这其中的关键是--onto
开关。
Let's say you had a topic branch imaginatively called topic
, that you branched off master
when the tip of master
was the 0deadbeef
commit. At some point while on the topic
branch, you did git rebase master
. Now you want to undo this. Here's how:
假设您有一个想象性地称为 的主题分支topic
,master
当提示master
是0deadbeef
提交时,您将其分支。在topic
分支上的某个时候,你做了git rebase master
。现在您想撤消此操作。就是这样:
git rebase --onto 0deadbeef master topic
This will take all commits on topic
that aren't on master
and replay them on top of 0deadbeef
.
这将获取所有topic
未打开的提交master
并在0deadbeef
.
With --onto
, you can rearrange your history into pretty much any shape whatsoever.
有了--onto
,您可以将您的历史重新排列成几乎任何形状。
Have fun. :-)
玩得开心。:-)
回答by Alex Gontmakher
I actually put a backup tag on the branch before I do any nontrivial operation (most rebases are trivial, but I'd do that if it looks anywhere complex).
在执行任何重要操作之前,我实际上在分支上放置了一个备份标签(大多数 rebase 都是微不足道的,但如果它看起来很复杂,我会这样做)。
Then, restoring is as easy as git reset --hard BACKUP
.
然后,恢复就像git reset --hard BACKUP
.
回答by Maksym
In case you had pushed your branch to remote repository(usually it's origin) and then you've done a succesfull rebase (without merge) (git rebase --abort
gives "No rebase in progress") you can easily reset branchusing
command:
如果您已将分支推送到远程存储库(通常是源代码库),然后您已经成功完成了 rebase(没有合并)(git rebase --abort
给出“No rebase in progress”),您可以使用命令轻松重置分支:
git reset --hard origin/{branchName}
git reset --hard origin/{branchName}
Example:
例子:
$ ~/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
回答by Kris
Using reflog
didn't work for me.
使用reflog
对我不起作用。
What worked for me was similar to as described here. Open the file in .git/logs/refs named after the branch that was rebased and find the line that contains "rebase finsihed", something like:
对我有用的方法与此处描述的类似。打开以重新定位的分支命名的 .git/logs/refs 中的文件,找到包含“rebase finsihed”的行,例如:
5fce6b51 88552c8f Kris Leech <[email protected]> 1329744625 +0000 rebase finished: refs/heads/integrate onto 9e460878
Checkout the second commit listed on the line.
签出该行上列出的第二个提交。
git checkout 88552c8f
Once confirmed this contained my lost changes I branched and let out a sigh of relief.
一旦确认这包含了我丢失的更改,我就松了一口气。
git log
git checkout -b lost_changes
回答by Greg Hewgill
For multiple commits, remember that any commit references all the history leading up to that commit. So in Charles' answer, read "the old commit" as "the newest of the old commits". If you reset to that commit, then all the history leading up to that commit will reappear. This should do what you want.
对于多次提交,请记住任何提交都会引用导致该提交的所有历史记录。因此,在 Charles 的回答中,将“旧提交”读作“旧提交中的最新提交”。如果您重置为该提交,则导致该提交的所有历史记录都将重新出现。这应该做你想做的。
回答by Matheus Felipe
Following the solution of @Allan and @Zearin, I wish I could simply do a comment though but I don't enough reputation, so I have used the following command:
按照@Allan 和@Zearin 的解决方案,我希望我可以简单地发表评论,但我没有足够的声誉,所以我使用了以下命令:
Instead of doing git rebase -i --abort
(note the -i) I had to simply do git rebase --abort
(withoutthe -i).
而不是做git rebase -i --abort
(注意-i),我不得不简单地做git rebase --abort
(没有的-i)。
Using both -i
and --abort
at the same time causes Git to show me a list of usage/options.
同时使用-i
,并--abort
在同一时间将导致混帐给我的使用/选项列表。
So my previous and current branch status with this solution is:
因此,我以前和当前使用此解决方案的分支状态是:
matbhz@myPc /my/project/environment (branch-123|REBASE-i)
$ git rebase --abort
matbhz@myPc /my/project/environment (branch-123)
$
回答by Sergey P. aka azure
If you successfully rebased against remote branch and can not git rebase --abort
you still can do some tricks to save your work and don't have forced pushes.
Suppose your current branch that was rebased by mistake is called your-branch
and is tracking origin/your-branch
如果您成功地针对远程分支重新定位并且不能,git rebase --abort
您仍然可以做一些技巧来保存您的工作并且没有强制推送。假设您当前错误地重新定位的分支被调用your-branch
并且正在跟踪origin/your-branch
git branch -m your-branch-rebased
# rename current branchgit checkout origin/your-branch
# checkout to latest state that is known to origingit checkout -b your-branch
- check
git log your-branch-rebased
, compare togit log your-branch
and define commits that are missing fromyour-branch
git cherry-pick COMMIT_HASH
for every commit inyour-branch-rebased
- push your changes. Please aware that two local branches are associated with
remote/your-branch
and you should push onlyyour-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