如果有人推迟重置或重置到发布的分支后,如何恢复/重新同步?

我们都听说过,不应该把已发表的作品重新发布,这是危险的。但是,我还没有看到任何关于如何处理这种情况的食谱,以防出版物发行。

现在请注意,如果知识库仅由一个已知​​的(最好是小的)人群克隆,那么推动重新署名或重置的人可以通知其他人下一次他们需要关注取(!)。

我看到的一个明显的解决scheme将工作,如果你有没有本地提交foo ,它得到重定位:

 git fetch git checkout foo git reset --hard origin/foo 

这将简单地抛弃foo的本地状态以支持其远程存储库的历史logging。

但是如果一个人在这个分支上进行了实质性的地方性改变,那么我们如何处理呢?

在推基金之后恢复同步在大多数情况下并不复杂。

 git checkout foo git branch old-foo origin/foo # BEFORE fetching!! git fetch git rebase --onto origin/foo old-foo foo git branch -D old-foo 

IE浏览器。 首先你build立了远程分支原来的位置的书签,然后你使用它来重放你的本地提交到重新发起的远程分支上。

重新激活就像暴力:如果它不能解决你的问题,你只需要更多。 ☺

当然,如果你查找pre-rebase origin/foo commit ID,就可以不用书签来做这件事。

这也是你如何处理你提取之前忘了做书签的情况。 什么都不会丢失 – 你只需要检查远程分支的reflog:

 git reflog show origin/foo | awk ' PRINT_NEXT==1 { print $1; exit } /fetch: forced-update/ { PRINT_NEXT=1 }' 

这将打印在最近一次获取更改历史logging之前origin/foo指向的提交ID。

你可以简单地

 git rebase --onto origin/foo $commit foo 

我想说从 git-rebase手册页的上游rebase部分恢复几乎涵盖了所有这一切。

与从你自己的债务中恢复过来的情况确实没有什么不同 – 你把一个分行搬了过来,把所有在历史上有分支的分行重新分配到新的位置。

从2014年第一季度的git 1.9 / 2.0开始,在重写上游分支之前,您不必标记之前的分支来源,如Aristotle Pagaltzis的回答所述 :
请参见提交07d406b并提交d96855f :

在使用git checkout -b topic origin/master创buildtopic分支之后,远程跟踪分支origin/master的历史可能已经被重绕和重build,导致这种形状的历史logging:

  o---B1 / ---o---o---B2--o---o---o---B (origin/master) \ B3 \ Derived (topic) 

origin/master点用于指向提交B3B2B1 ,现在它指向B ,并且当origin/master点在B3topic分支在其之上被启动。

此模式使用origin/master的reflog来查找B3作为分叉点,以便可以通过以下方式将topic重新组织在更新的origin/master之上

 $ fork_point=$(git merge-base --fork-point origin/master topic) $ git rebase --onto origin/master $fork_point topic 

这就是为什么git merge-base命令有一个新选项:

 --fork-point:: 

find一个分支(或任何导致<commit>历史)从另一个分支(或任何引用) <ref>分支的点。
这不仅仅是寻找两个提交的共同祖先,而且还考虑到了<ref>的引用日志,以查看<ref> <commit>的历史是否来自分支<ref>的更早版本


git pull --rebase ”命令使用分支的工作所基于的“ base ”分支(通常是远程跟踪分支)的reflog条目来计算被重新分支的分支的分叉点,以便处理该情况其中“基地”分支已经被重新卷起和重build。

例如,如果历史看起来像在哪里:

  • 当前提交的“ base ”分支在B ,但是先前的提取观察到它的提示曾经是B3 ,然后是B2 ,然后是B1 ,然后才到达当前的提交,
  • 在最新的“基础”之上重新分配的分支基于提交B3

它试图通过检查“ git rev-list --reflog base ”(即BB1B2B3 )的输出来findB3 ,直到find作为当前提示“ Derived (topic) ”的祖先的提交。

在内部,我们有get_merge_bases_many() ,它可以一次性计算出来。
我们希望在Derived和虚构的合并提交之间build立一个合并基础,合并所有“ base (origin/master) ”的历史提示。
当这样的提交存在时,我们应该得到一个与“ base ”的reflog条目完全匹配的结果。


Git 2.1(2014年第三季度)将增加使这个function更强大:请参阅John Keeping( johnkeeping )的 commit 1e0dacd

正确处理我们有以下拓扑的情况:

  C --- D --- E <- dev / B <- master@{1} / o --- B' --- C* --- D* <- master 

哪里:

  • B'B'的固定版本,与B不相同;
  • C*D*分别与CD补丁相同,如果以错误的顺序应用,则会发生文本冲突;
  • E依赖于D文本。

git rebase master dev的正确结果是B被识别为devmaster的fork-point,所以CDE是需要在master上重放的提交; 但CDC*D*补丁相同,因此可以丢弃,以便最终的结果是:

 o --- B' --- C* --- D* --- E <- dev 

如果fork-point没有被识别出来,那么在包含B'的分支上selectB B'导致冲突,并且如果没有正确识别补丁相同的提交,那么将C到包含D的分支上(或者相当于D* )会导致冲突。