如何维护开发代码和生产代码?

发布于 2024-07-07 04:22:56 字数 1449 浏览 10 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

赠我空喜 2024-07-14 04:22:56

2019 年更新:

如今,这个问题会出现在使用 Git 的环境中,以及使用 分布式 开发 10 年的情况< a href="https://stackoverflow.com/a/2705286/6309">工作流程(主要协作通过 GitHub)显示了一般最佳实践:

  • master 是随时可以部署到生产环境中的分支:下一个版本,一组选定的功能分支合并到master中。
  • 一起测试的分支
  • dev(或集成分支,或“next”)是为下一版本选择的功能分支与maintenance (或hot-fix) 分支是当前版本演变/错误修复的分支,可能合并回 < code>dev 和或 master

这种工作流程(您不将 dev 合并到 master,但是,您仅将功能分支合并到 dev,然后如果选择,则合并到 master,以便能够轻松删除尚未准备好用于下一个版本的功能分支)在 Git 存储库本身中,使用 gitworkflow (一个词,此处有说明)。
如需了解更多信息,请访问 rocketraman/gitworkflowAdam Dymitruk 的这篇文章

https:// /github.com/rocketraman/gitworkflow/raw/master/docs/images/topicgraduation.png

(来源:Gitworkflow:面向任务的入门)

注意:在分布式工作流程中,您可以随时提交并将一些 WIP(正在进行中的工作)推送到个人分支,不会出现任何问题:您将能够在将提交成为功能分支的一部分之前重新组织(git rebase)您的提交。


原始答案(2008 年 10 月,10 多年前)

这一切都取决于发布管理的顺序性

首先,您后备箱中的所有内容是否真的是为了下一个版本
您可能会发现当前开发的一些功能是:

  • 太复杂,仍然需要完善
  • 没有及时准备
  • 好 有趣,但不适合下一个版本

在这种情况下,主干应该包含任何当前的开发工作,但早期定义的发布分支在下一个版本可以作为合并分支之前,其中仅合并适当的代码(针对下一个版本进行验证),然后在同源阶段进行修复,最后冻结为它投入生产。

当涉及到生产代码时,您还需要管理您的补丁分支,同时记住:

  • 第一组补丁实际上可能在首次发布到生产之前开始(这意味着您知道您会去进入生产环境时存在一些无法及时修复的错误,但您可以在单独的分支中启动针对这些错误的工作)
  • 其他补丁分支将有机会从明确定义的生产标签开始

当涉及到开发分支时,您可以有一个主干,除非您需要并行进行其他开发工作,例如:

  • 对新技术库进行大规模重构
  • 调用其他类中事物的方式
  • 测试,这可能会改变您在新版本开始时 需要纳入重要架构变更的周期。

现在,如果您的开发-发布周期非常连续,您可以按照其他答案的建议进行:一个主干和多个发布分支。 这适用于小型项目,其中所有开发都肯定会进入下一个版本,并且可以冻结并作为发布分支的起点,可以在其中进行补丁。 这是名义上的过程,但是一旦您有一个更复杂的项目......它就不再足够了。


回答 Ville M. 的评论:

  • 请记住,开发分支并不意味着“每个开发人员一个分支”(这会引发“合并疯狂”,因为每个开发人员都必须合并其他人的工作才能查看/获取他们的工作)工作),但每个开发工作有一个开发分支。
  • 当这些工作需要合并回主干(或您定义的任何其他“主”或发布分支)时,这是开发人员的工作,不是 - 我重复一遍,不是 - SC 经理(谁不知道如何解决任何冲突的合并)。 项目负责人可以监督合并,这意味着确保它按时开始/完成。
  • 无论您选择谁来实际进行合并,最重要的是:
    • 拥有可以部署/测试合并结果的单元测试和/或组装环境。
    • 在合并开始之前定义一个标签,以便在所述合并证明本身太复杂或太长而无法返回到之前的状态解决。

Update 2019:

