On GitHub, sometimes I see projects with "1.x" and "2.x" branches, in addition to tags. Take the Grails SpringSec plugin for example. It has both a master and 1.x branch, as well as several tags.
This has me curious:
At what point would these "1.x" and "2.x" (etc.) "version branches" be created? At what point would they be merged back with master?
At what point would artifacts be built from these "version branches"? In other words, "1.x" could mean "1.0.0" or "1.5.29"...but the latest version might be "1.7.14". What's the relation between the "1.x" branch and the "1.7.14" version of the binary (JAR, ZIP, whatever)?
If you're already going to go with "version branches", then what purpose would a tag possibly serve?
Here's a brief explanation of how branches and tags work and how best to use them.
1. Branches
Branches provide a means to separate your code into different development streams. Initially you start with one main branch (be it master, trunk or other common names). As your project evolves, you start needing certain stability while developing.
A good way to guarantee this is to start using more than one branch for your work. Consider the following: you're working on a feature whose development effort would be high and/or long-term. You wouldn't want to have this in your main branch, if it's something that will change the behavior of your currently existing code, as while it's work-in-progress, you might break things for other people. So, this is when you normally create feature (or topic) branches. When your code becomes stable enough, you merge your feature branch with the respective master. This approach helps you work in isolation from the rest of the developers. They can check your work and comment on it, propose fixes and all at the same time while keeping your master stable.
2. Tags
Tags are something to be considered permanent. They are a marker of your code at a given point in time. When you release version 1.2.3, you need to be able to tell exactly what was in this release, if somebody reports a bug, so that you would be able to reproduce it easily and also check if it has been resolved during development at a later stage when you've released newer versions.
3. Working With Branches And Releasing From Them
Consider you have multiple clients. Assume ClientA has a contract with you that they will pay to use version 1.2.3, while ClientB is a new client interested in your ground-breaking work on some feature in version 2.x that ClientA isn't all hyped up about and therefore not so willing to upgrade to. Your contract states that each client gets service for a year after their payment for your licenses. Yes, generally companies should push for their clients to upgrade to newer versions of their product/service, but quite often the clients are large institutions in which the pace of work and decision-taking is much slower than desired.
So, in order to be able to support both clients, you need to make sure that you have a proper branching strategy and that you will be able to work in isolation. This normally means you have a main branch like master on which all your bleeding-edge development is done. When certain features are ready, if they are needed on the respective branches for those clients, they are merged to their branches. So, if you have feature-15 developed on master and it's something that is needed for ClientB, you only merge it to their branch. If ClientA has reported a critical issue which seems to be only relevant to their product version and not reproducible in later versions, you apply a fix just for them and rollout a release.
Quite often, your contracts are such that you don't give your clients certain functionality, unless they've paid for it. Your pricing model could be annual service which covers free upgrades for the whole year, covering minor and major version. You could also have some clients which you've signed a few years ago and who are very slow at upgrading and thus this need for keeping different version lines alive for a longer period.
3.1. Branching and Tagging In a Multi-branch Environment
Consider you have the following branches:
master : latest development (3.x)
1.x : for your clients who insist on using older versions of your code
2.x : for a bit more up-to-date clients.
Branch 1.x will be used for releasing 1.x-SNAPSHOT-s; 2.0 for 2.x-SNAPSHOT and the master -- for your yet unreleased work on 3.x. Normally, it's a good idea to have a branch per major version which you are actively supporting. For minors you would branch off that branch (for example, version 2.0.3 would be off branch 2.0.x). When your work on a given iteration of features is considered done and stable enough, you create a tag off that branch for the version under development and you bump the version of your current development to the next minor version. I'm talking abstractly, as you haven't mentioned what build tool you're using. With Maven, for example, the version currently under development would be a SNAPSHOT and if your currently released one was from branch 2.x and your development version was 2.3-SNAPSHOT, then your newly released version would be 2.3 and your next development version would be 2.4-SNAPSHOT.
I hope this all makes more sense now.
First of all the 1.x branch is technically just a branch name, like dev, aFeature or any other string.
This is a different model of version control. For example it makes sense, if you sell different licences for different versions.
In this model, you normally don't merge the branches back into the master. You start these branches if you start a new version. Then you maintain them parallel to the master branch.
You then build your releases (you called them artifacts) directly on those branches, by setting "Tags". After that you can go on developing on the same branch. For example:
We create a branch 2.x. After developing a while on that branch, we just create a Tag 2.1.0 and go on developing on that branch. After some bug fixes on the same branch a Tag 2.1.1 and so on. The same work is done for branch 3.x and 4.x.
So the purpose of the Tags is, to freeze a certain state of the code and provide it to the end users.
Related
I work for a small company that currently has only two developers. I'm not an expert with GitHub and I know that our current workflows aren't necessarily standard. I'm not looking to re-design our whole workflow, just a reasonable solution to this specific challenge:
We have two main branches: Development and Master. We use the Master branch for client installs, so it is always behind Development, until we merge the two before a major release.
Due to the nature of our software and target market, it is important for us to be able to periodically apply custom code for specific clients to the Master branch between releases so that it is ready for their use when we install. We also need to apply these changes to the Development branch so that they are included in the next release. This custom code is included in all future client installs/updates, but only accessible to the specific client based on configuration settings.
My current solution is to create the "Custom Feature" branch based on the Master branch. When the custom work is done, we will create a pull request for both the Master branch and the Development branch. Since the Master branch always has the same code as development, just in an earlier state - this seems to me like it should work. But like I said, I'm not an expert with GitHub and I'm sure this could be dangerous for any number of reasons.
I know it's risky to apply these types of periodic changes to a live release branch. However due to the nature of our software, most of our clients expect at least a small level of customization when we install for them.
Edit
I'm aware this is very similar to this question:
Avoid merging master into development branch
But I'm proposing branching from the release branch rather than the development branch, so I think it's a different case (I'll admit some of the concepts from that question go over my head though). I apologize if this is deemed to be a duplicate.
I recommend getting familiar with GitFlow as it might be a solution to your problem. https://datasift.github.io/gitflow/IntroducingGitFlow.html
Basically, you are right, the correct way to do this is to branch off from master, create the change in the branch and then merge to master and develop. Follow the "hotfix" section in the attached link.
I work as part of a small development team (4 people).
None of us are incredibly experienced with version control, but we are required to use Perforce under our company's policies. For the most part it has been great, but we have have kept to a simple process agreed between ourselves that is starting to become less ideal. I was wondering if people could share their experiences of version control working smoothly and efficiently.
Our original setup is this:
We have a trunk, which holds production code as it is now.
Each user creates a development branch for their work, as we have
always worked on separate areas that don't really affect each other.
We develop on Redhat Linux boxes and the code is run from /var/www/html. So we sync to a workspace and copy those files to this path, change the permissions and then perform our changes there. When we want to check in, we check out the files in the workspace, overwrite them with what we have changed and submit (I think this might be our weakest part)
Any changes to trunk will be incorporated if they affect the functionality in question. The code is then deployed for testing.
When testing is complete, we merge the branch into trunk, and then create a release branch from the current trunk this is tested again and then released into production.
This worked fine previously because our projects were small and very separated. Now, however, we are all working on the same big dev branch. Changes have been released since the creation of the dev branch, and more will be made before it is finished.
We are also required to deploy the code for testing in various stages of it's development, and this code needs to be up to date with both the development changes, and any changes that have been made to production.
We have decided at this stage that we will create the release branch at the same time as the dev branch, into which we will merge current Trunk(production) and the current dev branch each time we need a testing version so that it is completely up to date. However, this merge takes a lot of time from the whole team and isn't really working out too well.
I've been told that different teams have different ways of going about things so I'm not looking for a fix for my process, but I would love to hear what setup you use of your willing to share
If you are not particularly familiar with version control and best practices I would suggest utilizing Streams in Perforce. Functionally Streams and Branches are very similar. The difference with Streams is that Perforce utilizes pre-built relationships based on the stream type and gives basic governance (i.e. you can't copy those files to the other stream until you merge).
All the commands CAN be overridden by an admin.
Once you are utilizing streams you can do things a few different ways. You have three types of streams, Release (most stable), Main (stable), and Development (least stable). You can create any hierarchy you like.
I suppose in your case I would have a Mainline, an integration development stream, and then a development stream for each developer to utilize. That way you each have your own playground and can move your changes to the integration stream once they are complete. Those completed changes can then be merged down to the other developer streams.
Is there a specific rule I should be using for when to branch in source control? Branches seem to be expensive because they require that the team have extra knowledge about where the features they want to work on should go.
Our development team sometimes finds itself working on a long term feature and a shorter term feature at the same time. That means we end up with:
Trunk
-Branch A (Short Term)
-Branch B (Long Term)
After they complete we have to merge A in to the trunk, then merge the changes to the trunk back in to B to make sure those edits still function. It's messy.
I am wondering if we can cut down on branches by using Labels (Or tags, or pins or whatever your Source Control Software of choice calls it). Maybe it makes sense to branch for the longer term project, but we could just do the edits for the short term project right in the trunk after applying a label to the stable release. That way we can always retrieve the source code that was stable if we have to do an emergency bug fix, but we don't have to deal with the branch.
What rules do you use to decide when to branch?
One way to reduce branching is to implement new features (especially smaller ones) directly on trunk. This is how we do it:
small features, which will are guaranteed to be completed before the next release, are implemented on trunk
for larger features, we create a feature branch ("Branch B" in your example)
once we are ready to create a release, we create a release branch (from trunk), e.g. named "branches/2.x". This branch is then used for testing and finalizing the release.
once the release is built, we tag the corresponding revision from the release branch (e.g. tags/2.0.0).
normal development then continues on the trunk. the release branch is used for maintenance of the 2.x line of the product (e.g. bug fixes are merged from trunk, or implemented directly on that branch)
In a small team, the time to branch is when you can't commit directly into the trunk. With svn (as I guess with other version controls as well), it is possible to postpone the decision to branch till the time one realizes that one cannot commit into the trunk.
To minimize the need to branch, a new feature can be worked on in the trunk itself by restricting the new-feature code within compile-time or run-time flags. This approach also allows to later turn off feature if not needed, do A/B split testing experiments with the feature, etc.
Of course with this approach it always helps to have a continuous testing that gives an early alert whenever the build/test-suite breaks on the trunk.
For one thing, this depends on the tool you use. Branches are more 'expensive' in Subversion than in Mercurial or git, because merges are harder to do. For another, it depends on your project/organization: you should probably have at least one branch per maintained version.
It depends on the VCS you are using. If you are using a tool that has good support for merging, then you should branch whenever you feel like it. When in doubt, create a new branch. If the UNIX epoch time is even, then you should branch. If it's, odd, you should wait a second, and then branch. If you are using a tool that doesn't support merging well, then you should consider changing tools. In other words, stop using a tool that makes it necessary to ask this question.
It’s normally poor practice to develop against the mainline or trunk. The trunk should be used as the master code set and should reflect the code that currently represents production. If you are not in production yet, it should represent the gold copy and should always build and be subjected to automated regression tests. It should not be used to show development status or activity. Protect your trunk from change and resist the temptation to allow developers to check out and lock code on a trunk. The only updates in my view should be via the merge process, when you are ready to repatriate your code to the mainline.
When branching you should consider the purpose, complexity and duration of the development.
• Is it to support a team of developers working on a new feature or a substantial piece of development?
• Are you using traditional processes or the various agile flavors that are out there?
• It is to accommodate the development of a patch or fix for production?
• What development and in particular, test activity will you accommodate on the branch and will you retain the branch until the derived artifacts are built, tested and deemed releasable?
There are many models out there but few give sufficient consideration to the "build" process and the implications of regenerating your releasable artifacts.
Let’s assume you have the following lifecycle: DEV->SYSTEM-INTEGRATIONTEST->UAT->PRE-PROD->PRODUCTION. Assume you create a branch from mainline to accommodate the development and build processes. Your development\build\test cycle continues right through to UAT. The artifacts produced from this branch have been exposed to sufficient testing to deem them potentially suitable for release. You are able to state that the artifacts signed off by the users were also exposed to system and integration testing.
Some folks advocate merging the source code to the trunk at this point and recommend that you create a RELEASE branch upon a successful trunk rebuild. For me this is fine if the solution is stable and requires no further change prior to production, otherwise you risk propagating bugs elsewhere. In variably it will need to change.
If you do unearth issues in PRE_PROD, where are these “Fix” changes going to be made? Many suggest that you can make the code changes directly in the release branch. If you proceed, this modification will produce a new build and a new set of artifacts. You may elect to push these artifacts back through PRE_PROD and on to production, as the underlying code has been validated through previous testing and the modifications made to stabilize the release are deemed risk free? But you have a problem.
You cannot state that the executables\artefacts released to pre-prod and subsequently production, have been tested in your lower environments. Despite confidence being high, the output from the release branch build is different from that produced from the development builds. This may fail audit.
Branching for me is about managing your code and not the build output or solely the release. If you advocate branching for release and release stabilization (pre-prod fixing), you must take the above risk combined with the need for significant regression testing into consideration.
On the basis that the trunk should represent production code, you cannot push code to it unless it has been pushed to production first. I advocate creating a branch that supports the development, build and release as a single cycle. To avoid branch longevity and unnecessary divergence from the trunk (and potential big bang conflict issues) limit the development as much as you can and release and repatriate often with the trunk to keep other development efforts current.
We use a JIRA as our ticket system. New bugs/tickets are submitted to that system. Once a bug is fixed, we create a new build and test it on our dev server. If everything is good we push it to the live server. Now I usually work on the trunk without any branching to fix the bugs. This is of course a problem. Because there can be many bugs in our system, but only certain ones get fixed at a time. However if I fix all of them in the trunk instead of a branch, then we are forced to test them all even if we did not had enough time to test them all. How do you usually fix bugs and branch etc..? (I am not sure if I explained it very well).
Here is the strategy I use. I develop in the main trunk. When the software is released, I branch it (say v1.0). When bugs come in, fix in the branch trunk and then merge back to main trunk. Here is a good synopsis of strategies that are available: http://www.cmcrossroads.com/bradapp/acme/branching/branch-structs.html
I'm not sure if it's the normal strategy but we do all work on the trunk and then backport bugfixes into release branches. Our main trunk is always 'unstable' and when we feel we have a trunk in a releasable state we branch it into a release branch. From then on buyfixes are ported back into the release branch and new functionality only gets added to the trunk. It means you can run your release branch through testing and focus on testing the bugfixes.
One common mode of operations is that the deployed software lives in a separate branch which receives only bugfixes. Where you actually develop those fixes is mostly irrelevant; to avoid interference with the current development, it makes sense to develop the fix on top of the "live" branch, then test/commit/deploy to the live system and aftewards merge the fix back into the trunk.
We have the same problem (or almost), and I think every developer team has it. I can unfortunately not yet give you an answer by experience, but only a theoretical one.
In my opinion, as long as it's a bug fix, it should be deployed as soon as possible.
What I am about to implement is a feature branch strategy, and a release branch.
This means we have to differentiate features from bugs. and what is deployed is branched separately (or labeled, in our case)
Doing this, you can still work on the trunk for the bugs, and deploy them to your testing server, and once it's tested and approved branch it to the release branch and deploy it.
you can also merge-in the bug fixes into your feature branch, or try to merge the feature later when you plan to deploy it to the testing server.
Anyway, the most important I think is to branch the long work that prevent you from deploying smaller bug fixes.
If you branch too much, you will have a merging problem. If you don't branch enough, you will have a deployment flexibility issue.
It depends on your version control system. If you're using git, where branches are cheap and merges are easy, then I would definitely create a new branch for each fix. This allows you to keep bug fixes independent of each other, allowing greater flexibility with respect to what gets merged into the master/trunk, and when.
On the other hand, if you're using Subversion, branches are more expensive (in terms of creating and switching/updating) and merging is more difficult. Often the cost/benefit ratio of a new branch isn't high enough (especially for small bugs) to make it worthwhile.
I wouldn't recommend branching on every reported bug. As you said, you may not decide to fix every bug that's reported, which would mean that you'd have a lot of dead branches to prune at some point.
If your tools & language support it, branching on every bug you decide to fix (and feature you decide to implement) isn't a bad idea. It allows you to develop and test each bugfix/feature when you have the budget and schedule to do so, and merge them back into trunk when you are ready.
We split our branches into product versions / release, so that each release has its own branch. The release from the branch is tested, and so we only need to test the fixes applied to that branch.
Additionally each product version has a dev and a main branch. Developers are allowed to freely commit to the dev branch without fear of interfering with the Release (only other developers!)
Unless you're using a distributed SCM (Mercurial, Git, ...) where branching is basically free, branching on every bug sounds like an unreasonnable amount of work.
The usual strategy with central repository SCM is to note the revision that is supposed to fix the bug, and test against a build made with a later revision. You can then merge the concerned revision back into the release branch.
We are using mercurial, and branching to fix bugs and then merge changes back is quite doable in a distributed SCM
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Suppose you're developing a software product that has periodic releases. What are the best practices with regard to branching and merging? Slicing off periodic release branches to the public (or whomever your customer is) and then continuing development on the trunk, or considering the trunk the stable version, tagging it as a release periodically, and doing your experimental work in branches. What do folks think is the trunk considered "gold" or considered a "sand box"?
I have tried both methods with a large commercial application.
The answer to which method is better is highly dependent on your exact situation, but I will write what my overall experience has shown so far.
The better method overall (in my experience): The trunk should be always stable.
Here are some guidelines and benefits of this method:
Code each task (or related set of tasks) in its own branch, then you will have the flexibility of when you would like to merge these tasks and perform a release.
QA should be done on each branch before it is merged to the trunk.
By doing QA on each individual branch, you will know exactly what caused the bug easier.
This solution scales to any number of developers.
This method works since branching is an almost instant operation in SVN.
Tag each release that you perform.
You can develop features that you don't plan to release for a while and decide exactly when to merge them.
For all work you do, you can have the benefit of committing your code. If you work out of the trunk only, you will probably keep your code uncommitted a lot, and hence unprotected and without automatic history.
If you try to do the opposite and do all your development in the trunk you'll have the following issues:
Constant build problems for daily builds
Productivity loss when a a developer commits a problem for all other people on the project
Longer release cycles, because you need to finally get a stable version
Less stable releases
You simply will not have the flexibility that you need if you try to keep a branch stable and the trunk as the development sandbox. The reason is that you can't pick and chose from the trunk what you want to put in that stable release. It would already be all mixed in together in the trunk.
The one case in particular that I would say to do all development in the trunk, is when you are starting a new project. There may be other cases too depending on your situation.
By the way distributed version control systems provide much more flexibility and I highly recommend switching to either hg or git.
I've worked with both techniques and I would say that developing on the trunk and branching off stable points as releases is the best way to go.
Those people above who object saying that you'll have:
Constant build problems for daily builds
Productivity loss when a a developer commits a problem for all
other people on the project
have probably not used continuous integration techniques.
It's true that if you don't perform several test builds during the day, say once every hour or so, will leave themselves open to these problems which will quickly strangle the pace of development.
Doing several test builds during the day quickly folds in updates to the main code base so that other's can use it and also alerts you during the day if someone has broken the build so that they can fix it before going home.
As pointed out, only finding out about a broken build when the nightly build for running the regression tests fails is sheer folly and will quickly slow things down.
Have a read of Martin Fowler's paper on Continuous Integration. We rolled our own such system for a major project (3,000kSLOC) in about 2,000 lines of Posix sh.
I tend to take the "release branch" approach. The trunk is volatile. Once release time approaches, I'd make a release branch, which I would treat more cautiously. When that's finally done, I'd label/tag the state of the repository so I'd know the "official" released version.
I understand there are other ways to do it - this is just the way I've done it in the past.
Both.
The trunk is used for the majority of development. But it's expected that best efforts will be made to ensure that any check-in to the trunk won't break it. (partially verified by an automated build and test system)
Releases are maintained in their own directory, with only bug fixes being made on them (and then merged into trunk).
Any new feature that is going to leave the trunk in an unstable or non-working state is done in it's own separate branch and then merged into the trunk up on completion.
I like and use the approach described by Henrik Kniberg in Version Control for Multiple Agile Teams. Henrik did a great job at explaining how to handle version control in an agile environment with multiple teams (works for single team in traditional environments too) and there is no point at paraphrasing him so I'll just post the "cheat sheet" (which is self explaining) below:
I like it because:
It is simple: you can get it from the picture.
It works (and scales) well without too much merge and conflict troubles.
You can release "working software" at any time (in the spirit of agile).
And just in case it wasn't explicit enough: development is done in "work branch(es)", the trunk is used for DONE (releasable) code. Check Version Control for Multiple Agile Teams for all the details.
A good reference on a development process that keeps trunk stable and does all work in branches is Divmod's Ultimate Quality Development System. A quick summary:
All work done must have a ticket associated with it
A new branch is created for each ticket where the work for that ticket is done
Changes from that branch are not merged back into the mainline trunk without being reviewed by another project member
They use SVN for this, but this could easily be done with any of the distributed version control systems.
I think your second approach (e.g., tagging releases and doing experimental stuff in branches, considering the trunk stable) is the best approach.
It should be clear that branches inherit all the bugs of a system at the point in time where it is branched: if fixes are applied to a trunk, you will have to go one by one to all branches if you maintain branches as a sort of release cycle terminator. If you have already had 20 releases and you discovered a bug that goes as far back as the first one, you'll have to reapply your fix 20 times.
Branches are supposed to be the real sand boxes, although the trunk will have to play this role as well: tags will indicate whether the code is "gold" at that point in time, suitable for release.
We develop on the trunk unless the changes are too major, destabilizing, or we are nearing a major release of one of our products, in which case we create a temporary branch. We also create a permanent branch for every individual product release. I found Microsoft's document on Branching Guidance quite helpful. Eric Sink's tutorial on branching is also interesting, and points out that what works for Microsoft may be too heavy for some of the rest of us. It was in our case, we actually use the approach Eric says his team does.
It depends on your situations. We use Perforce and have typically have several lines of development. The trunk is considered "gold" and all development happens on branches that get merged back to the mainline when they are stable enough to integrate. This allows rejection of features that don't make the cut and can provide solid incremental capability over time that independent projects/features can pick up.
There is integration cost to the merging and catching up to new features rolled into the trunk, but you're going to suffer this pain anyway. Having everyone develop on the trunk together can lead to a wild west situation, while branching allows you to scale and choose the points at which you'd like to take the bitter integration pills. We're currently scaled to over a hundred developers on a dozen projects, each with multiple releases using the same core components, and it works pretty well.
The beauty of this is that you can do this recursively: a big feature branch can be its own trunk with other branches coming off if it. Also, final releases get a new branch to give you a place to do stable maintenance.
Attempting to manage maintenance of current production code in line with new development is problematic at best. In order to mitigate those problems code should branch into a maintenance line once testing efforts have completed and the code is ready for delivery. Additionally, the mainline should branch to assist in release stabilization, to contain experimental development efforts, or to house any development efforts whose lifecycle extends across multiple releases.
A non-maintenance branch should be created only when there is the likelihood (or certainty) of collisions among the code that would be difficult to manage any other way. If the branch does not solve a logistical problem, it will create one.
Normal release development occurs in the mainline. Developers check into and out of the mainline for normal release work. Development work for patches to current Production code should be in the branch for that release and then merged with the mainline once the patch has passed testing and is deployed. Work in non-maintenance branches should be coordinated on a case-by-case basis.
It depends on the size of your development effort. Multiple teams working in parallel won't be able to work effectively all on the same code (trunk). If you have just a small group of people working and your main concern is cutting a branch so you can continue to work while going back to the branch for making bug-fixes to the current production code that would work. This is a trivial use of branching and not too burdensome.
If you have a lots of parallel development you'll want to have branches for each of the efforts but that'll also require more discipline: Making sure your branches are tested and ready to merge back. Scheduling merges so two groups aren't trying to merge at the same time etc.
Some branches are under development for so long that you have to permit merges from the trunk to the branch in order to reduce the number of surprises when finally merging back to the trunk.
You will have to experiment if you have a large group of developers and get a feel for what works in your situation. Here is a page from Microsoft that may be somewhat useful: http://msdn.microsoft.com/en-us/library/aa730834(VS.80).aspx
We are using the trunk for main development and branch for releases maintenance work. It works nice. But then branches should only be used for bug fixes, no major changes, especially on database side, we have a rule that only a schema change can happen on the main trunk and never in the branch.
If you are gonna be working through a release cycle, big feature, you get marooned to a branch. Otherwise we work in trunk, and branch for every production release at the moment we build.
Previous production builds are moved at that time to old_production_ and current prod release is always just production. All our build server knows about production is how to deploy the production branch, and we kick that build off with a force trigger.
We follow the trunk=current development stream, branch=release(s) approach. On release to the customer we branch the trunk and just keep the trunk rolling forward. You'll need to make a decision on how many releases you're prepared to support. The more you support the more merging you'll be doing on bug fixes. We try and keep our customers on no more than 2 releases behind the trunk. (Eg. Dev = 1.3, supported releases 1.2 and 1.1).
The trunk is generally the main development line.
Releases are branched off and often times experimental or major work is done on branches then merged back to the trunk when it's ready to be integrated with the main development line.
The trunk should generally be your main development source. Otherwise you will spend a lot of time merging in new features. I've seen it done the other way and it usually leads to a lot of last minute integration headaches.
We label our releases so we can quickly respond to production emergencies without distribing active development.
For me, it depends on the software I'm using.
Under CVS, I would just work in "trunk" and never tag/branch, because it was really painful to do otherwise.
In SVN, I would do my "bleeding edge" stuff in trunk, but when it was time to do a server push get tagged appropriately.
I recently switching to git. Now I find that I never work in trunk. Instead I use a named "new-featurename" sandbox branch and then merge into a fixed "current-production" branch. Now that I think about it, I really should be making "release-VERSIONNUMBER" branches before merging back into "current-production" so I can go back to older stable versions...
It really depends on how well your organization/team manages versions and which SCM you use.
If what's next(in the next release) can be easily planned, you are better off with developing in the trunk. Managing branches takes more time and resources. But if next can't be planned easily(happens all the time in bigger organizations), you would probably end up cherry picking commits(hundreds/thousands) rather than branches(severals or tens).
With Git or Mercurial, managing branches is much easier than cvs and subversion. I would go for the stable trunk/topic branches methodlogy. This is what the git.git team using. read:http://www.kernel.org/pub/software/scm/git/docs/gitworkflows.html
With Subversion, I first applied the develop-in-the-trunk methodlogy. There was quite some work when it came to release date because everytime I had to cherry pick commits(my company is no good at planning). Now I am sort of expert in Subversion and know quite well about manaing branches in Subversion, so I am moving towards the stable trunk/topic branches methodlogy. It works much better than before. Now I am trying the way how git.git team works, although we will probably stick with Subversion.
Here is the SVN design that I prefer:
root
development
branches
feature1
feature2
...
trunk
beta
tags
trunk
release
tags
trunk
All work is done from development/trunk, except for major features that require its own branch. After work is tested against development/trunk, we merge tested issues into beta/trunk. If necessary, code is tested against the beta server. When we are ready to roll some changes out, we just merge appropriate revisions into release/trunk and deploy.
Tags can be made in the beta branch or the release branch so we can keep track of specific release for both beta and release.
This design allows for a lot of flexibility. It also makes it easy for us to leave revisions in beta/trunk while merging others to release/trunk if some revisions did not pass tests in beta.
There's no one-size-fits-all answer for the subversion convention question IMHO.
It really depends on the dynamics of the project and company using it. In a very fast-paced environment, when a release might happen as often as every few days, if you try to religiously tag and branch, you'll end up with an unmanageable repository. In such an environment, the branch-when-needed approach would create a much more maintainable environment.
Also - in my experience it is extremely easy, from a pure administrative standpoint, to switch between svn methodologies when you choose to.
The two approaches I've known to work best are the branch-when-needed, and the branch-each-task. These are, of course, sort of the exact opposite of one another. Like I said - it's all about the project dynamics.