Git(流程):使用 Rebase 还是双重 QA?
我们商店的部署周期相当快(从编写代码到发布代码需要 1-2 周)。因此,经过一些实验,我们采用了以下 Git 使用模式:
- 开发人员基于 master 为其特定票证创建一个分支(即“bug-5555”分支)
- 开发人员提交修复代码到该分支
- 主管将我们的“pre-master”分支(其上包含当前候选版本的 master 副本)重新设置为 bug 分支
- 主管将来自 bug 分支的提交合并(快进式)到 pre-master 分支
- QA 团队在 pre-master 分支中进行修复
- 如果修复在 QA 中失败,则会从 pre-master 分支重新调整基础
- (完成 QA 失败的修复后,将执行步骤 3-5)重复)
- 当我们准备好发布时,预主分支将成为新的主分支
这种风格对我们来说有很多优点:它使得 QA 团队可以准确测试正在发生的事情为了上线,它使我们可以轻松地在 QA 中添加和取出内容,它使特定修复的代码在自己的分支中保持整洁,等等。
但是,这里有几个人担心我们的使用rebase(在将该修复分支合并到 pre-master 之前将当前的 pre-master 重新设置为修复分支,并重新设置 pre-master 分支以取出失败的修复)。他们担心变基可能会导致历史记录丢失,因此我们应该尽可能少地变基。
然而,在不进行变基的情况下,我们提出的唯一替代方案是使 pre-master 分支成为一个死胡同,仅用于 QA。这将使该分支的变基更加安全,当我们准备好发布时,我们会将修复分支直接重新合并到主分支中。但这种方法的问题在于,QA 实际上不会测试正在运行的内容,并且不正确的合并冲突解决方案(将修复程序合并到 master 中时)很容易被他们忽略(除非他们重新重新对所有内容进行 QA) 。尽管存在变基问题,这也是我们坚持采用当前方法的主要原因。
所以,随着那段很长的前奏结束,我真正的问题是……嗯,它分为两部分:
- 你认为哪一个更糟糕:不准确地对正在运行的内容进行质量检查的风险,或者失败的风险我们所做的(有限的)变基量中的历史(或实际代码)?
- 有没有人看到我所概述的第三种选择,这将为我们提供相同的灵活性并测试实际将要上线的内容,而无需承担变基的危险?
Our shop has a fairly rapid deploy cycle (1-2 weeks between when the code is written and when it's released). As such, after a bit of experimentation we've adopted the following pattern for our Git usage:
- Developer creates a branch, based off master, for their specific ticket (ie. "bug-5555" branch)
- Developer commits the code for the fix to that branch
- A supervisor rebases our "pre-master" branch (a copy of master with the current release candidates on top of it) in to the bug branch
- A supervisor merges (fast-forward-style) the commits from the bug branch in to the pre-master branch
- The QA team qa's the fixes in the pre-master branch
- If a fix fails QA, it is rebased out of the pre-master branch
- (After a fix for the QA failure is completed, steps 3-5 are repeated)
- When we're ready to release, the pre-master branch becomes the new master branch
This style has a number of advantages for us: it makes it so the QA team is testing exactly what is going to go live, it makes it easy for us to put stuff in and take stuff out of QA, it keeps the code for a specific fix all nice and tidy in its own branch, etc.
However, several people here are concerned about our use of rebase (both to rebase the current pre-master in to the fix branch before merging that fix branch in to pre-master, and to rebase the pre-master branch to take out failed fixes). Their concern is that rebasing could potentially result in lost history, and as such we should rebase as infrequently as possible.
However, without rebasing the only alternative we've come up with is to make the pre-master branch a dead-end branch, used only for QA. This would make rebasing that branch safer, and when we're ready to release we'd re-merge the fix branches directly in to master. The problem with this approach though is that QA wouldn't actually be testing what's going live, and an improper merge conflict resolution (when merging the fixes in to master) could easily slip by them (unless they re-qa everything all over again). This is the main reason why we've stuck with our current approach, despite the rebasing concerns.
So, with that very long prelude out of the way, my actual question is ... well it's two-part:
- Which do you think is worse: the risk of not QA-ing exactly what is going live, or the risk of losing history (or actual code) from the (limited) amount of rebasing we do?
- Does anyone see a third option to what I've outlined, which would give us the same flexibility and testing of what's actually going to go live, without the dangers of rebasing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
总的来说,我同意,如果没有一个好的机制来跟踪正在运行的事物(可能在您的 SCM 系统本身之外,例如,在您的错误跟踪器中),则将事物重新设置为规则可能是危险的。
关于如何使用 Git 分支管理发布流程,有(至少)2 个以上非常好的资源。
Git 本身使用一个“建议更新”分支(称为 pu)来镜像您的 pre-master 分支。该分支由各个修复分支合并组成。该分支适用于需要测试和集成的非常不稳定的功能。它可以相对自由地重新定位和重置。 (同样,每个单独的主题/功能分支都是在 Git 外部跟踪的)。功能通常只会合并到
pu
中一次,并且pu
会定期针对更稳定的内容进行重置。更稳定的更改将合并到
next
中以进行更广泛的测试。同样,这是通过合并而不是变基来处理的。您的pre-master
分支的用途与next
和pu
类似。一项功能可能会多次合并到next
中,以纳入额外的反馈。不过,开发仍然发生在主题分支上。当主题分支被认为足够稳定时,它会被合并到
master
。为了帮助跟踪正在发生的事情,Git 有一个“What's Cooking”的概念。 Git 维护者 Junio Hamano 有一个一个名为
cook
的脚本来帮助让每个人都清楚了解各个主题分支的状态。当然,Git 没有明确的 QA 流程;就您而言,有了真正的质量检查团队,您可以做一些事情的组合。
--no-ff
来显式跟踪分支来源。pre-master
分支,或通过恢复合并提交,或通过合并出现在旧修复分支顶部的新修复。master
时,创建一个新的集成分支,该分支直接将每个修复分支中的所有成功修复合并一次。您可以验证该树实际上是 QA 测试的代码(例如,git diff Integration pre-master
为空)。然后将集成分支合并到 master 中(再次使用--no-ff
来跟踪谁做的以及何时做的)。git checkout pre-master; git merge -s 递归 -X 他们的主人
)。pre-master
的特定版本以进行 QA。这里的区别主要是使用合并来帮助您跟踪合并的内容以及合并时间和合并者。合并的另一个好处是开发人员(和 QA)将看到更少的强制更新,而更多的是定期更新。
再次强调,真正需要强调的是,必须有一些东西用于跟踪已合并(或重新基址)到稳定分支并成功测试的内容。
In general, I would agree that without a good mechanism for keeping track of things that are in flight (which could be outside your SCM system itself, e.g., in your bug tracker), rebasing things as a rule could be dangerous.
There are (at least) 2+ very good resources on how to manage a release process using Git branches.
Git itself uses a "proposed updates" branch (called
pu
) that mirrors yourpre-master
branch. This branch consists of merges from various fix branches. This branch is intended for really unstable features that need to be tested and integrated. It can relatively freely be rebased and reset. (Again, each individual topic/feature branch is tracked outside of Git). Features are generally only merged once intopu
andpu
gets reset against something more stable very regularly.More stable changes get merged into
next
for wider testing. Again, this is handled with merging, not rebasing. Yourpre-master
branch serves similar purpose to bothnext
andpu
. A feature might get merged multiple times intonext
, to incorporate additional feedback. Development still happens on the topic branch though.When the topic branch is deemed stable enough, it is merged to
master
.To help track what is going on, Git has a concept of "What's Cooking". Junio Hamano, the Git maintainer, has a script called
cook
that helps keep things straight for everyone and what state various topic branches are in.Of course, there is no explicit QA process for Git; in your case, with a real QA team, you can do some combination of things.
--no-ff
to explicitly track the branch provenance.pre-master
branch by resetting and re-merging, or by reverting the merge commit, or by merging in a new fix that appeared on top of the old fix branch.master
, create a new integration branch that directly merges in all of the successful fixes just once from each fix branch. You can verify that this tree is literally the code that QA tested (e.g.,git diff integration pre-master
is empty). Then merge the integration branch into master (again, using--no-ff
to track who did it and when).pre-master
from scratch by doing agit checkout pre-master; git reset --hard master
, or you can do a presumably trivial merge back from master (resolving all conflicts in favor of master, e.g.git checkout pre-master; git merge -s recursive -X theirs master
).pre-master
.The differences here are mostly just to use the merges to help you keep track of what has been merged and when and by whom. The other nice thing about merges is that developers (and QA) will see fewer forced updates, and more just regular updates.
Again, the real thing to emphasize is that there must be something that is used to track what has been merged (or rebased) into a stable branch and tested successfully.
总而言之,第二种策略是将主题分支合并到主分支中,并将预主分支作为 QA 的暂存区域。为了确保您准确地发布了 QAed 的内容,此 diff 应该为空(在合并到 master 成功 QAed 主题分支后,并从 pre-master 失败 QA 主题分支中变基):
To summarize, the second strategy of merging topic branches into master, and having the pre-master branch as a staging area for QA is the way to go. To make sure you're releasing exactly what you QAed, this diff should be empty (after you merge in to master successfully QAed topic branches, and rebase out of pre-master failed QA topic branches):