撤消Git重基

撤消Git重基,git,git-rebase,assembla,Git,Git Rebase,Assembla,我在我的分支上执行了一个git-rebase-master,直到我把它推到远程后才意识到这不是我想要的。只有我和另外一个人在做这个项目,所以我知道他们还没有做出最新的改变 在阅读有关StackOverflow的其他问题时,它说要使用git reflog,然后在重新基址之前使用git reset--hard HEAD@{n}。我这样做是为了转到我在重新基址之前创建的提交,但它并没有恢复到以前的状态 我漏了一步吗?有没有办法让另一个人强迫回购协议恢复原状 谢谢如果您确实从reflog(也是正常git

我在我的分支上执行了一个
git-rebase-master
,直到我把它推到远程后才意识到这不是我想要的。只有我和另外一个人在做这个项目,所以我知道他们还没有做出最新的改变

在阅读有关StackOverflow的其他问题时,它说要使用
git reflog
,然后在重新基址之前使用
git reset--hard HEAD@{n}
。我这样做是为了转到我在重新基址之前创建的提交,但它并没有恢复到以前的状态

我漏了一步吗?有没有办法让另一个人强迫回购协议恢复原状


谢谢

如果您确实从reflog(也是正常git日志中条目的尾部)获取提交散列,那么您可以得到reset——硬提交,然后是git push-f origin master,它通常是一个。我建议在执行强制推送之前,将完整的历史记录签出到一个单独的、干净的目录中

我有好消息和坏消息要告诉你

好消息是,你现在的状态是你!
master
上的最后一次提交现在确实在您的分支中,宇宙一切都很好

坏消息是,现在,通过你的重基操作,你已经有效地将你的分支移到了大师的顶端;也就是说,您的开发分支现在处于相同的状态,就像您只是从master的顶端分支一样

但这[被认为]是一件好事:如果您没有任何合并冲突,您在这个过程中没有丢失任何数据,并且您的分支上也没有毫无价值的合并提交

,所以我不再重复了。从你描述的操作来看,你不应该损失任何工作


如果您确实希望在强制推送之前重新创建原始历史记录,则具有非推送历史记录的用户可以强制将其分支推送到远程存储库。这将导致你的回购协议的状态与他们推出回购协议时的状态相同。

因此,你可能不应该费心去撤销这个重新基准:这可能是你想要的。尽管如此,请继续阅读如何撤销它


对分支使用reflog,因为它更易于阅读。(头reflog有相同的信息,但是里面有很多东西,因此很难找到你想要的东西。)

例如,如果我刚刚重新设置了mybranch的基础,我会看到:

$ git reflog mybranch
nnnnnnn mybranch@{0}: rebase finished: refs/heads/mybranch onto biguglysha1
ooooooo mybranch@{1}: commit: some sort of commit message
...
因此,
mybranch@{1}
的名称(目前)与
ooooooo
同义,即旧缩写SHA-1。每次对分支执行操作(例如
git reset
)时,
@{…}
部分中的数字都会发生变化,而SHA-1是永久的,因此使用SHA-1(完整或缩写)进行剪切和粘贴更安全

如果你当时:

$ git checkout mybranch # if needed
以及:

你应该把原件拿回来。这是因为
rebase
只是复制提交,然后移动标签。在重新基址之后,但在重置之前,提交图看起来像这样,其中
A
C
是“您的”提交:

请注意,现在,在重置后,重基生成的提交副本是仅在reflog条目中找到的“放弃”副本。原先被遗弃的原件现在又在
mybranch
下被认领

考虑这一点的方法是绘制提交图(新提交指向其父提交),然后绘制带有指向提交图的长箭头的分支标签。除了添加newcommittes之外,该图没有任何变化,它有新的和不同的大而丑陋的SHA-1(这就是为什么我使用
A
B
C
等字母,并在副本上添加
A'
)。SHA-1保证是唯一的并且是永久的,但是带有长箭头的标签会一直被擦除和重新指向。(如果在白板上执行此操作,则提交图通常应使用黑色,标签应使用一种或几种颜色。)


1嗯,
git reset
不仅仅是移动标签,除非添加一些命令行标志。默认情况下,它移动标签并重置索引;使用
--hard
,它移动标签、重置索引并清除工作树。使用
--soft
时,它只移动标签,而不移动索引和工作树。git就是这样,有更多的标志进一步扭曲了它的含义,但它们是三大标志:
--soft
,nothing aka
--mixed
,和
--hard

2如果git只增加了一些东西,那么随着时间的推移,你的回购协议将变得越来越大。因此,最终,“不可访问”提交那些没有标签的提交,甚至没有任何剩余的reflog条目指向它们,并且没有被某个有标签的提交指向,或者其他指向提交的提交最终会提交这些不可访问的提交(以及任何其他不可访问的对象)当git为您自动运行
git gc
时,将删除。你可以强迫他们更早地被移除,但是很少有好的理由去烦恼

3Git本身取决于担保。从数学上讲,任何两个不同的物体都有可能得到同一个SHA-1,但这是极不可能的。如果发生这种情况,git就会崩溃。4如果分布足够好,概率是2160中的1,这是非常小的。这是一件好事,因为它很快提高了可能性,但是因为它开始时很小,所以它保持很小,实际上它从来都不是一个问题

4根据设计,“破坏”是指git只是停止添加对象,所以到目前为止一切都还不错。然后,你必须转向任何新的系统来处理数十亿个对象存储库,“下一代”git或其他任何东西。

详细说明“它没有恢复到以前的状态。”
$ git reset --hard ooooooo  # or mybranch@{1}
          A - B - C              <-- (only in reflog now)
        /
... - o - o - o - A' - B' - C'   <-- mybranch (after rebase)
          A - B - C              <-- mybranch, plus older reflog
        /
... - o - o - o - A' - B' - C'   <-- (only in reflog now)