These days, the question would be seen in a context using Git, and 10 years of using that distributed development workflow (collaborating mainly through GitHub) shows the general best practices:

  • master is the branch ready to be deployed into production at any time: the next release, with a selected set of feature branches merged in master.
  • dev (or integration branch, or 'next') is the one where the feature branch selected for the next release are tested together
  • maintenance (or hot-fix) branch is the one for the current release evolution/bug fixes, with possible merges back to dev and or master

That kind of workflow (where you don't merge dev to master, but where you merge only feature branch to dev, then if selected, to master, in order to be able to drop easily feature branches not ready for the next release) is implemented in the Git repo itself, with the gitworkflow (one word, illustrated here).
See more at rocketraman/gitworkflow. The history of doing this vs Trunk-Based-Development is noted in the comments and discussions of this article by Adam Dymitruk.

https://github.com/rocketraman/gitworkflow/raw/master/docs/images/topicgraduation.png

(source: Gitworkflow: A Task-Oriented Primer)

Note: in that distributed workflow, you can commit whenever you want and push to a personal branch some WIP (Work In Progress) without issue: you will be able to reorganize (git rebase) your commits before making them part of a feature branch.


Original answer (Oct. 2008, 10+ years ago)

It all depends of the sequential nature of your release management

First, is everything in your trunk really for the next release?
You might find out that some of the currently developed functions are:

  • too complicated and still need to be refined
  • not ready in time
  • interesting but not for this next release

In this case, trunk should contain any current development efforts, but a release branch defined early before the next release can serve as consolidation branch in which only the appropriate code (validated for the next release) is merged, then fixed during the homologation phase, and finally frozen as it goes into production.

When it comes to production code, you also need to manage your patch branches, while keeping in mind that:

  • the first set of patches might actually begin before to first release into production (meaning you know you will go into production with some bugs you can not fix in time, but you can initiate work for those bugs in a separate branch)
  • the other patch branches will have the luxury to start from a well-defined production label

When it comes to dev branch, you can have one trunk, unless you have other development efforts you need to make in parallel like:

  • massive refactoring
  • testing of a new technical library which might change the way you calls things in other classes
  • beginning of a new release cycle where important architectural changes need to be incorporated.

Now, if your development-release cycle is very sequential, you can just go as the other answers suggest: one trunk and several release branches. That works for small projects where all the development is sure to go into the next release, and can just be frozen and serve as a starting point for release branch, where patches can take place. That is the nominal process, but as soon as you have a more complex project... it is not enough anymore.


To answer Ville M.'s comment:

  • keep in mind that dev branch does not mean 'one branch per developer' (which would trigger 'merge madness', in that each developer would have to merge the work of other to see/get their work), but one dev branch per development effort.
  • When those efforts need to be merged back into trunk (or any other "main" or release branch you define), this is the work of the developer, not - I repeat, NOT - the SC Manager (who would not know how to solve any conflicting merge). The project leader may supervise the merge, meaning make sure it starts/finish on time.
  • whoever you choose for actually doing the merge, the most important is:
    • to have unit tests and/or assembly environment in which you can deploy/test the result of the merge.
    • to have defined a tag before the beginning of the merge in order to be able to get back to previous state if said merge proves itself too complex or rather long to resolve.
李白 2024-07-14 04:22:56

我们专门使用:

  • 开发分支,

直到项目接近完成,或者我们正在创建一个里程碑版本(例如产品演示、演示版本),然后我们(定期)将当前的开发分支分支到:

  • 发布分支

没有新功能进入发布分支。 发布分支中只修复重要的错误,修复这些错误的代码会重新集成到开发分支中。

开发和稳定(发布)分支的两部分过程使我们的生活变得更加轻松,而且我不相信我们可以通过引入更多分支来改进它的任何部分。 每个分支也有自己的构建过程,这意味着每隔几分钟就会产生一个新的构建过程,因此在代码签入后,我们在大约半小时内就有了所有构建版本和分支的新可执行文件。

有时,我们也会为单个开发人员设立分支机构,以开发未经验证的新技术或创建概念验证。 但通常只有当更改影响到代码库的许多部分时才会这样做。 这种情况平均每 3-4 个月发生一次,这样的分支通常会在一两个月内重新整合(或废弃)。

一般来说,我不喜欢每个开发人员在自己的分支中工作的想法,因为你“跳过 go 并直接进入集成地狱”。 我强烈建议不要这样做。 如果您有一个共同的代码库,那么大家应该一起使用它。 这使得开发人员对他们的签入更加谨慎,并且根据经验,每个编码人员都知道哪些更改可能会破坏构建,因此在这种情况下测试会更加严格。

关于早期签入的问题:

如果您只需要签入完美代码,那么实际上不应该签入任何内容。没有代码是完美的,对于 QA 来验证和测试它,它需要位于开发分支中,以便可以构建新的可执行文件。

对我们来说,这意味着一旦功能完成并由开发人员测试,它就会被签入。如果存在已知(非致命)错误,甚至可能会被签入,但在这种情况下,将受到该错误影响的人是通常被告知。 不完整和正在进行的代码也可以签入,但前提是它不会造成任何明显的负面影响,例如崩溃或破坏现有功能。

时不时地,不可避免地会出现组合代码和组合代码。 数据签入将使程序无法使用,直到新代码构建完成。 我们至少要做的是在签入评论中添加“等待构建”和/或发送电子邮件。

We use:

  • development branch exclusively

until the project nears completion, or we are creating a milestone version (eg. product demo, presentation version), then we (regularly) branch off our current development branch into the:

  • release branch

No new features go into the release branch. Only important bugs are fixed in the release branch, and the code to fix these bugs is reintegrated into the development branch.

The two-part process with a development and a stable (release) branch makes life a lot easier for us, and i don't believe we could improve any part of it by introducing more branches. Each branch also has it's own build process, meaning every couple minutes a new build process is spawned and so after a code checkin we have a new executable of all build versions and branches within about half an hour.

Occassionally we also have branches for a single developer working on a new and unproved technology, or creating a proof of concept. But generally it's only done if the changes affects many parts of the codebase. This happens in average every 3-4 months and such a branch is usually reintegrated (or scrapped) within a month or two.

Generally i don't like the idea of every developer working in his own branch, because you "skip go and move directly to integration hell". I would strongly advise against it. If you have a common codebase, you should all work in it together. This makes developers more wary about their checkins, and with experience every coder knows which changes are potentially breaking the build and so testing is more rigorous in such cases.

On the check-in early question:

If you require only PERFECT CODE to be checked in, then actually nothing should get checked in. No code is perfect, and for the QA to verify and test it, it needs to be in the development branch so a new executable can be built.

For us that means once a feature is complete and tested by the developer it is checked in. It may even be checked in if there are known (non-fatal) bugs, but in that case the people who would be affected by the bug are usually informed. Incomplete and work-in-progress code can also be checked in but only if it doesn't cause any obvious negative effects, like crashes or breaking existing functionality.

Every now and then an unavoidable combined code & data checkin will make the program unusable until the new code has been built. The very least we do is to add a "WAIT FOR BUILD" in the check-in comment and/or send out an e-mail.

夏尔 2024-07-14 04:22:56

就其价值而言,我们就是这么做的。

大多数开发都是在主干中进行的,尽管实验性功能或可能严重破坏系统的事物往往会获得自己的分支。 这非常有效,因为这意味着每个开发人员在其工作副本中始终拥有所有内容的最新版本。

这确实意味着保持主干处于模糊的工作状态很重要,因为完全有可能完全破坏它。 在实践中,这种情况并不经常发生,也很少成为重大问题。

对于生产版本,我们对主干进行分支,停止添加新功能,并致力于错误修复和测试分支(定期合并回主干),直到准备好发布为止。 此时,我们最终合并到主干中,以确保所有内容都在其中,然后发布。

然后可以根据需要在发布分支上执行维护,并且这些修复可以轻松地合并回主干。

我并不认为这是一个完美的系统(它仍然有一些漏洞 - 我认为我们的发布管理还不是一个足够严格的流程),但它运行得足够好。

For what it's worth, this is how we do it.

Most development is performed in trunk, although experimental features or things that might break the system significantly tend to get their own branch. This works out pretty well as it means every developer always has the latest version of everything in their working copy.

It does mean that it's important to keep trunk in vaguely working order, as it's perfectly possible to completely break it. In practice that doesn't happen often, and is rarely a significant problem.

For a production release, we branch trunk, stop adding new features, and work on bugfixing and testing the branch (regularly merging back into trunk) until it's ready for release. At which point we do a final merge into trunk to make sure everything is in there, and then release.

Maintenance can then be performed on the release branch as necessary, and those fixes can be easily merged back into trunk.

I don't claim this to be a perfect system (and it still has some holes - I don't think our release management is a tight enough process yet), but it works well enough.

