在有人将重新定位或重置为已出版的分支机构后,如何恢复/重新同步?
-
28-09-2019 - |
题
我们都听说过,永远不应该重新出版的作品,这很危险等。但是,我还没有看到任何有关如何处理情况的食谱,以防万一rebase 是 出版。
现在,请注意,只有在存储库仅由已知(和最好是小)人群克隆的情况下,这才是可行的,因此,无论推动重生或重置的人都可以通知其他所有人,下次他们下次他们需要注意拿来(!)。
如果您没有本地提交,我看到的一个明显的解决方案将有效 foo
它被重新构成:
git fetch
git checkout foo
git reset --hard origin/foo
这只会抛弃当地的状态 foo
根据远程存储库有利于其历史记录。
但是,如果一个人对该分支机构进行了重大的本地变化,如何处理这种情况?
解决方案
在大多数情况下,在推动重新构想后重新恢复同步并不是那么复杂。
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。首先,您为远程分支最初所在的位置设置了书签,然后使用它来重播您的本地提交,从该点开始到重建的远程分支。
重新打造就像暴力:如果它不能解决您的问题,您只需要更多即可。 ☺
当然,如果您查找re固定之前,您可以在没有书签的情况下执行此操作 origin/foo
提交ID,并使用它。
这也是您如何处理忘记制作书签的情况 前 提取。什么都不会丢失 - 您只需要检查远程分支的换回路:
git reflog show origin/foo | awk '
PRINT_NEXT==1 { print $1; exit }
/fetch: forced-update/ { PRINT_NEXT=1 }'
这将打印提交ID origin/foo
在改变其历史的最新提取之前。
然后您可以简单地
git rebase --onto origin/foo $提交 foo
其他提示
我会说 从上游恢复 Git-Rebase Man页面的部分几乎涵盖了所有这些。
这与从自己的重生中恢复并没有什么不同 - 您将一个分支移动,并将其历史上的所有分支机构置于其新位置。
从GIT 1.9/2.0 Q1 2014开始,您不必在重新编写上游分支上重新编写之前的分支机构,如 亚里士多德Pagaltzis' 回答:
看 提交07D406B 和 提交D96855F :
在工作之后
topic
创建的分支git checkout -b topic origin/master
, ,远程跟踪分支的历史origin/master
可能已经重新构成并重建,导致了这种形状的历史:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
在哪里
origin/master
用来指向提交B3
,B2
,B1
现在它指的是B
, , 和你的topic
当分支开始在它的顶部origin/master
在B3
.此模式使用的回流
origin/master
找到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::
找到分支的点(或任何导致的历史记录
<commit>
)从另一个分支(或任何参考)分支<ref>
.
这不仅是寻找两个提交的共同祖先,而且还在 还考虑了<ref>
看看历史是否导致<commit>
从分支的早期化身分叉<ref>
.
这 ”
git pull --rebase
“命令使用使用的回流条目重新重新列出分支的叉子点”base
“分支(通常是一个遥控分支)该分支的工作是基于分支机构的,以应对“基础”分支已被重新构成并重建的情况。
例如,如果历史看起来像在哪里:
- 当前的尖端
base
“分支在B
, ,但早些时候发现它的尖端曾经是B3
进而B2
进而B1
在达到当前的提交之前,- 该分支在最新的“基础”之上重新基于提交
B3
,它试图找到
B3
通过通过输出git rev-list --reflog base
“ (IEB
,B1
,B2
,B3
)直到找到当前小费的祖先的提交”Derived (topic)
".在内部,我们有
get_merge_bases_many()
可以用一脚来计算这一点。
我们希望在Derived
以及通过合并所有历史技巧而产生的虚构合并。base (origin/master)
".
当存在这样的提交时,我们应该得到一个结果,这与一个返回条目之一完全匹配。base
".
GIT 2.1(Q3 2014)将添加此功能更强大:请参阅 提交1E0DACD 经过 约翰·韦尔(John Keep)(johnkeeping
)
正确处理我们具有以下拓扑的方案:
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
, , 以便 C
, D
, E
是需要重播的承诺 master
;但 C
和 D
与补丁相同 C*
和 D*
因此可以删除,因此最终结果是:
o --- B' --- C* --- D* --- E <- dev
如果未确定叉点,请选择 B
在包含的分支上 B'
结果发生冲突,如果未正确识别补丁相关的提交,则选择 C
在包含的分支上 D
(或等效 D*
)导致冲突。