VSTS 和 Git:为什么在合并到 master 时压缩我的 DEV 分支说 DEV 既落后又领先 master?

VSTS and Git: Why does squashing my DEV branch while merging to master says that DEV is both behind and ahead of master?

我希望有人能帮助我解决这个问题,因为我正在挠头了解发生了什么,以及是否可以纠正。

我目前正在 VSTS 中开发一个项目并使用 GIT 作为代码存储库。我有通常的 MASTER 分支,还有一个 DEVELOPMENT 分支。然后我在 DEVELOPMENT 分支中创建功能分支。

当我们完成了feature分支的修改后,我创建了一个Pull Request,可以成功的将修改合并到DEV分支中。然后,DEV 分支在 MASTER 之前显示“0”,在 MASTER 之前显示 'x' ...这是正确的。

当我们准备将更改合并到 MASTER 时,问题就来了。我们创建一个 PULL REQUEST 来执行此操作,并且更改成功地合并到 MASTER 中……但是……DEV 分支现在说它比 MASTER 落后 1,但仍然比 MASTER 领先 x!为什么 DEV 1 在 MASTER 后面?为什么 DEV 仍然领先于 MASTER? PULL REQUEST之后,MASTER和DEV不应该是同步的吗?即DEV应该在后面0,MASTER前面0?

很有可能我没有正确理解 GIT,但我是否可以在 VSTS 中设置一些错误的设置...例如错误设置的分支策略?我在 MASTER 上设置的唯一分支策略(在这个阶段)是 "Enforce a merge strategy - Squash merge".

提前致谢。

壁球合并是您误解的原因。

压缩合并时,开发分支的所有提交都被压缩为一个提交。这就是 DEV 落后 master 1 的原因,因为它没有压缩的提交。 DEV 也比 master 早 x,因为 DEV 有 x 个不在 master 中的提交。

理想情况下,您应该只压缩合并您的 feature/topic 分支,这将为您提供每个功能一个提交。当你合并到 master 时,你不应该压缩你的开发分支。因此,如果需要,您可以更改 master 上的分支策略并将该策略放在 DEV 中。我的建议是让您的开发人员决定何时压缩或不压缩。当您在 VSTS 中完成 PR 时,它会为您提供压缩选项。

只是为了增加@harshil-lodhi 的(绝对正确)答案的知名度。

在创建拉取请求之前,存储库的状态如下所示:

如果您查看 SourceTree 工具中的这个存储库,它证明数字是正确的(1 后,3 前):

当您合并强制压缩提交的拉取请求时,状态更改为以下 (VSTS):

和 SourceTree:

dev 分支仍然有 3 个独立的提交,这就是它比 master 提前 3 个提交的原因。另一方面,master 还有一个提交,压缩了 merging/squashing 期间从 dev 分支到达的更改。如你看到的。压缩的提交不是合并提交——它没有 2 个父项。虽然dev和master分支的内容是一样的,但是对于Git.

来说还是不同的分支

这是VSTS处理fast-forward合并的方式造成的。我们可以用图表来说明细节。

完成 PR 将 feature 分支合并到 dev 后,dev 分支落后 0,领先 x(假设这里提前 3 次提交)mater分支,masterdev 的提交历史如下:

...---A----B       master
            \
             C---D---E   dev

然后在创建 PR 将 dev 合并到 master 并完成合并后,提交历史如下所示:

...---A----B-----------F   master
            \         /
             C---D---E  dev

那是因为 VSTS 句柄 fast-forward 与 --no-ff 选项合并 (git merge --no-ff)。

对于默认方式(git merge dev)来处理fast-forward合并,它将使master分支指向与dev分支相同的提交(两者他们将指向提交 E 如上例)。

但对于 --no-ff 合并 (git merge --no-ff dev),git 将创建一个新的合并提交,即使它是 fast-forward 合并。

所以 dev 分支显示后面有 1 次提交(提交 F)和 3 次提交(提交 CDE)通过与 master 分支进行比较领先。