Question

Sometimes when I merge a project from trunk, some files will appear modified (ie., need to be checked in with the merge) even though there is no difference between my version and the trunk. A compare shows they are exactly the same even white spaces are not different.

  • How could this be ? Does it have something to do with mergeinfo ?
  • What are the side-effects of not checking in these files into my branch considering there are no changes...
  • Will it be trouble when I try to merge back to trunk ?
Was it helpful?

Solution

One of the things you may see is a report that a file was updated during the merge even though it was not. This maybe due to the updating of the svn:mergeinfo property on that file or directory.

Normally, only the root directory of the project should have a svn:mergeinfo property on it because you should almost always merge from the root of the project. However, some developers have a habit to merge single files and directories because they know these have been changed. When a developer does that, Subversion starts tracking the merge on those files and directories with their own individual svn:mergeinfo property.

Now, when you do a merge, all of these svn:mergeinfo properties must be updated even if the file itself isn't changed. After all, Subversion STILL has to track that you did a particular merge even if it didn't affect that file in order to be able to track what was and wasn't already merged.

If the svn:mergeinfo is the issue, don't revert the file. Otherwise, Subversion will simply redo the useless merge over and over. You can try to remove the svn:mergeinfo from both the trunk and branch for that particular file, but be careful that you don't lose track of what was merged.

Merging in Subversion is not as cleancut as it should be. Subversion recognizes two different types of merging:

  • Regular merging where you are merging work from trunk into a particular branch.
  • Reintegration merges where work on a branch is merged back into the trunk.

The reintegration concept is needed because your branch contains stuff you've merged from trunk into the branch AND work on that branch that is not in trunk itself. You don't want the stuff you've merged into the branch to be placed once again in trunk, so the reintegration feature copies only the work on the branch back into trunk (it's actually a two way merge). Once this is done, you have to be very careful about merging back to that branch once again.

Why?: All of the changes on that branch have been merged into trunk creating a new trunk revision. If you do a new Subversion trunk to branch merge, Subversion will see that new revision created by the merge, and attempt to remerge all of the changes that new revision contains back into the branch.

To handle this, use the --record-only option of the merge to merge that new revision from trunk back into the branch. Now, when you merge from the trunk back to the branch, that new revision won't be considered for the merge:

$ svn co $REPO/trunk
$ cd trunk
$ svn merge --reintegrate $REPO/branch/1.2    #Two-way Reintegrating branch 1.2 to trunk
$ svn commit -m"Reintegrate 1.2"
commit revision 12345

The merge created revision 12345. This has to be record only back to the branch in order for us to be able to reuse the branch:

$ svn co $REPO/branch/1.2
$ cd 1.2
$ svn merge -c 12345 --record-only $REPO/trunk
$ svn commit -m"Mark Reintegrate Merge as completed"

Recap

  • How could this be ? Does it have something to do with mergeinfo?

Yes it does. You might be able to delete the svn:mergeinfo information from that file from both the trunk and the branch. However, you need to be careful. Or, you can ignore it now that you know it's okay.

  • What are the side-effects of not checking in these files into my branch considering there are no changes...

Subversion will simply try the merge again the next time you merge with each merge taking longer and longer since more revisions must be merged each time.

  • Will it be trouble when I try to merge back to trunk ?

When you merge from the branch to the trunk, you have to use the --reintegrate parameter to prevent the branch from remerging changes back to trunk. The reintegration merge uses only a two-way merge. This basically makes trunk match the branch.

Once this is done, you must be careful about new merges from trunk to the branch.

OTHER TIPS

David was correct in most (not all) aspects of troubles, related to "Merge-Hell". But I want to shed some additional light on some specific details

  1. When you perform ordinary diff, you can compare only content (and some differs may miss some changes due to settings - f.e EOL-style changes, if this change ignored in /mostly GUI/ diff-viewers)
  2. Every object in repository can contain not only content, but also serve as container for non-content data (read about svn: properties, svn:mergeinfo is just one most obvious sample, but every file can contain more custom properties), which also merged (replaced, updated) in the process on merge. svn diff in modified Working Copy after merge (before commit) will show all changes in WC, svn diff between two nodes (mergeset and source of merge) will show all these details too - try it
  3. When you perform subtree merge (merge only part on nested tree) and later perform full-merge (i.e you branched /A/B/C-file, for some reasons merge C-file only and later repeat for /A/B/C-file, last merge remove mergeinfo, contained in C-file)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top