一笔一画续写前缘 2024-07-14 04:22:56

怎么还没人提这个? 成功的 Git 分支模型

对我来说这是终极的分支模型!

如果您的项目很小,请不要一直使用所有不同的分支(也许您可以跳过小功能的功能分支)。 但除此之外,这就是这样做的方法!

分支模型

Why no one still mention this? A successful Git branching model.

It's for me the ultimate branching model!

If you're project is small, don't use all the time all the different branches (perhaps you could skip feature branches for small features). But otherwise, it's the way to do it!

branching model

揽清风入怀 2024-07-14 04:22:56

分支上的开发代码,主干上标记的实时代码。

不需要有“只提交完美代码”的规则 - 开发人员错过的任何内容都应该在四个地方找到:代码审查、分支测试、回归测试、最终 QA 测试。

以下是更详细的分步说明:

  1. 在分支上进行所有开发,并定期提交。
  2. 所有开发完成后,对更改进行独立代码审查。
  3. 然后将分支传递给测试。
  4. 分支测试完成后,将代码合并到发布候选分支中。
  5. 发布候选分支在每次单独合并后都会进行回归测试。
  6. 在所有开发分支合并后,在 RC 上执行最终的 QA 和 UA 测试。
  7. 一旦 QA 和 UAT 通过,将发布分支合并到 MAIN/TRUNK 分支。
  8. 最后,在该点标记主干,并将该标记部署到 Live。

