views:

729

answers:

4

We have several large subprojects inside our main SVN project root.
I commit and merge only my subproject when working with our release branches, mainly because it's faster.

However, a colleague pointed out this reference to merging subdirectories in Version Control with Subversion (a.k.a "The SVN Book"):

Unfortunately, this is the extent of the warning. The linked section does not give an explanation either.

Is committing and merging SVN subdirectories harmful for release branches?
What about short-lived feature branches?

+12  A: 

One possible explanation is that you could forget parts of a change set.

If the change sets that you are merging cover files that are outside the subdirectory that you have checked out, then there is always the possibility that you will forget to merge those files.

For example, if you have a commit like this on trunk:

r5 | rich | 2009-04-16 22:22:46 +0200 (Thu, 16 Apr 2009) | 2 lines
Changed paths:
   M /trunk/subdir1/main.c
   M /trunk/subdir2/main.c

Change some stuff

And you then have a checkout of subdir1 from your branch "stable", then you could merge the change set r5 like this:

$ svn co http://example.com/svn/branches/stable/subdir1
$ cd subdir1
$ svn merge -c 5 http://example.com/svn/trunk/subdir1 .
--- Merging r5 into '.':
U    main.c
$ svn ci -m"Merged r5 from trunk"

But this will only merge half of revision 5. Worse still, if you go back and look at the log, it will now show this:

$ svn log -g http://example.com/svn/
...
------------------------------------------------------------------------
r5 | rich | 2009-04-16 22:22:46 +0200 (Thu, 16 Apr 2009) | 2 lines
Changed paths:
   M /trunk/subdir1/main.c
   M /trunk/subdir2/main.c
Merged via: r6

Change some stuff

So it looks like you've merged the whole commit, when in fact you have only merged some of it. Of course r6 does show that only 1 file has changed on the stable branch.

------------------------------------------------------------------------
r6 | rich | 2009-04-16 22:28:16 +0200 (Thu, 16 Apr 2009) | 1 line
Changed paths:
   M /branches/stable/subdir2
   M /branches/stable/subdir2/main.c

Merge revision 5 from trunk

Someone has to remember, or notice, that only part of the change set got merged and the rest needs doing. Not using subdirectory merges avoids this problem.

There are times when you really don't want to merge all of a previous commit, and the above scenario is exactly what you intended to do. In that case, it is probably best to add a good commit message describing your intentions.

rq
+1 - Great answer and example
Gary.Ray
+1  A: 

Committing should not have a problem, but in merges SVN tracks what is and is not merged.

Therefore I assume you want to merge at the root to simplify future merges (in respect to the data set size being compared by SVN).

Simeon Pilgrim
+1  A: 

For subversion versions prior to 1.5, merging subdirectories made later merges of the rest of the directory tree really complicated. If you merged a directory, svn simply applied all the changes made in that directory to the other branch. If you had already merged a subdirectory and then tried to merge the main directory, all the changes in the subdirectory were already in the target branch (since you merged them before). Svn now didn't know that these changes were from a previous merge, it just saw that there were things "in the way" when it tried to merge the subdirectory, resulting in lots of conflicts.

To avoid this you would have had to take care to only merge the directories that you hadn't merged before, making the whole process much more complicated. You had to remember exactly which revisions of which subdirectories you already had merged and only apply the remaining changes of the remaining directories/revisions. This can get confusing. Always merging the whole branch made this much easier. Current versions of subversion keep track of previous merges internally, so that these problems can be avoided.

Committing subdirectories is no problem. For svn this is just a normal, global revision of the repository. In that revision there will be only changes in one subdirectory, but for svn it's still a new version of the whole repository, just like any other commit.

sth
In svn 1.5+ this is not actually the case. Merging a subdirectory, then merging the rest of the same commit from the root does not "re-merge" the stuff already merged in the subdirectory causing a conflict. The svn:mergeinfo property prevents that from happening.
rq
Glad to hear that. It really made subversions merging unnecessarily and annoyingly complex, to the point of uselessness.
sth
+3  A: 

Another reason for this could be that merging only to the root limits the number of svn:mergeinfo properties that are going to be set on the folders/files in your repository.

LeonZandman
Your answer is more in the spirit of my question, thanks.My gut feel is that since our subprojects are only one level deep, setting mergeinfo on one of those would still be reasonable.
mskfisher