Git - 使用 cherrypicking 时分支之间的差异

Git - diff between branches when using cherrypicking

我们目前正在使用 Azure DevOps。根据版本的不同,我们有一个包含多个分支的存储库,即分支 版本 1版本 2版本 3.

版本 1 修复了错误后,我们希望在 版本 2版本 3。但是 版本 1 不是 版本 2 的子集,所以我们不能使用合并命令。 版本 2版本 3 相同。因此,我们使用 cherry-picking 进行修复。

存在未在所有版本中实施修复的风险。我想看到在 版本 1 中完成的提交,而不是在 版本 3 中完成的提交。不包括已精心挑选到 版本 3 的提交。有没有一种方法可以在处理精选提交的分支之间进行区分?

Cherry-picking 是,我和其他人会争辩说,解决手头问题的错误工具:请参阅 Raymond Chen 的博客系列文章,标题为 Stop cherry-picking, start merging. As Lasse V. Karelsen comments,cherry-picked commits are not绑在一起。合并提交 绑定在一起,因此合并提供了更多指示,表明如果修复不完整,可能需要额外的合并。

在您通读链接的博文或我下面非常有限的摘要并更改您的总体总体 work-flow 后,您将创建一个分支来修复一些特定的错误并进行修复工作那里。然后,您会将此分支合并到 错误的每个 release-candidate 分支。如果修复证明不充分,您将向修复分支添加更多提交,并且需要 re-merge 将其添加到每个候选发布版中。根据您的 bug-tracking 系统,您可能希望 Git 找到修复分支的前一个提示提交被合并到的分支。为此,您可以使用 git branch --merged(或者,如果您想构建自己的工具,git for-each-ref,它是 git branchgit tag).因此,使用合并方法可为您提供更好的工具。

如何通过合并修复bug

请注意,这是我对博文的总结;那里还有很多东西要学。我包含这个只是为了涵盖 Whosebug 帖子的基本规则,这些规则需要 self-contained(至少对于 SO 系统本身),因为博客链接会随着时间的推移而变化并且需要维护。

随着时间的推移,软件中发生的事情是,我们编写的代码中存在不会立即显示出来的错误。当我们使用一个好的版本控制系统时,这使我们能够 追踪 错误到它们的起源点。如果我们将其绘制为简化的 Git 提交历史图,它最终看起来像这样:

                     o--...--A   <-- release-1
                    /
                   /  o--...--B   <-- release-2
                  /  /
...--o--o--X--o--:--:--...--C   <-- release-3
                  \  \
                   \  o--...--D   <-- release-4
                    \
                     o--...--E   <-- release-5

在这里,提交 X 是其中包含实际 bug 的那个。从图中我们可以看出,这个错误现在感染了五个版本。

我们无法修复过去的错误,所以我们经常天真地做的是修复其中一个版本中的错误:

                     o--...--A--F1   <-- release-1
                    /
                   /  o--...--B   <-- release-2
                  /  /
...--o--o--X--o--:--:--...--C   <-- release-3
                  \  \
                   \  o--...--D   <-- release-4
                    \
                     o--...--E   <-- release-5

其中 F1 是修复错误的提交。但是现在我们必须将F1复制到每个版本:

                     o--...--A--F1   <-- release-1
                    /
                   /  o--...--B--F2   <-- release-2
                  /  /
...--o--o--X--o--:--:--...--C--F3   <-- release-3
                  \  \
                   \  o--...--D--F4   <-- release-4
                    \
                     o--...--E--F5   <-- release-5

如果 修复简单明了,则没有根本性错误,无需重新访问。我们将以五次提交结束,这是实际解决问题所需的最低限度。

但是,如果修复微妙而复杂,或者引入了必须稍后解决的性能问题,或者可能需要额外的工作,该怎么办?稍后,当我们提出另一个提交或一系列提交来修复问题时,我们将不得不返回并单独修改每个分支。如果我们可以及时回到我们的旧代码并在提交 X 时解决问题 它发生的地方 会怎样?嗯,有了版本控制系统,我们可以.1

我们直接检查历史提交 X,然后为其附加一个新的分支名称 — 有点难以按照我绘制图表的方式绘制。这是一个尝试:

                     o--...--A   <-- release-1
                    /
                   /  o--...--B   <-- release-2
                  /  /
...--o--o--X--o--:--:--...--C   <-- release-3
            .     \  \
             .     \  o--...--D   <-- release-4
              .     \
               .     o--...--E   <-- release-5
                .
                 . <-- fix-bug-where-it-cropped-up

现在,此时,我们进行修复提交:

                     o--...--A   <-- release-1
                    /
                   /  o--...--B   <-- release-2
                  /  /
...--o--o--X--o--:--:--...--C   <-- release-3
            .     \  \
             .     \  o--...--D   <-- release-4
              .     \
               .     o--...--E   <-- release-5
                .
                 .--F1--F2--F3--F4 <-- fix-bug-where-it-cropped-up

这个分支的尖端——此时提交 F4——现在可以合并回每个现有的发布或开发分支。每次合并都会生成一个新的合并提交,因此我们最终得到的总提交数比 super-simple 情况下 cherry-picking 的情况要多。但这些提交实际上 记录 合并。这是进入 release-5 的那个:

                     o--...--A   <-- release-1
                    /
                   /  o--...--B   <-- release-2
                  /  /
...--o--o--X--o--:--:--...--C   <-- release-3
            .     \  \
             .     \  o--...--D   <-- release-4
              .     \
               .     o--...--E-----M5   <-- release-5
                .                 /
                 .--F1--F2--F3--F4 <-- fix-bug-where-it-cropped-up

(我不会尝试绘制其他合并,因为图形很快变得非常混乱。)如果我们稍后发现 F1-F2-F3-F4 提交链不充分或不正确,我们可以添加更多提交 F5 等来修复它们,然后 re-do 每次合并。

这无论如何都不是灵丹妙药,但比 cherry-pick 方法更好,因为它将修复固定在错误上并在Git 提交图。 Git 提交图 项目的历史,因此这些痕迹表明这是一个重要的修复,被带回到多个版本中。请注意,图表本身相当粗糙和机械,因此包含 良好的提交消息 很重要。默认情况下 git merge 生成的那些并不好,但确实具有可预测形成的优势,因此 mechanically-search-able.


1还有其他条件也适用:拥有 VCS 是必要的,但还不够。