Development code on branches, Live code tagged on Trunk.

There doesn't need to be a "commit only perfect code" rule - anything that the developer misses should get picked up in four places: the code review, branch testing, regression testing, final QA testing.

Here's a more detailed step-by-step explanation:

  1. Do all development on a branch, committing regularly as you go.
  2. Independent Code Review of changes once all development is complete.
  3. Then pass the branch over to Testing.
  4. Once branch testing complete, merge code into Release Candidate branch.
  5. Release Candidate branch is regression tested after each individual merge.
  6. Final QA and UA Testing performed on RC after all dev branches merged in.
  7. Once QA and UAT are passed, merge release branch into MAIN/TRUNK branch.
  8. Finally, tag the Trunk at that point, and deploy that tag to Live.
我的痛♀有谁懂 2024-07-14 04:22:56

开发进入主干(svn 风格),发布(生产代码)获得自己的分支,

这是“按目的分支模型”(分支模型的重要性 /!\ pdf)

dev goes in trunk (svn style) and releases (production code) get their own branches

It's the "Branch-by purpose model" (figure 3 in The importance of branching models /!\ pdf)

南街九尾狐 2024-07-14 04:22:56

我们通过将生产代码(主干)与开发代码(每个开发人员都有自己的分支)完全分离来解决这个问题。

在(由 QA 和代码审查人员)彻底检查之前,任何代码都不允许进入生产代码。

这样就不会混淆哪些代码可以工作,它始终是主分支。

We solve this problem by completely separating the production code (the main trunk) from the development code (where every developer has his own branch).

No code is allowed into production code before it has been thoroughly checked (by QA and code reviewers).

This way there is no confusion about which code works, it is always the main branch.

客…行舟 2024-07-14 04:22:56

哦,是的 - 另一件事 - 我们在 cvs HEAD 中保留非生产代码(即永远不会发布的代码 - 例如工具脚本、测试实用程序)。 通常它需要被清楚地标记,这样就没有人“意外”释放它。

