在有人将重新定位或重置为已出版的分支机构后,如何恢复/重新同步?

StackOverflow https://stackoverflow.com/questions/4084868

我们都听说过,永远不应该重新出版的作品,这很危险等。但是,我还没有看到任何有关如何处理情况的食谱,以防万一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/masterB3.

此模式使用的回流 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“ (IE B, 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* 是相同的 CD 如果以错误的顺序应用,则分别在文字上进行冲突;
  • E 在文本上取决于 D.

正确的结果 git rebase master dev 就是它 B 被确定为 devmaster, , 以便 C, D, E 是需要重播的承诺 master;但 CD 与补丁相同 C*D* 因此可以删除,因此最终结果是:

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

如果未确定叉点,请选择 B 在包含的分支上 B' 结果发生冲突,如果未正确识别补丁相关的提交,则选择 C 在包含的分支上 D (或等效 D*)导致冲突。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top