首页 文章

撤消git rebase

提问于
浏览
2562

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

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

  • git checkout两个分支的提交父级

  • 然后从那里创建一个临时分支

  • cherry-pick所有提交手工

  • 用手动创建的分支替换我重新定位的分支

在我目前的情况下,这将是有效的,因为我可以很容易地发现两个分支的提交(一个是我的东西,另一个是我的同事的东西) .

然而,我的方法让我感到不理想和容易出错(假设我刚刚用自己的2个分支进行了重新定位) .

有任何想法吗?

澄清:我正在谈论一个rebase,在此期间重播了一堆提交 . 不仅仅是一个 .

15 回答

  • 10

    最简单的方法是找到分支的头部提交,因为它是在reflog中的rebase开始之前...

    git reflog
    

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

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

    git reset --hard HEAD@{5}
    

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

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

    您只需执行 git log HEAD@{5} (Windows: git log "HEAD@{5}" )即可查看候选旧头的历史记录 .

    如果你没有禁用每个分支reflogs你应该能够简单地做 git reflog branchname@{1} ,因为rebase在重新连接到最终头之前分离分支头 . 我会仔细检查这个,但我最近没有证实这一点 .

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

    [core]
        logAllRefUpdates = true
    
  • 3533

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

    git reset --hard ORIG_HEAD
    

    但是, resetrebasemerge 全部将原始 HEAD 指针保存到 ORIG_HEAD 中,因此,如果您尝试撤消,则必须使用reflog .

  • 3

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

    git rebase --abort
    

    reset 后清理 .

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

  • 53

    将分支重置为其旧提示的悬空提交对象当然是最佳解决方案,因为它可以在不花费任何精力的情况下恢复之前的状态 . 但是,如果您碰巧丢失了这些提交(f.ex . 因为您在此期间垃圾收集了您的存储库,或者这是一个新的克隆),您可以再次重新绑定该分支 . 关键是 --onto 开关 .

    假设您有一个富有想象力的主题分支 topic ,当 master 的提示是 0deadbeef 提交时,您分支 master . 在 topic 分支的某个时刻,你做了 git rebase master . 现在你要撤消这个 . 这是如何做:

    git rebase --onto 0deadbeef master topic
    

    这将使 topic 上的所有提交都不在 master 上,并在 0deadbeef 之上重播它们 .

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

    玩得开心 . :-)

  • 11

    在我做任何非常重要的操作之前,我实际上在分支上放了一个备份标签(大多数rebase都很简单,但如果它看起来很复杂,我会这样做) .

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

  • 15

    如果 you had pushed your branch to remote repository (通常它's origin) and then you'已完成一个成功的rebase(没有合并)( git rebase --abort 给"No rebase in progress")你可以轻松 reset branch 使用命令:

    git reset --hard origin /

    例:

    $ ~/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
    
  • 51

    我很惊讶这里没有人提到过这个 . Rebase将旧状态保留为 ORIG_HEAD ,因此您可以通过运行以下命令恢复最后一个rebase:

    git reset --hard ORIG_HEAD
    
  • -8

    如果您尚未完成rebase,并且在其中间,则以下工作:

    git rebase --abort
    
  • 54

    对于多次提交,请记住任何提交都会引用导致该提交的所有历史记录 . 所以在查尔斯的回答中,将“旧提交”称为“旧提交的最新内容” . 如果重置为该提交,则会再次出现导致该提交的所有历史记录 . 这应该做你想要的 .

  • 326

    使用 reflog 对我不起作用 .

    对我有用的东西类似于here所述 . 打开以重新命名的分支命名的.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
    
  • -3

    根据@Allan和@Zearin的解决方案,我希望我可以简单地做一个评论,但我没有足够的声誉,所以我使用了以下命令:

    而不是做 git rebase -i --abort (注意 -i )我不得不做 git rebase --abortwithout -i ) .

    同时使用 -i--abort 会导致Git向我显示使用/选项列表 .

    因此,此解决方案的先前和当前分支状态为:

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

    如果你成功地反对远程分支并且不能 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

  • 15

    假设我将master重新绑定到我的功能分支,并且我得到了30个新的提交,它们会破坏某些东西 . 我发现通常最简单的方法就是删除糟糕的提交 .

    git rebase -i HEAD~31
    

    最近31次提交的交互式rebase(如果选择的方式太多则不会受到影响) .

    只需要删除你想要删除的提交,并用“d”而不是“pick”标记它们 . 现在删除了提交,有效地删除了rebase(如果只删除了刚刚进行rebased时提交的提交) .

  • 79

    如果你在git rebase中混淆了一些东西,例如 git rebase --abort ,虽然您有未提交的文件,但它们将丢失且 git reflog 无效 . 这发生在我身上,你需要在这里开箱即思考 . 如果你像我一样幸运并使用IntelliJ Webstorm那么你可以 right-click->local history 并且可以恢复到文件/文件夹的先前状态,无论你使用版本控制软件犯了什么错误 . 另一个故障安全运行总是好的 .

  • 64

    要取消,您可以输入以下命令:

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

相关问题