扭转意外的git rebase更改

时间:2017-08-26 14:59:24

标签: git

我在我的存储库上执行了一个不合适的git命令,我试图弄清楚如何扭转我的行为效果。

我的"预先错误"状态(即我试图恢复的状态)在使用git log --oneline --graph --decorate --all进行记录时显示如下所示(为了清楚起见,我自己添加了额外的评论):

* 9aaaaaa (HEAD -> master) commit message 9
* 8aaaaaa commit message 8                  <=== note that this...
| * 7aaaaaa (branchB) commit message 7
|/  
| * 6aaaaaa (branchA) commit message 6
| * 5aaaaaa commit message 5
| * 4aaaaaa commit message 4, i.e. branchA~2
| * 3aaaaaa commit message 3
|/  
* 2aaaaaa commit message 2                  <=== ...descends from this
* 1aaaaaa commit message 1

我想在branchA分支中重新提交一个提交。所以我输入了以下命令:git rebase -i branchA~2打算使用reword命令并完成。进入rebase窗口后,我决定不做任何更改并退出。但是,我怀疑我没有取消操作并退出,因为我应该有,而是保存文件并退出。我认为,问题是,为了尝试我正在做的事情,我应该首先检查自己branchA然后执行git rebase -i branchA~2。但是,我不恰当地从master分支开始。因此,我想我以某种方式告诉git我现在希望我的master分支以新的方式连接branchA~2,即提交4aaaaaa,这是我不想要的。

因此,在save-and-quit之后,我的提交树现在如下所示:

* 9bbbbbb (HEAD -> master) commmit message 9
* 8bbbbbb commit message 8                    <=== now, instead, this...
| * 7aaaaaa (branchB) commit message 7
| | * 6aaaaaa (branchA) commit message 6
| | * 5aaaaaa commit message 5
| |/  
|/|   
* | 4aaaaaa commit message 4, i.e. branchA~2  <=== ...descends from this...
* | 3aaaaaa commit message 3
|/  
* 2aaaaaa commit message 2
* 1aaaaaa commit message 1

请注意,如上面的注释所示,在原始状态下,commit 8aaaaaa直接来自commit 2aaaaaa,但是在我的rebase命令之后,相应的commit {{1}现在从提交8bbbbbb下降,即从提交4aaaaaa

那么,我该如何回到原来的状态呢?

我没有尝试任何事情,因为我对进一步搞砸事情感到非常紧张。以下是一些可能性:

  • 留在branchA~2分支,然后master
  • 做一些挑选樱桃的重新安排。
  • git rebase -i 2aaaaaa
  • 中摆弄一些东西

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

  1. 复制整个仓库,这样您就不必害怕进行进一步的更改。
  2. 运行git reflog。您应该会看到以前的分支提示:9aaaaaa7aaaaaa6aaaaaa
  3. 将分支重置为这些SHA1:git checkout master && git reset --hard 9aaaaaa等。
  4. 那有用吗?
    • 是的:太棒了,让我们参加派对。
    • 否:对不起,请从副本中恢复并等待更好的答案。
  5. 这里重要的一点是,无论何时重写历史记录,旧提交都不会就地更改或删除。在重写之前:

    ...--A--B <-- branch
    

    重写后:

    ...--A--B
      \
       \--A'--B' <-- branch
    

    正如你所看到的,没有任何东西指向B,所以整个分支都“丢失”了,但它没有被删除(除非你运行git gc或类似的东西)并且你需要做的就是恢复它将branch指针翻转回B.

答案 1 :(得分:2)

我不确定我是完全从图中发生了什么,而是我常见的&#34;恐慌按钮&#34;在borked rebase或更改的情况下,是使用git reflog检查reflog。

From the documentation

  

参考日志,或&#34; reflogs&#34;,记录分支的提示和   其他引用已在本地存储库中更新。 Reflogs是   在各种Git命令中有用,用于指定a的旧值   参考

基本上,您应该能够在尝试使用rebase之前查看当前分支的提示位置。然后,您可以使用git reset <commit hash>将分支重置为其所处的状态,从根本上忽略您的更改。它通常比试图撤消你刚刚做的任何事情更简单(并且处理具有分支副本的人的潜在影响)。

reflog输出可能看起来像(从本地仓库生成):

75d2e74 HEAD@{0}: rebase -i (finish): returning to refs/heads/master
75d2e74 HEAD@{1}: rebase -i (reword): I was trying to do something with a change here. 
3b7e664 HEAD@{2}: cherry-pick: fast-forward
16180cd HEAD@{3}: <some other git operation>

你可以看到对rebase尝试的先前操作是一个挑选,​​对你来说它可能会有所不同。使用git show进行检查,看看它是否适合用作重置点。

即使您的重置出错(例如您重置太远),您也可以再次检查reflog并再次进行重新设置。