tags:

views:

1605

answers:

3

I've got a source code tree in subversion with several branches. I've just finished a fairly intense debugging session in an otherwise active branch and now need to merge the changes across to the new branch. The new branch was taken off trunk (which represents released code) recently, after all the development in the old branch (obviously) but before I committed all my debugging. Attempting to svn merge, however, doesn't merge across all the files that were added. It adds some, but not all.

Here's the time line:

  • Branch off trunk to create branch dev1.
  • Code in dev1, modifying files and adding files.
  • Branch off trunk to create branch dev2.
  • Bug fix in dev1, modifying files but not adding files.
  • Merge all changes in dev1 over to dev2.

As expected, there are many changes, including new files, but not all of them. Is it because the range of versions I'm merging from includes the version that made the dev2 branch? Or should I be merging to trunk and then down to dev2?

Edit: All code is fully committed into Subversion. But I think what might be happening is that file additions do not propagate through merges. That is, a prior merge to dev1 added a few files, but a merge from dev1 that encompasses the commit from the prior merge does not include the added files.

But I'm still checking.

A: 

Files that were added to a branch and then changed on the branch don't get added when doing a merge across a number of revisions because subversion is trying to apply a context diff to a file that doesn't exist in the working directory (the new file). You will see a warning from svn stating something like "Skipping missing file blah.c..."

There are two basic ways to deal with this. Commit your branch (this is always a good idea since merging can mess things up sometimes and it's much nicer to simply be able to revert), then merge each specific revision that adds files (one at a time) in order to ensure that the files actually get added to your working directory.

The other option you have is to create empty files (e.g., using the unix touch command) for all the files that were added across the revisions (you can get a list of these files by simply doing the merge with the --dry-run specifier and taking note of all the "Skipping missing file" warnings), then run the merge with your entire revision list (like -r 1023:1040). That will merge the changes into the new empty files and everything should be peachy :)

Jason Coco
I like the "add empty files first" trick. Then it's just one delta with all of the "diff meat" in it. Cool.
Roboprog
+3  A: 

The following statement is not true:

Files that were added to a branch and then changed on the branch don't get added when doing a merge across number of revisions

That would imply merging is totally broken.

When you do the merge, you need to make sure that you do merge the revision that created the file, otherwise you'll get those warnings about no target.

The other thing to watch out for is if you do a merge into a working copy, then decide you're not happy with it and revert everything, the newly added files will still be in the working copy, so if you merge again, the unversioned files will prevent the merge of new files there, so you will miss them. So running "svn status" and removing unversioned files will ensure the merge works properly.

The comment about adding an empty file should not be done, because then the new file has no history of where it came from. In other words, it's not a copy, so "svn log" will not show its history. And finally, if the file were a gigabyte photo, you wouldn't want to merge it into a new file, because then the repository would have two copies of the exact same context. Merging and copying with history saves repository storage (at least until rep-sharing is put in).

Blair Zajac
That makes sense. I think I've got some tricky merges to do... :-(
staticsan
A: 

I have always known svn warnings to be subversion's indication that you screwed up somehow. Then I ran into the above case where I was getting a lot of skipped files on a merge from a branch, but I knew I had the correct paths for the merge. The skipped files were all files that were added and changes on the branch but did not yet exist on trunk.

Then I realized that all of these files already existed, though unversioned, on my working copy of trunk -- I had done a test merge (not a dry run) a week earlier and reverted, but the files never got physically removed by my SVN client. As soon as I deleted them physically from my working copy of trunk the issue went away!

JasonZ