【问题标题】:How to prevent forked git repo from diverging如何防止分叉的 git repo 发散
【发布时间】:2017-09-21 10:16:39
【问题描述】:

以下一系列 git 命令导致 repos 出现分歧。我做错了什么?

  1. 来自 GitLab 的 Fork 项目

    调用父项目“上游”

  2. 从分叉项目中克隆 repo
  3. 在分支 master 中进行本地编辑
  4. 提交本地编辑,推送到分叉仓库
  5. 上游 repo 有来自其他开发者的提交
  6. 从上游仓库获取最新提交

    git pull --rebase 上游主控

  7. 将来自上游的最新提交合并到本地 分叉回购

    git push origin master

  8. git 说我的分支分别被 x 次提交和 y 次提交分歧。要求我做一个git pull,这最终会弄乱历史。

这样做的正确方法是什么?

【问题讨论】:

    标签: git gitlab git-fork


    【解决方案1】:

    让我们解决这个问题。

    有 3 个存储库:您的本地克隆、上游、您的 fork(源自本地克隆)

    在第 2 步之后,它们看起来像这样:

    上游

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

    分叉

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

    本地

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

    在第 5 步之后,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---o---o---o
    a   b   c   f   g   h
    

    也就是说,上游有新的提交 de,而你已经提交了新的提交 fgh

    现在,你可以git pull --rebase upstream master

    存储库现在如下所示:

    上游

    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,但它有不同的父级。

    您可以在这里看到,local 现在与 fork 有不同的历史;推动它不仅仅是添加新提交的情况。两者都认为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'、@ 987654353@ 和 h' 仍然),如果没有其他人从 fork

    克隆,这可能没问题

    在第 6 步,你可以做而不是做变基

    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 是一个合并提交。这可以通过简单地推送到 fork 因为它只是添加额外的提交。

    但是,如果您打算向上游发出拉取请求,最好不要合并他们的更改,让他们拉取并处理合并。

    【讨论】:

    • 首先,你应该因为这个解释而获得奖励。那太棒了。 git push -f 是我想要的 b/c 没有其他人会克隆分叉的 repo。最终我希望所有 3 个存储库保持同步。如果我执行 git push -f,我可以从上游拉/推而不会出现任何分歧问题吗?
    • 是的。如果它是您要推送的仓库的 快进,则可以推送。也就是说,您可以轻松地添加新的提交并将 HEAD 推进到最新的提交。如果远程 repo 的 HEAD 不是您正在推送的 HEAD 的祖先,则 repos 已经分歧。当你对 git 工作原理的心智模型是准确的但很难解释时,这一切都是有道理的。
    • 我会试一试并确保它有效。然后相应地接受答案。再次感谢您!
    • push -f 就像一个魅力。正是我需要的。谢谢。
    猜你喜欢
    • 2014-11-02
    • 2011-05-05
    • 1970-01-01
    • 2014-11-19
    • 1970-01-01
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多