撤消Git Rebase

use*_*364 24 git assembla git-rebase

git rebase master在我的分支上执行了一次,直到我将它推到遥控器之后才意识到它不是我想要的.只有我自己和另外一个人参与这个项目,所以我知道他们没有采取最新的变化.

在StackOverflow上阅读其他问题,它说要使用git reflog然后git reset --hard HEAD@{n}再到rebase之前.我这样做是为了转到我在rebase之前创建的一个提交,但它没有恢复到以前的状态.

我错过了一步吗?有没有办法让对方强行推回他的回购以恢复他们的状态?

谢谢

tor*_*rek 54

正如Makoto已经指出的那样,你可能不应该费心去掉这个底板:它可能就是你想要的.尽管如此,请随时阅读如何撤消它.


使用分支的reflog ,因为它更容易阅读.(HEADreflog具有相同的信息,但其中包含更多内容,因此更难找到您要查找的内容.)

例如,如果我刚刚重新定位mybranch,我会看到:

$ git reflog mybranch
nnnnnnn mybranch@{0}: rebase finished: refs/heads/mybranch onto biguglysha1
ooooooo mybranch@{1}: commit: some sort of commit message
...
Run Code Online (Sandbox Code Playgroud)

mybranch@{1}因此,该名称与ooooooo旧的缩写SHA-1 同义(目前).每次你对分支做某事(例如git reset)时,@{...}部件内部的数字都会改变,而SHA-1永远是永久性的,因此使用SHA-1(全部或缩写)进行切割更安全一点糊.

如果你那么:

$ git checkout mybranch # if needed
Run Code Online (Sandbox Code Playgroud)

和:

$ git reset --hard ooooooo  # or mybranch@{1}
Run Code Online (Sandbox Code Playgroud)

你应该有原来的回来.这是因为rebase只需复制提交然后移动标签.在rebase之后,但在重置之前,提交图看起来像这样,其中Athrough C是"你的"提交:

          A - B - C              <-- (only in reflog now)
        /
... - o - o - o - A' - B' - C'   <-- mybranch (after rebase)
Run Code Online (Sandbox Code Playgroud)

git reset简单地1擦除当前分支标签并将其粘贴到提供的SHA-1上(如果需要,首先将reflog名称转换为SHA-1).因此,在reset:

          A - B - C              <-- mybranch, plus older reflog
        /
... - o - o - o - A' - B' - C'   <-- (only in reflog now)
Run Code Online (Sandbox Code Playgroud)

请注意,现在,post- reset,rebase制作的提交副本是"废弃的",只能在reflog条目中找到.已经放弃的原件现在mybranch再次被声称.

考虑这个问题的方法是绘制提交图(使用指向其父提交的新提交),然后使用指向提交图的长箭头绘制分支标签.图表从来2名除了更改添加 的提交,其中有新的和不同的大丑SHA-1(这就是为什么我使用信件像A BC代替,和粘性的添加剂,如A'为复印件).SHA-1保证是唯一的3并且是永久性的,但带有长箭头的标签会一直被擦除和重新指向.(如果在白板上执行此操作,通常应使用黑色作为提交图,使用颜色或多种颜色作为标签.)


1嗯,git reset除了添加一些命令行标志之外,不仅仅是移动标签.默认情况下,它会移动标签重置索引; with --hard,它移动标签重置索引清除你的工作树.有了--soft只是移动的标签,留下独自索引和工作树.随着git的存在,有更多的旗帜进一步扭曲了意义,但那些是三--soft巨头:,没有什么又名--mixed,和--hard.

2如果git只添加了东西,那么你的回购会随着时间的推移而增长.所以,最终,"无法访问"的承诺,那些没有标签,甚至没有任何剩余的引用日志条目,指着他们,而不是指向的一些承诺是不会有一个标签,或其他一些指向的commit-当git git gc自动运行时,最终会删除这些无法访问的提交(以及任何其他无法访问的对象).你可以强制它们被删除,但很少有理由去打扰.

3 Git本身取决于保证.它在数学上是可能的,但极不可能的是,任何两个不同的物体都可以使用相同的SHA-1.如果发生这种情况,git会中断.4 如果分布足够好,则概率为2 160中的1,这非常小.这是一件好事,因为"生日悖论"很快就提出了这种可能性,但由于它开始时非常小,它仍然很小,在实践中它从来都不是问题.

4根据设计,"破损"是git只是停止添加对象,所以到目前为止所有东西仍然是好的.然后你必须转向任何新的系统来处理数十亿的对象存储库,"下一代"git或其他什么.