如何防止分叉的Git仓库发散

6
以下一系列Git命令导致了库的分叉。我做错了什么?
  1. 从GitLab中fork项目

    将父项目称为“upstream”

  2. 从fork的项目中克隆repo
  3. 在主分支(master)本地进行编辑
  4. 提交本地更改,推送到forked repo
  5. 上游repo有其他开发者的提交
  6. 从上游repo获取最新提交

    git pull --rebase upstream master

  7. 将现在在本地的最新提交从上游合并到forked repo中

    git push origin master

  8. Git说我的分支已经分叉了x个提交和y个提交。要求我执行git pull,这最终会使历史记录混乱。
正确的做法是什么?
1个回答

10

让我们来一起解决这个问题。

有三个存储库:您的本地克隆,upstream,以及您的分支(即origin到您的本地克隆)

完成第二步后,它们看起来像这样:

upstream

o---o---o
a   b   c

分叉

o---o---o
a   b   c

本地的

o---o---o
a   b   c

第5步后,仓库看起来像这样:

upstream

o---o---o---o---o
a   b   c   d   e

分叉

o---o---o---o---o---o
a   b   c   f   g   h

本地的

o---o---o---o---o---o
a   b   c   f   g   h

也就是说,上游(upstream)有新的提交记录de,而你自己也做了新的提交记录fgh

现在,你需要执行git pull --rebase upstream master

仓库现在看起来像这样:

upstream

o---o---o---o---o
a   b   c   d   e

分叉

o---o---o---o---o---o
a   b   c   f   g   h

本地的

o---o---o---o---o---o---o---o
a   b   c   d   e   f'  g'  h'

ff' 不是同一个提交时——f' 应该等同于 f,但它有不同的父节点。

你可以看到,现在 localfork 有不同的历史记录;向其推送并不只是简单地添加新的提交。这两个分支认为在 c 后面有不同的提交,并且两个分支不会汇合;如果您添加了所有的提交,您将得到以下图形:

        ,-----------o---o---o
        |           f   g   h
o---o---o---o---o---o---o---o
a   b   c   d   e   f'  g'  h'

当前 HEAD 是什么?是 h 还是 h'?两者都没有保留对方的历史记录。

你可以合并它们,但这是错误的,因为在 ff'gg' 等中,你有等效的更改。

你可以执行以下操作:

git push -f

这将从fork中抛弃fgh,并使其看起来像local(你仍然拥有f'g'h'),如果没有其他人从fork上克隆的话,这可能是可以接受的。

在步骤6中,您可以不进行rebase,而是执行以下操作

git pull upstream master

这将导致合并,因此 repos 将看起来像这样:

上游

o---o---o---o---o
a   b   c   d   e

分叉

o---o---o---o---o---o
a   b   c   f   g   h

本地

        ,---o---o---o---,
        |   f   g   h   |
o---o---o---o---o-------o
a   b   c   d   e       m

其中m是一个合并提交。这个提交可以很容易地推送到分支,因为它只是添加了额外的提交。

如果您计划向上游发出拉取请求,最好不要将他们的更改合并,让他们拉取和处理合并。


首先,你应该因为那个解释而获得奖励。那太棒了。我想要的是 git push -f,因为没有人会克隆分叉的存储库。最终,我希望所有三个存储库保持同步。如果我执行 git push -f,那么我是否可以从上游拉取/推送而不会有任何分歧问题? - BigBrownBear00
1
是的,如果你要推送的仓库是 快进 的话,你可以进行推送。也就是说,你可以轻松地添加新的提交并将 HEAD 推进到最新的提交。如果远程仓库的 HEAD 不是你正在推送的 HEAD 的祖先,则仓库已经分叉。当你对 git 的工作原理有一个准确的心理模型时,这一切都是有意义的,但是解释起来可能会很困难。 - SpoonMeiser
我会尝试并确保它能够正常工作。然后相应地接受答案。再次感谢! - BigBrownBear00
2
push -f 像魔法一样奏效。正是我所需要的。谢谢你。 - BigBrownBear00
这是我找到的最好的答案,用于解释上游、分叉和本地开发。 - Huan Jiang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接