Need help / advice on using branches and merging back to trunk
My question is, when merging as per the procedure below, is the last step of the procedure "folding the branch back into trunk" the proper way to do this, in a best-practices scenario?
I've been using svn for many years now. In my personal projects, I always hack away happily on trunk without second-thoughts and having versioning in a single-line linear fashion has been close to perfect for a long time. Simple and efficient. All was bliss, until the day I wanted more control over 3rd party libraries.
Today, I am on a project that I feel has outgrown the hack-straight-from-trunk approach. I have multpiple 3rd party libraries, some that change weekly, and I really need more control on what goes in. I need the ability to view specific changesets between 3rd party lib version and track changes I made to specific libraries. I have seen a few times a codebase get very confusing and hard to bring back in workable state with inexperienced buildmaster, I cannot afford time-wise to go wrong here.
So I looked into vendor branching, read a few articles here and there. I have the great 'Version Control with Subversion' book, but the examples I see are sometimes contradictary in their approach, and I would like to make sense of 'branching'. I was about to follow the approach given on this post by Evan Weaver.
I laid out the procedure below, my concern is in the last section "Folding the branch into trunk". It seems buildmasters I worked with in the past usually "merged" the branches changeset onto trunk, and I don't think branches were even deleted. Is this a proper approach?
Creating the Branch
1 - Note the current head revision:
svn info svn://server.com/svn/repository/trunk | grep Revision
2 - Make a clean, remote copy of trunk into the branches folder. Name it something. We’ll call it your_branch, replacing HEAD_REVISION with the revision number you noted in step 1.:
svn cp svn://server.com/svn/repository/trunk \
svn://server.com/svn/repository/branches/your_branch \
-m "Branching from trunk to your_branch at HEAD_REVISION"
3 - switch your local checkout to point to the new branch (this will not overwrite your changes):
svn switch --relocate \
svn://server.com/svn/repository/trunk \
svn://server.com/svn/repository/branches/your_branch
4 - Check that your local checkout is definitely now your_branch, and that you can update ok:
svn info | grep URL
svn up
5 - Commit your new changes if necessary.
Updating the branch
You’ve been developing for a while on your_branch, and so have other people on trunk, and now you have to add their changes to yo开发者_运维问答ur_branch.
1 - First, update your branch checkout and commit any outstanding changes.
2 - Search the Subversion log to see at what revision number you last merged the changes (or when the original branch was made, if you’ve never merged). This is critical for making a successful merge:
svn log --limit 500 | grep -B 3 your_branch
3 - Also note the current head revision:
svn info svn://server.com/svn/repository/trunk | grep Revision
4 - Merge the difference of the last merged revision on trunk and the head revision on trunk into the your_branch working copy, replacing LAST_MERGED_REVISION with the revision number noted in step 2 and HEAD_REVISION with the revision number noted in step 3:
svn merge -r LAST_MERGED_REVISION:HEAD_REVISION \
svn://server.com/svn/repository/trunk .
5.a - Look for errors in the output. Could all files be found? Did things get deleted that shouldn’t have been? Maybe you did it wrong. If you need to revert, run svn revert -R
5.b - If things seem ok in 5.a, check for conflicts, resolve any found conflicts:
svn status | egrep '^C|^.C'
6 - Commit the merge, replacing COMMAND with the exact command contents from step 4.:
svn ci -m "Merged changes from trunk to your_branch: COMMAND"
Folding the branch back into trunk
Hey, your_branch is done. Now it has to become trunk.
1 - First, follow every step in the previous section (“updating the branch”) so that your_branch is in sync with any recent changes on trunk.
2 - Delete trunk completely:
svn del svn://server.com/svn/repository/trunk
3 - Move your_branch onto the old trunk location:
svn mv svn://server.com/svn/repository/branches/your_branch \
svn://server.com/svn/repository/trunk
4 - Relocate your working copy back to trunk:
svn switch --relocate \
svn://server.com/svn/repository/branches/your_branch \
svn://server.com/svn/repository/trunk
Done!
Please, any advice, comments or feedback on this procedure is appreciated.
If you haven't already done so, I'd suggest your read the branching + merging section here.
The post you've referenced is quite old (August 2007) and out of date. As of subversion 1.5 (June 2008), merge tracking has improved a lot (you can create branches and perform merges and subversion actually tracks which revisions have already been merged in from the trunk for you). This has been improved further in subversion 1.6 (March 2009).
I particularly dislike this suggestion
2 - Delete trunk completely
svn del svn://server.com/svn/repository/trunk
As a way of managing the trunk. This seems somewhat error prone at best (what happens if two feature branches want to merge back at the same time). I tend to share the view of the most recent comment on the post.
Instead, you can perform a 'reintegrate' merge to merge back from your branch into the trunk when you're ready to do so. This applies the relevant changesets from your branch to the trunk.
svn switch --relocate \ svn://server.com/svn/repository/trunk \ svn://server.com/svn/repository/branches/your_branch
--relocate option is to switch to another repo. New branch is a copy of trunk so do switch.
Just do:
svn switch ^/branches/your_branch
svn info | grep URL svn up
This update most of the time will do nothing.
svn merge -r LAST_MERGED_REVISION:HEAD_REVISION \ svn://server.com/svn/repository/trunk .
Most of the time I use TortoiseSVN but try only:
svn merge ^/trunk .
Try if this will work, it should. About merge tracking, newer SVN uses merge-info property so most of the time it should know what to merge. It there are problem Your approach should work well.
- ^/ is repozitory relative url.
- svn info ^/ to try if it is available in your's svn version (You should be in svn folder)
Part with deleting branch scares me...
Try:
# note that your branch should be up-to date (resolve most of conflicts early on branch) svn switch ^/trunk svn merge --reintegrate ^/branches/your_branch .
resolve conflicts ;)
svn commit -m "reintegrated your_branch" svn delete ^/branches/your_branch
Most of the time this is better to remove this branch if you do not know how to deal with it (it is not so easy so better is to delete it and create new).
Also Beware of changing names/relocating files that you change in other branch/trunk. This will lead you to tree conflicts. Free to do it if there are no changes in other branches.
精彩评论