如果有人推迟重置或重置到发布的分支后,如何恢复/重新同步?
我们都听说过,不应该把已发表的作品重新发布,这是危险的。但是,我还没有看到任何关于如何处理这种情况的食谱,以防出版物发行。
现在请注意,如果知识库仅由一个已知的(最好是小的)人群克隆,那么推动重新署名或重置的人可以通知其他人下一次他们需要关注取(!)。
我看到的一个明显的解决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
点用于指向提交B3
,B2
,B1
,现在它指向B
,并且当origin/master
点在B3
,topic
分支在其之上被启动。此模式使用
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
”(即B
,B1
,B2
,B3
)的输出来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*
分别与C
和D
补丁相同,如果以错误的顺序应用,则会发生文本冲突; -
E
依赖于D
文本。
git rebase master dev
的正确结果是B
被识别为dev
和master
的fork-point,所以C
, D
, E
是需要在master
上重放的提交; 但C
和D
与C*
和D*
补丁相同,因此可以丢弃,以便最终的结果是:
o --- B' --- C* --- D* --- E <- dev
如果fork-point没有被识别出来,那么在包含B'
的分支上selectB
B'
导致冲突,并且如果没有正确识别补丁相同的提交,那么将C
到包含D
的分支上(或者相当于D*
)会导致冲突。