【问题标题】:Git update my remote branch from another remote branchGit 从另一个远程分支更新我的远程分支
【发布时间】:2016-11-12 13:26:44
【问题描述】:

我们有一个名为“develop”的主分支,所以每当我们开发一个特性时,我们都会从“develop”创建一个本地特性分支,然后合并回develop。

现在的情况是,
1. 用户 1 必须从“开发”(比如 feature1)创建一个功能分支,并且他必须将它发布到 Git。这样就完成了。
所以现在,“develop”和“feature1”是 Git 中的 2 个不同的分支,“feature1”中的更改没有合并到“develop”,因为“feature1”仍在开发中。
2. 后来我开始实现的功能对'feature1'有一些依赖。所以我从 git 克隆了“feature1”分支并决定更新我对它的更改,认为“feature1”已经从“开发”分支更新。
3. 但后来我发现'feature1' 分支并没有更新'develop' 分支的一些最新更改。
4. 现在我需要在'feature1' 分支中更新'develop' 分支中的更改,然后再更新我对它的更改。

任何可能的方式来使用 GIT 命令来做到这一点?

【问题讨论】:

  • 附带说明:none 这些都是“远程”分支。 (事实上​​,“远程分支”并不是一个真正的 Git 术语。有一种叫做 remote-tracking branch 的东西,你看到的名称就像 origin/developorigin/master。这些只是记住 your Git 从某个 other Git 那里得到了什么,最后一次你的 Git 与另一个 Git 交谈。这意味着你永远不会改变它们。你让你的 Git 更新它们当你的 Git 再次与另一个 Git 对话时。但只有那个 Git 应该以任何方式更改它们。)

标签: git github git-branch git-merge master


【解决方案1】:

根据我收集到的信息,这是您存储库中的情况:

                  develop
                    ↓
A -- A -- B -- C -- C
           \
            F -- F -- F
                      ↑
                   feature1

因此,提交A 是之前存在的develop 上的提交。 B 是创建功能分支时 develop 的基本提交。 F 是在功能分支上进行的提交,C 是在功能分支已经创建并正在处理之后在 develop 上进行的提交。

现在,您要做的是继续在功能分支上工作,同时取决于提交 C 引入的更改。对吗?

在这种情况下,假设您与用户 1 不是同一个开发人员,将这些更改引入功能分支的最安全方法是简单地将它们合并。因此,在签出 feature1 时,只需使用 `git merge develop* 合并 develop。然后,历史将如下所示:

                      develop
                         ↓
A -- A -- B ---- C ----- C
           \              \
            F -- F -- F -- M
                           ↑
                        feature1

因此,您只需合并更改,然后就可以继续处理它。事实上,随着 feature1develop 的增长,您可以继续多次这样做:

                                     develop
                                        ↓
A -- A -- B ---- C ----- C -- C -- C -- C
           \              \         \    \
            F -- F -- F -- M -- F -- M -- M -- F
                                               ↑
                                            feature1

一旦你完成了特性分支,你可以将它合并到 develop

                                              develop
                                                 ↓
A -- A -- B ---- C ----- C -- C -- C -- C ------ M
           \              \         \    \      /
            F -- F -- F -- M -- F -- M -- M -- F

当然,这让历史看起来有些混乱,但它正确地代表了特性分支如何随着时间的推移而演变,而相关的变化仍在 develop 上发生。


如果您想避免看起来像这样的历史记录,有几种选择。如果您只依赖很少的更改,例如有些是在单个提交中引入的,而其他提交与您无关,您也可以将那个提交挑选到功能分支上。 Cherry-picking 允许您复制一个提交,基本上完全重用它,同时仍将其作为单独的提交。

假设,您只需要上面显示的第一个图表中的第一个提交 C。然后你可以通过git cherry-pick C1 将其复制到功能分支:

                  develop
                     ↓
A -- A -- B -- C1 -- C2
           \
            F -- F -- F -- C1'
                            ↑
                        feature1

这将创建一个副本C1',其中包含与其原始C1 相同的更改(但仍然是不同的提交对象)。然后,您可以继续处理包含这些更改的功能分支。


最后,剩下的选择是变基。重新设置重写历史记录,因此再次从第一张图开始,您可以通过运行git rebase develop 得到以下结果:

                 develop
                    ↓
A -- A -- B -- C -- C
                     \
                      F' -- F' -- F'
                                  ↑
                               feature1

要记住的重要一点是历史真的被重写了,所以feature1上的所有提交都被修改并重新创建。这导致它们是具有不同提交标识符的完全不同的对象,从而使它们与分支的先前状态不兼容。

这会导致其他开发人员,在您的情况下,尤其是在 feature1 分支上工作的“用户 1”,在尝试合并您的更改时遇到冲突。修复它需要他们手动修复它,除非你告诉他们,否则他们可能甚至都不会注意到(导致历史非常混乱并且有些破损)。

因此,除非您知道自己在做什么,否则您应该永远不要对之前发布的提交进行变基。即使这意味着您的历史记录会因此变得不那么美好。

【讨论】:

    【解决方案2】:
    1. 在本地仓库中将feature1 重新设置为develop。它将回退feature1 中的任何更改,将develop 合并到feature1,然后重做您的更改。

    git checkout feature1

    git rebase develop

    1. 将本地存储库强制推送到主存储库。

    git push -f

    1. 将您的分支(例如,feature2)重新设置为 feature1

    git checkout feature2

    git rebase feature1


    参考:https://git-scm.com/book/en/v2/Git-Branching-Rebasing

    希望这会有所帮助!

    编辑:阅读poke's answer,因为这会使其他开发人员的本地存储库有些损坏。

    【讨论】:

    • 你不应该在这种情况下变基,因为有多个开发人员在功能分支上工作,并且该分支已经发布。变基将完全破坏他们的本地分支,需要他们手动修复它。
    猜你喜欢
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2014-04-27
    • 2012-10-22
    • 2014-03-17
    • 2014-06-13
    • 2020-06-09
    相关资源
    最近更新 更多