注意:为了本回答的目的,假设您有一个名为
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)
在这种情况下,提交(commit)
Z
将包含提交(commit)
X
和
Y
的所有更改,如果合并提交中有任何更改,则还包括
M
。
如果您选择将
feature
变基到
master
而不是合并(在您的情况下使用pull),则图形如下:
A---B---C---D---E (master)---X'---Y' (feature)
X'
和Y'
分别代表X
和Y
的重写提交。如果您将这两个提交压缩成一个提交,那么您就会得到与压缩合并相同的结果。(然后您可以将feature
合并到master
上使master
保持最新)
现在的 origin 包含 A、B、C 两份了吗?
假设您将master
推送到origin
,在这两种情况下,origin(master)都不会包含A、B、C两份。
话虽如此,也许您的概念是相反的,因为看起来您的图形实际上试图将master
压缩到feature
上。如果您这样做了,由于master
已经合并到feature
中,随后的压缩合并将不起作用,这意味着Z
甚至都不会被创建。但是,如果您不先将master
合并到feature
中,然后将master
压缩合并到feature
中,也许您会更接近您所考虑的结果,因为该图形将如下所示:
A---B---C---D---E (master)
\
X---Y---Z (feature)
现在,Z
将会包含你提议的来自 C
、D
和 E
的更改。然后将其合并回 master
看起来会是这样:
A---B---C---D---E---M (master)
\ /
X---Y--------Z (feature)
在这种情况下,
Z
是一个无意义的提交,你不需要它,实际上3次提交的
更改会被重复显示。(就像在将提交复制到其他分支后再进行合并时一样。)
针对你的最后一个问题:
我们应该使用rebase吗?
如果你正在比较合并(merge)和变基(rebase)以及压缩(squash),那么这部分取决于你希望图形看起来如何,但更重要的是你希望长期保留哪些信息:
- 压缩保留最少的信息。它仅包含更改内容。它不保留任何有关作者、日期、开发人员所需的提交顺序和内容或开发开始时的原始分支点的信息。
- 变基保留有关作者、日期和开发人员所需的提交顺序和内容的信息,但不保留开发开始时的原始分支点的信息。
- 合并保留有关作者、日期和开发开始时的原始分支点的信息,但通常不具有开发人员所需的期望的提交顺序和内容,而是保留提交按实际发生顺序的实际顺序和内容。
选择哪个取决于个人喜好。对于
特性分支,我个人更喜欢变基选项,但前提是开发人员实际上创建了可以单独提供价值的有意义提交,并且如果多个开发人员共享一个特性分支,则需要适应通信强制推送和正确重置他们的分支。如果特性分支的开发不符合这些标准,我会选择压缩。对于像Git Flow这样的
长寿命共享分支,我更喜欢合并(还有--no-ff)。我永远不会对长期共享的分支进行变基。
git merge --squash
谢谢,我会尝试使用git fetch来看看它的效果。 我想问题是,我们应该使用rebase吗? - Travis Petersongit merge --squash
)到主分支中,然后将主分支合并到未来的特性分支中所产生的下游影响。不断将特性分支压缩到主分支中并将其合并到新的特性分支中是否会带来任何长期问题。 - Donovan R