151

What are the best practices and rules-of-thumb to follow while maintaining code? Is it good practice to have only the production ready code in the development branch, or should untested latest code be available in the development branch?

How do you guys maintain your development code and production code?

Edit - Supplementary question - Does your development team follow "commit-as-soon-as-possible-and-often-even-if-the-code-contains-minor-bugs-or-is-incomplete" protocol or "commit-ONLY-perfect-code" protocol while committing code to DEVELOPMENT branch?

2
  • I've answered a similar question (or well, a question in that same space/direction) before, so you might want to check out this question: What are some good strategies to allow deployed applications to be hotfixable?
    – Till
    Commented Oct 19, 2008 at 15:27
  • @revo: wait... my 2008 answer is out-of-date? :) I suppose it is indeed. It has been more than 10 years: I have edited my answer.
    – VonC
    Commented Mar 13, 2019 at 7:34

12 Answers 12

132

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.
4
  • How do you ensure that master (production) and dev (integration) do not diverge? Especially with hot fixes? Do you regularly merge master back into dev, e.g. after doing a release?
    – Bergi
    Commented Aug 21, 2020 at 18:07
  • 1
    @Bergi with gitworflow, dev is an ephemeral branch, deleted and recreated on top of each new release. No divergence there.
    – VonC
    Commented Aug 21, 2020 at 18:33
  • 1
    It has been more than 12 years since it was originally posted, but I'd like to say that this answer still extremely useful and current.
    – Matheus
    Commented Jun 17, 2021 at 12:45
  • 1
    @MatheusCirillo Thank you Matheus. I had actually revised this answer in 2019 to mention gitworkflow. But I am glad this is still useful.
    – VonC
    Commented Jun 17, 2021 at 16:01
45

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.

2
  • 1
    I voted it up. This is similar to what we do, but we are making all changes in development and then trying to merge those bug fixes into the release branch.. Not working. However, I think if we change to do all bug fixes in release and merge into the development, that will fix it. Commented Nov 7, 2008 at 14:09
  • 2
    You imply that the QA test the development branch, wouldn't it be better if they check the release branch? That way I could start working on my new mad feature that won't be included in the next release (and might break something) while in that time QA will test the existing code without my new feature interfearing?
    – BornToCode
    Commented Dec 27, 2016 at 14:36
16

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.

1
  • works well enough and is simple enough as well for code-only-non-vcs-druids developers.
    – Matthieu
    Commented Aug 17, 2018 at 10:03
14

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

4
  • 4
    Yes, except if it often a bit too complex/complete, as scottchacon.com/2011/08/31/github-flow.html illustrates.
    – VonC
    Commented Jul 16, 2013 at 12:33
  • I agree. Understand the git flow branching model (that solve a lot of problems) and simplify it to match your needs. And GitHub flow require quick deploying but that's not always possible... It's more or less the branching model we use in my project (to keep things simple) but we faced a case where we would have loved to use the git-flow model :( and that put us in really big shit :(
    – Philippe
    Commented Jul 16, 2013 at 16:49
  • 1
    The way I see it, this basically copies everything VonC said roughly 1 year before (on his answer), but in a more detailed way and with nice pictures!
    – cregox
    Commented Dec 2, 2013 at 21:13
  • "Why no one still mention this?" because the contents (proposed model) is 13 years old, and the author, VD, makes updated comments how things evolved, moved on, etc. IMO it's less not about "best practice", but rather the act of balancing the opinions of management, about what you're doing.
    – user5248982
    Commented Aug 24, 2023 at 15:32
6

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.
4

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)

3

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.

2

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.

2
  • 2
    maybe this would be better as an edit to the previous answer. Commented Oct 19, 2008 at 11:34
  • 6
    He said CVS. :-)
    – Till
    Commented Oct 19, 2008 at 15:28
2

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.

0

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.

0

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.

0

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.