【问题标题】:What happens if I use git pull (merge) and squash my commit into master?如果我使用 git pull (merge) 并将我的提交压缩到 master 会发生什么?
【发布时间】:2021-12-27 13:56:53
【问题描述】:

我不确定这种策略是否给我们带来了比其价值更多的问题。让我们以此为例(来自 git docs)。


    A---B---C---D---E origin/master
        \     
         X---Y--- feature/branch

我在提交 B 中创建了一个源/主的功能/分支。我在本地提交了 X 和 Y。 C、D 和 E 已由其他开发者承诺起源。然后我使用 git pull origin master 将最新的更改从 master 下拉到我的功能/分支中。

    A---B---C---D---E origin/master
        \            \
         X---Y--------M feature/branch

这似乎采用 CDE 并在我的功能分支 M 中创建合并提交。然后我压缩我的功能分支创建提交 Z 并将其推送到原点。

    A---B---C---D---E       origin/master
        \            \     /
         X---Y--------M---Z feature/branch

我可能误解了pull merge

origin 现在是否包含 A、B、C 两次?

我们应该改用 rebase 吗?

非常感谢任何建议。

【问题讨论】:

  • 你没有“功能分支”。您正在直接在 master 上工作。
  • “壁球”对您意味着什么?显示您获得I 的命令以及您“将其推入原点”的命令。事实上,如果你显示所有的命令会有所帮助。
  • "origin 现在是否包含 A,B,C 两次?"你怎么能怀疑。只需git fetch 自己看看。
  • 最后:问题是什么?您的个人误解似乎很深,您的工作习惯有点好奇,但除此之外,这里并没有发生什么特别有趣或令人惊讶的事情。
  • Matt,你说得对,我在这个例子中拉下了 master 并直接提交到它,但是我提到它就像一个特性分支。很抱歉造成混乱。 Squash 命令 - git merge --squash 谢谢,我会尝试 git fetch 看看它是什么样子的。我想问题是,我们应该改用 rebase 吗?

标签: git merge squash


【解决方案1】:

注意:就本答案而言,假设您有一个名为 master 的本地分支,它等效于 origin/master,还有另一个名为 feature 的本地分支,它等效于feature/branch.

我相信您的问题源于您的第三张图表不正确。鉴于您的第二张图表原样:

    A---B---C---D---E (master)
        \            \
         X---Y--------M (feature)

如果您希望将 feature 压缩到 master 上,则结果图将是:

A---B---C---D---E---Z (master)

在这种情况下,提交 Z 将包含来自提交 XY 的所有更改,如果合并提交中有任何更改,还包括 M

如果您选择将feature 重新设置为master 而不是合并(在您的情况下使用拉取),则图表将如下所示:

A---B---C---D---E (master)---X'---Y' (feature)

其中X'Y' 代表XY 的重写提交。如果您随后将这两个提交压缩为一个,那么您将与壁球合并处于同一位置。 (然后您将feature 合并到master 以使master 保持最新。)

origin 现在是否包含 A、B、C 两次?

假设您将master 推送到origin,在这两种情况下,origin(master)现在都不会包含 A、B、C 两次。

话虽如此,也许您在概念上是倒退的,因为看起来您的图表实际上试图将master 压缩到feature。如果你这样做了,因为 master 已经合并到 feature 中,后续的 squash 合并将没有任何效果,这意味着 Z 甚至不会被创建。但是,如果您先将master 合并到feature,然后将master 合并到feature,也许您会更接近您的想法,因为图表会看起来像这样:


    A---B---C---D---E (master)
        \     
         X---Y---Z (feature)

现在Z 将包含您建议的CDE 的更改。然后将其合并回master 看起来像这样:

    A---B---C---D---E---M (master)
        \              /
         X---Y--------Z (feature)

在这种情况下,Z 是您不需要的毫无意义的提交,基本上 3 次提交的 更改 存在两次。 (类似于你挑选提交到其他分支,然后将它们合并回来。)

最后一个问题:

我们应该改用 rebase 吗?

如果您在比较合并、变基和壁球,这部分归结为您希望图表的外观,但也许更重要的是您希望长期保留哪些信息:

  1. Squash 的信息保留量最少。它将仅包含更改。它不保留有关作者、日期、开发人员期望的提交顺序和提交内容或开发开始时的原始分支点的任何信息。
  2. Rebase 保留有关作者、日期和开发人员期望的提交顺序和内容的信息,但不保留开发开始时的原始分支点。
  3. Merge 保留了关于作者、日期和开发开始时的原始分支点的信息,但一般没有开发者的期望顺序和提交内容,而是保留了实际提交的顺序和内容。

你选择哪一个是一个品味问题。对于功能分支,我个人更喜欢 rebase 选项,但前提是开发人员确实创建了有意义的提交来为他们自己提供价值,并且共享一个功能分支的多个开发人员能够轻松地交流强制推送和重置他们的正确地分支。如果功能分支开发不符合该标准,我更喜欢壁球。对于长期存在的共享分支,例如 Git Flow,我更喜欢合并(以及 --no-ff 也是)。我永远不会 rebase 一个长期存在的共享分支。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2012-02-03
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多