views:

435

answers:

3

OK, so I am implementing an SVN repository to track development on a Dot Net project. I have defined the repository directory in accordance with the following structure:

\project  
   \trunk  
   \branches  
      \systest  
      \production
   \tags  
      \production_yyyymmdd

Main development is committed to the trunk of the project, and development is performed based on Change Requests (CRs) from the client. For the moment, I am happy to exclude the problem of overlapping CRs (ie a file that is changed by more than on CR). My problem is how to manage the process of migrating only the file changes associated with a single CR from trunk to systest and from systest to production. The promotion process as I have it at the moment is (take migrating from systest to prod as an example):

1) Create a tag "production_yyyymmdd" based on the current production branch (this is used to allow retrieving a particular 'version' if you like)
2) "Update" from production to a local "Migration" location (eg C:\Build\ProjectName)
3) "Merge" selected changes from "systest" to local "Migration" location 4) "Commit" changes back to production

The problem I have is with step 3. How do I tell SVN which files to merge to the Migration location. I do not want to merge all changes from systest to prod (and I might not even want to merge all changes in a particular revision from systest to prod), only changes in specific files.

Edit: I should also clarify that all the repository access is being done from a Windows client. I'm not running commands on the SVN server. (For interest's sake, the SVN server is running on Linux, but that makes no difference to the problem space I believe)

Cheers
Richard

+2  A: 

Here's a cool library/tool that we use: Savana. For each ticket, a developer will create a branch using Savana, and when ready promote this user branch back to trunk. A similar approach could solve the problem you presented: you create a branch for any given task, and merge it back into your main trunk path when the time is right.

joeslice
I assume then that your trunk is the production code base from which you build. Do you have a similar process for test? From what code base do you build to test? trunk?
plancake
Just a comment (not really a criticism -ok well it kind of is)... my issue is not to do with branching of development paths, but management of distinct test and prod code bases for deploy to test and production environments.
plancake
A: 

The "normal" process (i.e. the one my shop follows) is to create a release branch and a tag copy for each release of the product. Any critical issues that occur in production are fixed in the production branch, merged back into the trunk, the product is re-released, and a new tag copy is made.

Meanwhile, non-critical issues are developed against the trunk and rolled up into a periodic release. It is not a standard practice to re-release upon completion of each non-critical issue (CR in your case).

If you want to re-release upon completion of a certain CR, I think you should follow the pattern of feature branching. When you receive a CR that requires a production release, create a feature branch from the production release branch. When the changes are completed, merge the feature branch into the production branch and the trunk and release from the production branch.

You might also consider shortening your release cycle. Frequent releases mitigate the necessity to make changes to released code. The business can often tolerate waiting 6-8 weeks for a change to be implemented but not 6-8 months.

Jamie Ide
Thanks Jamie,Firstly, our release cycle is usually pretty quick... 2-3 weeks between releases... Secondly, these are normally legacy systems with reasonably stable code bases that are not being significantly enhanced, so the overhead of creating a "release" branch for the next version is a bit overkill (for us)... there is normally no parallel development of major features with small CRs and bug fixes (most of what we do is just small CRs and bug fixes) so coding against the trunk is normally fine. I am also trying to automate this to simplify for our devs.Thanks for your suggestions.
plancake
If you're doing 2-3 week release cycles then I'm having a hard time seeing the need to promote releases with that level of granularity. Also, a release branch doesn't imply parallel development -- development is done against a release branch for critical issues that can't wait until the next planned release. For most releases the release branch never gets touched.
Jamie Ide
A: 

Wow, this actually sounds like a nice sane promotion system you've got here :)

In terms of tracking things, the simplest answer I have is to enforce a certain developer discipline - that is, only include 1 CR per commit.

Tortoise has support for the bugtraq properties which can help you here by ensuring that every commit comment includes at least one CR number - it may be a useful hint to tell developers that if they're including >1 tracking number for the commit then they're probably doing it wrong (unless one fix really does do multiple things).

So this will let you merge from trunk to systemtest just with the CR's you want. You can even use the tortoise merge ui to see what revisions in trunk haven't been merged into systemtest yet. But of course now you're going to want to go from systemstest to production with similar granularity - which is what the question is about.

The problem as I see it is that a single revision in systemtest can consist of multiple trunk commits, and you may not want them all in to production just yet.

I wonder if it might not be best to do the merge into production from trunk - instead of coming from systemtest. In theory it should be the same code - you'll be able to track what trunk revisions are in system test and what's in production.

So to be clear with that, you promote a revision from trunk to systemtest, test it, then if it's ok, promote the revision from trunk to production (you may have to start a clean production branch again).

You should be able to write some tools that use mergeinfo to confirm for you which revisions are in systemtest but which aren't in production. And using the bugtraq properties, you should also be able to tell which CR's are completely merged into either branch, and which have revisions still to go.

If you're going to want to start promoting less than a complete trunk commit into test and production, you're in a bit of trouble, especially if picking changes from the same file. You could right click on indiviudal files and merge in directly on the file level (and perhaps manually undo certain changes) but choosing the files and changes will be very manual work and you won't get any help from the tools. Also, you're tracking scripts start to get extremely comples.

Be warned however, that by doing this there's a very real risk of code drift between system test and production. I'd recommend regularly doing a diff between the branches and ensuring that you can account for all the differences. If the two branches have the same revisions merged from trunk, they should be identical, any differences should be because of revisions in test that aren't yet in production, and of course, there should never be a revision in production that isn't in test.

Jim T
Hmm, this is coming closer I think. However I still have an issue if I need to promote 1 CR to test but not another. If there have been 2 CRs commited to the trunk (assuming the CRs did NOT reference the same files - if they do then its an all or nothing deal) and I want to promote the 2nd, but not the first, I need a way to apply just the differences between the trunk at r:CR1 and r:CR2 to systest. I also like the concept of promoting changes from dev to prod but will need to give it more thought. Thanks for your input Jim.
plancake