tags:

views:

95

answers:

4

I am kind of new to SVN, I haven't used it in detail basically just checking out trunk and committing then exporting and deploying.

I am working on a big project now with several developers and we are looking for the best deployment process. The one thing we are hung up on is the best way to tag, branch and so on. We are used to CVS where all you have to do is commit a file and tag it as production ready and if not that code will not get deployed.

I see that SVN handles tagging differently then CVS. I figure I am looking at this and making it overly complex. It seems the only way to work on a project and commit files without it being in the production code is to do it in a branch and then merge those changes when you are ready for it to be deployed. I am assuming you could also be working on other code that should be deployed so you would have to be switching between working copies, because otherwise you are working on a branch that isn't getting mixed in with the trunk or production branch?

This process seems overly complex and I was wondering if anyone could give me what you think is the best process for managing this.

A: 

the only way to work on a project and commit files without it being in the production code is to do it in a branch and then merge those changes when you are ready for it to be deployed.

Absolutely correct. This is the way to work with SVN, TFS and most modern source control management systems.

The normal workflow is to have a TRUNK branch which is as close to production as possible, and a Main branch, which the work is done on - for large features you create sub branches from your Main branch.

There are distributed SCMs, such as Git and Mercurial that do not work this way, but chances are you will find them even more complex than SVN.

See this blog post on one branching strategy (A SVN branching strategy that works).

Here is another (Simple branching and merging with SVN).

Oded
'most modern source control management systems' - except DVCSs like Mercurial...
Mark Pim
mercurial is different. its branches are called clones. ;)
stmax
Thanks for the info and the links, those are some great resources, can't believe they didn't come up in my googling
dan.codes
A: 

What the best process is depends on a number of factors. How big are your changes, what kind are they (bug-fixes, new features), how many developers do you have?

In general I would suggest to use branches for big new features or large refactorings that might affect the entire software. Small bugfixes or really small features, that don't affect other parts might be developed on the trunk.

But the main uneasiness you seem to have might be resolved by actually using two trunks. One for the current development/testing version and one for the current stable version. Then you can merge the changes from development to stable before deploying them. In the end this is more or less like another branch common to all developers.

Fortunately subversion lets you do any of this without any problems.

The best source for more information might be the SVN Book

nfechner
Thanks, I guess my uneasyness is that it just seems a lot more complex then CVS for being able to commit files but not have them released to production I guess its the merging and keeping track of all the branches.
dan.codes
+1  A: 

we do the following and are very happy with it:

  • small features and bugfixes (that take less than about two days) are made on the trunk. the trunk should always be stable enough to be "releaseable" in less than one week.
  • more complex features and bugfixes are implemented on feature branches and are later reintegrated into trunk.
  • every build (we have a build server) gets a tag containing its version number.
  • once we get closer to a release, a release (or bugfix) branch is created from one of the latest tags. that way new features for the next release can already be committed on the trunk, but only features (and bugfixes) for the current release will be merged to the release-branch.

i have a projects folder into which i checkout the trunk, the last few release-branches and the feature branch(es) i'm currently working on. that way i can easily commit and merge between different branches.

two more helpful rules:

  • create bugfixes on the trunk and merge them to the release branches, not the other way around. otherwise you can forget to merge bugfixes to the trunk, which would make already fixed bugs pop up in the next release again.
  • weekly merge all changes on the trunk to your feature branches to prevent the two branches from drifting too far apart. if you let weeks or months pass before trying to reintegrate the feature branch, you might have to spend days or weeks to resolve all the conflicts. that won't happen if you merge weekly from the trunk to the feature branches.
stmax
So all small features and bug fixes done on trunk, The more complex ones get their own branch. So you have to switch between working copies if you want to work on just the trunk?Then when you build you create a tag with its version number, is your build server like staging? because you say then when you get get close to release a branch is created from one of the latest tags. Wouldn't it have to be the latest tag if the only tags you have are the most builds? It just seems like you have to jump around to all these different branches, it must not be as confusing as I am making it.
dan.codes
i never switch (in sense of "svn switch") between working copies, instead i checkout multiple branches. if i was working on a "calc" project, my folder would look like this:\projects\calc-trunk\projects\calc-1.0-release\projects\calc-1.1-release\projects\calc-complexnumbers-featurethat way i can work on each of the four branches, commit/update and merge between them.. i think that's as easy as it gets :)
stmax
concerning the build server - no this has nothing to do with a staging server. i should have said "continuous integration server" instead. whenever someone commits something, the build server automatically downloads the sources, compiles them and creates a tag with a new version number. of course this is optional for you. you can as well create tags manually and you don't have to create them for every single build.
stmax
I see what you are saying about the way you checkout the branches, I guess my issue is that if we are working on web applications and having these separate folders would mean I would have to switch at the least my virtual host config to setup the correct document root to go back and forth through the different projects and be able to view the site on my browser. And then also in my IDE I could have the project folder with the branches, trunk and what not and navigate between them?So if there are a bunch of releases you have like 100 release branches in your project folder?
dan.codes
I guess I didn't mean switching projects, but switching branches for the virtual host.
dan.codes
i don't have much experience with web projects, but i guess you could configure one virtual host for each branch? that probably depends on your set up.. if every developer runs it in his own IDE, or if you have a central (staging) server for all developers.
stmax
concerning "100 release branches in my project folder" - normally i only keep the last 2 or 3 release branches in my projects folder and delete the older ones. normally we stop maintaining releases that are older and experience has shown that the older a release is, the fewer bugfixes it needs. so you can just delete it from your harddisk and in the seldom case that you'll need it again, you just check it out again.
stmax
Thanks for all your advice!
dan.codes
A: 

There are two schools of thought for working with SVN (and most other centralized VCS):

  1. Stable Trunk - The trunk is where all of your good stable code is. Only safe "single work-unit" changes are done to the trunk. All of your development is done in branches and then merged to the trunk. When it is release time, you tag from the trunk.

  2. Unstable Trunk - The trunk is your "bleeding edge". All the new stuff gets committed to the trunk. When your work starts to gel into a release, you make a branch where you can work on stabilizing and polishing everything. You'll end up with a branch for each release (branches/v1.0, branches/v1.1, etc). You tag from the release branch when it is ready.

Notes about Model #1:

  • People can work in branches without stomping on each other.
  • You can divide the unstable development work up as you see fit, even one branch per developer.
  • You can have hierarchical branches, with quality gates between them. Example: Joe commits unstable stuff to his private branch, when Joe is happy with his work, it gets merged to the team-level branch, which gets tested more formally, and then it is merged to the trunk with the fully-tested work from other teams.
  • This means a lot of merging, in both directions. Stuff gets pushed up to the trunk. Trunk changes need to be propagated down to the branches.
  • Prior to SVN's merge tracking features, this was really hard to do.

Notes about Model #2:

  • The development work is more collaborative. It discourages people from working for a too long in isolation, then dropping a bomb onto the codebase.
  • There will be a lot of broken builds, unless you enforce some discipline with pre-commit testing.
  • It encourages keeping the codebase modularized, so you don't have everyone fighting to change the same files in the trunk at the same time.
  • This model makes it easier to manage updates to older and newer releases (e.g. you are releasing bugfixes for both v1.x and v2.x).
  • For long-running changes, you probably need a branch to work on the feature anyway.

I have seen both models work very well. It depends on how the team works and how the codebase is structured.

msemack
Thanks msemack, very helpful, just trying to consume all of this and make the best decision.
dan.codes