Git 从另一个远程分支更新我的远程分支

标签 git github git-merge git-branch

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

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

有什么方法可以用 GIT 命令来做到这一点?

最佳答案

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

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

因此,提交 A 是之前存在的 develop 上的提交。 B 是创建功能分支时 develop 所在的基础提交。 F 是在功能分支上进行的提交,C 是在功能分支已经创建并正在开发之后在 develop 上进行的提交继续努力。

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

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

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

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

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

一旦你完成了特性分支,你就可以将它 merge 到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 相同的更改(但仍然是不同的提交对象)。然后,您可以继续处理包含这些更改的功能分支。


最后,剩下的替代方案是 rebase 。 rebase 重写 历史,因此再次从第一张图开始,您可以通过运行 git rebase develop 得到以下结果:

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

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

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

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

关于Git 从另一个远程分支更新我的远程分支,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40563327/

相关文章:

git - Git 中如何管理依赖于另一个项目的项目?

git log --remotes --decorate 显示已删除的分支?

git - 我如何告诉 github 我从我的笔记本电脑推送了所有提交?

git - 使用 git branch 的 heroku 令人困惑!

windows - 如何在具有跨平台兼容性的 Git 提交中强制执行一致的行结尾

git - git subtree merge 和 git-subtree 有什么区别

Git:将部分分支复制到另一个分支

git - 使用 cmd "ant run"在 contiki 中运行 cooja

github - 获取 GitHub 工作流程中的当前日期和时间

Git 将开发分支与生产版本的主分支 merge