tags:

views:

386

answers:

3

We have a large project with several sub-projects. We're approaching a release of our project, and the new features in one sub-project are not going to be completed before the release as was originally planned. What I'd like to do is move all the changes to that sub project related to the new features into a separate branch to continue work for the next release, but I'm not sure how to best accomplish this.

The situation is basically:

/proj/trunk/A/
/proj/trunk/B/
/proj/trunk/C/

We have revisions a..z checked in since the last release. Revisions d, f, g, and j..n contain work related to a new feature in C which isn't going to be completed in time. Revisions e, h, and q contain unrelated changes in C which need to be in this release. I'd like to create a /proj/branches/new-feature-for-C/ and move changes d, f, g, and j..n there, while keeping e, h, and q in trunk. There is no overlap between changes to be moved to the branch and changes to be kept on the trunk, and none of the changes to be moved to the branch depend on any changes in any other subproject since the last release.

A: 

This doesn't answer your question, but in the future you should develop each of your sub-projects on a different branch to begin with. Only when a sub-project is finished and ready to ship should it be merged into trunk. That way, trunk is always in a shippable state.

The only challenge is if two different sub-projects need to share some of the same new code. Subversion makes that case challenging, but other revision control systems such as Git, Mercurial, and Bazaar make that case easy.

As far as answering your actual question, the following URL explains how to undo a specific revision number:

http://svnbook.red-bean.com/en/1.5/svn-book.html#svn.branchmerge.basicmerging.undo

I guess you could branch your entire trunk. Then, the branch would have all of the sub-projects (both the ones you're shipping and the ones that aren't ready yet). And, you could apply the technique from the link above over and over to trunk for each of the revisions you want to undo. Sounds like it will be tedious and messy, but it should work.

Clint Miller
A: 

There are many ways to set up repos, but the way I usually do it is this.

trunk - always tracks the latest code in development that will definitely get released
branches/R1 - when I do a release, I create a branch for it, and also a tag (see below R1.0). This branch always tracks the latest version of Release 1.x. If I need to go back, I use the tags, below.
branches/Import Tool - when I am working on a standalone feature that may not get released with latest code (e.g., main product is a calendar, import tool may not be ready in time).
tags/R1.0
tags/R1.1 - every time I release an update to a release, I create a tag, so that I can easily revert to that version e.g., if I need to reproduce a bug
tags/R1.2

When I find a bug in the latest code (trunk), I merge it back into the current release branch (e.g., branches/R1) if necessary.

You don't want to create too many branches, as it will cause more work in merging from the main trunk, so keep the number of branches as small as possible.

RedFilter
+5  A: 

This is how I would do it: Copy the trunk to a branch, then reverse merge the change sets.

so if the trunk is at http://svnserver/svn/myrepo/trunk/C and the unwanted change sets are 3, 6 , 9-11

svn copy http://svnserver/svn/myrepo/trunk/C http://svnserver/svn/myrepo/branch/C -m "Branch no completable work"
svn merge -c -3,-6 http://svnserver/svn/myrepo/trunk/C <filepath to root of trunk>
svn merge -r 11:8 http://svnserver/svn/myrepo/trunk/C <filepath to root of trunk>
****CHECK EVERY THING WORKED***
svn commit . -m "Removed some changes that weren't to be finished"

Note that the -r 11:8 is one less than the changeset you want to stop at

Andrew Cox
I've played a bit with doing it this way, but I can't see an easy way to merge it all back into the trunk once the new feature is completed. Because we branched from the head of the trunk, then reverted the unwanted changes on the trunk, there seems to be no good way to pull those changes back in from the branch along with the newer changes to finish feature C, while preserving changes to the trunk unrelated to feature C.
Thomee
what version of subversion are you using? In 1.5+ it should work, though you may want to use the --reintegrate option. Prior to 1.5 I have used the svnmerge.py script with some success.
Andrew Cox
The repository has not been upgraded, so I don't have the 1.5+ merge tracking features. The problem I'm running into (and maybe it's something I'm doing wrong), is that when I'm trying to reintegrate the feature branch, there's nothing to distinguish between the removal of the incomplete feature from the trunk, and other meaningful changes which have happened on the trunk after that. So all the existing work that got copied then removed, stays removed, or I lose the other changes which were made after removing the incomplete feature.
Thomee
Have you tried to (1) re merge the unmerged changes then (2) merge the branch back into the trunk. (1) should get you back to the original + general changes(2) should add the branch back, and as the trunk now has the deleted changes back it should (hopefully) work. Let me know if it works.
Andrew Cox
To clarify, I've been playing with this on a test repo before doing anything on our main repo, so I can try different approaches, and have smaller sets of changes. Your suggestion seems to work, but feels clumsy. I'd initially thought this would require manually going through the list of all the changes twice, once to back it out of the trunk, and a second time to put it all back in. I then realized that to put it back in all I need to do is reverse the one commit where it was all taken out after the branch was copied. It still feels a bit clumsy to me, but should be workable.
Thomee
I agree, that is why 1.5 with its merge tracking is such a godsend :)
Andrew Cox