James P.
James P.

Reputation: 19617

Use of trunks, branches and tags in a project

I know the theory but how is svn used from a practical point of view for a project? Say, I have a web site with features that are going to be modifed or added. In what cases would new trunks, branches and tags be used?

Upvotes: 0

Views: 327

Answers (4)

Sir Rippov the Maple
Sir Rippov the Maple

Reputation: 7581

Have a look at these two articles:

http://www.snuffybear.com/ucm_branch.htm

http://www.vance.com/steve/perforce/Branching_Strategies.html

The the link from SnuffyBear speaks more about the strategy that you seem to want to employ whereas the other article talks about other strategies such as branch by release. Each article outlines the advantages and disadvantages of each strategy.

Upvotes: 2

Jay
Jay

Reputation: 27502

My humble observations: Merging branches is scary. In many cases, changes made by different developers are completely separate and so merge smoothly. But in any busy project, there are going to be times when changes conflict. If you're lucky, SVN recognizes the conflict and gives you errors at merge times. If you're less lucky, SVN doesn't catch it but it fails to compile. Either way, somebody now has to figure out how to put the changes together. Sometimes this is obvious and easy. But I've had many times where I've had to get the developers who made the changes together so we could figure out what to do.

If you're very unlucky, neither SVN nor the compiler see a problem, conflicting changes go to production, and the program behaves incorrectly.

From this observation I come to two conclusions: (a) Make as few branches as possible. Or more accurately, develop your strategy to do as few merges as possible. And (b) Do merges on code while it is still in testing.

For a while my company had a branching strategy that said that each project got its own branch, tested off of that branch, and when we were ready to deploy to production, we merged all the branches to be included in that release, compiled and deployed. This turned out to be a really really bad idea. Somebody would be trying to resolve merge conflicts the day before deploying, and the results of the merge were never tested. A lot of subtle bugs crept into production.

For a whlie we used this strategy: Most development is done in trunk. When a release is ready to be turned over to the test group, we peel off a branch for it. Then work on the next release proceeds in trunk. Any bug fixes to the current release are done in the branch, and the changes in this branch are periodically merged back into trunk. Occassionally it was necessary to have work on 3 releases going on simultaneously, i.e. one release was in testing, another was getting close to being ready for testing, and now we need to start on the next release. In that case we'd have the test branch, trunk for the current release, and a "pre" branch for the next release. When the current release went to the test group, we would then merge the "pre" branch into trunk and it became the current release.

We have recently begun experimenting with a slightly different strategy. When a release is in testing, we still peel off a separate branch for it. But any fixes coming out of testing are made in trunk, and then those fixes are merged from trunk into the test branch. This means that all development happens in trunk, and merges are always from trunk to somewhere else. This has two big advantages: One, developers are always testing with trunk, so we have a higher confidence that the code in trunk is good. The testing group will test against the release branch, so we have confidence that the release branch is good. That is, we have some confidence that both branches will be tested. When you make changes in a branch and then merge back to trunk. there's little assurance that anyone will test the results of that merge. Two, trunk always has the full "blame" history of every module. When you merge from branches back to trunk. the history in trunk attributes all changes from the branch to the person who did the merge, rather than the person who really made the change, and the comment tends to be an uninformative "merged from brach xyz". When you merge from trunk to a branch, sure the branch now shows the "wrong" person and an uninformative comment, but trunk has a good history. There's one place to go for history instead of trying to chase down branches.

Upvotes: 1

btilly
btilly

Reputation: 46507

Different organizations do very different things. The solution that Alex gives above is a common one, however it encounters the issue that you'll only discover what other branches have conflicts with yours after you land your branch. This causes people to have to debug conflicts in stuff that they have not looked at in some time.

The other common approach that I have encountered is to do all development in trunk, and make developers make all commits small, standalone, commits. There are a variety of ways to add a feature and make it invisible by default, but turned on in your development copy. Use them. This approach requires care from the developers, but avoids pain from managing conflicts between longer lived branches.

A lot of the people who use Alex' solution will jump up and down and say, "That will never work for anything beyond a tiny team!" To that I respond that there is nothing wrong with small teams, their productivity typically far exceeds anything a large team can do. And that strategy can scale if developers have discipline, for instance Google uses it. If you want to see an actual project that uses that strategy, take a look at http://llvm.org/.

And some advice. If you want to follow Alex' strategy, I strongly recommend using git instead of svn. It handles branches much better than svn does. If you want to follow the strategy that I suggest and your team is not a small team with people you trust, you need to use a code review tool like http://code.google.com/appengine/articles/rietveld.html to reduce the obvious problems that can arise.

Upvotes: 2

Alex KeySmith
Alex KeySmith

Reputation: 17111

I'd say a single trunk where "stable" very minor changes (perhaps small bug fixes) are made, that will not break your build.

Branches should be made for new features / large changes. The branch should be kept up to date with changes to your trunk, whilst the branch is in operation.

Once your new feature has been completed the branch should be merged back into the trunk and then the branch can be deleted.

Tags are for releases. e.g. v1.2

Upvotes: 1

Related Questions