Oh yes - one other thing - we keep non-production code (i.e that which will NEVER be released - e.g. tool scripts, testing utilities) in cvs HEAD. Usually it needs to be clearly marked so nobody "accidentally" releases it.

忆依然 2024-07-14 04:22:56

我们在主干上进行开发,然后每两周进行一次分支并投入生产。 只有严重的错误在分支中得到修复,其余的可以再等两周。

对于主干,唯一的规则是提交不应破坏任何内容。 为了管理在制品代码和未经测试的代码,我们只需添加适当的 if 语句即可轻松打开和关闭。

基本上可以随时分支主干并将其投入生产。

We develop on trunk wich is then branched every two weeks and put into production. Only critical bugs are fixed in branch, the rest can wait another two weeks.

For trunk the only rule is that a commit shouldn't break anything. To manage wip-code and untested code we just add appropriate if statments to make it easy to toggle on and off.

Basically it whould be possible to branch trunk at any time and put it in production.

零度℉ 2024-07-14 04:22:56

我使用 git 并且有 2 个分支:mastermaint

  • master - 开发代码
  • maint - 生产代码

当我将代码发布到生产时,我对其进行标记并合并 master 到 maint 分支。 我总是从 maint 分支部署。 我从开发分支挑选补丁来维护分支并部署补丁。

I use git and I have 2 branches: master and maint

  • master - development code
  • maint - production code

when I release code to production, I tag it and I merge master to maint branch. I always deploy from maint branch. Patches from development branch I cherry-pick them to maint branch and deploy patches.

逐鹿 2024-07-14 04:22:56

我们有一个“发布”分支,其中包含当前正在生产或即将部署的内容(已经通过了大多数质量检查)

每个项目,或在某些情况下其他单元,都有自己的从发布分支出来的分支。

项目开发人员将更改提交到他们项目自己的分支中。 定期地将发布合并回开发分支。

一旦分支上的工作包全部经过 QA(单元测试、系统测试、代码审查、QA 审查等),该分支就会合并到发布分支。 新版本是从发布分支构建的,最终验证发生在该版本上。

整个过程基本没问题,直到合并完成后发现问题。 如果 WP 在合并后“卡住”,它将保留其后的所有内容,直到修复为止(在卡住的版本被释放之前我们无法进行另一次发布)。


它也有一定的灵活性——如果发布分支的发布时间很短(比如 1-2 天左右),那么一个非常微不足道的更改可能会直接发生在发布分支上。

如果由于某种原因将更改直接投入生产(影响客户的关键生产问题,需要立即更改代码来修复),这些更改将被放回到 BRANCH_RELEASE 中。 这种情况几乎不会发生。

We have a "release" branch which contains what's currently on production or will be deployed shortly (already passed most QA)

Each project, or in some cases other unit, has its own branch which is branched from release.

Changes get committed, by the developers on the project, into their project's own branch. Periodically, release is merged back into a development branch.

Once the work packages on the branch are all QA'd (unit test, system test, code review, QA review etc), the branch is merged into the release branch. The new build(s) are built from the release branch, and final validation happens on that version.

The process is basically OK until an issue is discovered after a merge has been done. If a WP gets "stuck" after it's been merged, it holds up everything after it until it's fixed (we can't do another release until the stuck one is released).


It's also somewhat flexible - a very trivial change could happen directly on the release branch if it was being released on a very short time scale (like 1-2 days or so).

If a change was put directly on to production for some reason (a critical customer-affecting production issue which required an immediate code change to fix), those changes would be put back in BRANCH_RELEASE. That hardly ever happens.

过去的过去 2024-07-14 04:22:56

这取决于项目。 我们的 Web 代码的签入非常一致,而我们的应用程序代码仅在编译后才会签入。 我注意到这与我们发布东西的方式非常相似。 当应用程序遇到严格的截止日期时,网络内容就会尽可能地增加。 不过,我还没有看到这两种方法有质量损失。

It depends on the project. Our web code is checked in pretty consistently, while our application code is only checked in if it compiles. I've noticed that this is pretty similar to how we release things. Web stuff goes up whenever it can while applications hit a hard deadline. I haven't seen a loss of quality in either method though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文