SmartSVN – cleaning up subtree mergeinfo

When merging, a common source of confusion are property-only modifications of various files and/or directories which have not actually been affected by the merged commits. Usually, these are modifications only in the svn:mergeinfo property of the respective entries. Why does that happen and how can this be resolved?

svn:mergeinfo is a Subversion-internal property which stores important information used for merge-tracking. Usually, merges should only performed on the trunk or branch root directory and hence svn:mergeinfo is also present only on the corresponding root directories.

When performing a merge on a sub-directory, or even a single file, svn:mergeinfo will be introduced on these entries as well. This is how troubles start: once introduced, it will remain and will be updated with every new merge, even when performed only on the root directory.
This is the reason, why it’s not recommended to perform subtree merges at all. If you still need subtree merges, you unfortunately have to take these svn:mergeinfo inconveniences into account. If subtree merges have happened by accident, there is following receipt to fix this situation:

  • Be sure to have a clean working copy and update to HEAD.
  • Use Properties|Set or Delete Property on your trunk or branch root directory, select svn:mergeinfo, select Delete Property, keep Depth set to Fully recursive and unselect Include this directory
  • Once finished, all files and sub-directories which previously had svn:mergeinfo attached will show up as modified. From now on there are two ways to go:

  • The hard one: use Properties|Edit to find out which svn:mergeinfo every modified file or directory had before. Manually compare this to the svn:mergeinfo of your root (which should still be present). If revision changes are significant, this indicates that many subtree merges had been performed on the file or directory. Unfortunately, this requires further investigation and you will have to decide whether to record-only merge certain revisions to your root, so these subtree-merges will be tracked in the root’s svn:mergeinfo, too. To get this correct, it may also be necessary to actually merge all other changes outside of the subtree for the record-only revisions. When you are actually faced with this situation, this indicates that subtree merges have been performed by intention and maybe subtree mergeinfo should be kept for the corresponding entry. In this case, you may simply Revert your changes to restore the svn:mergeinfo properties.
  • The easy way: you may not pay attention to what subtree mergeinfo has been removed and risk unexpected conflicts on later merges. If subtree mergeinfo had been introduced to a couple of files by accident and these subtree merges for these files didn’t occur frequently, it will usually be no problem to resolve conflict later (if any at all occur).

In either way, you should be aware that changing respesctively deleting subtree mergeinfo possibly affects Subversion’s merge tracking and hence should be performed with caution. For an in-depth understanding, we recommend to read Paul Burba’s article.

Shelves in SmartSVN

“Shelves” can be helpful in various situations to “save” the changes of your working copy away for later application. In his article, Mark Phippard points out five common scenarios:

  • Interrupt When you have pending changes that are not ready for check in but you need to work on a different task, you can shelve your pending changes to set them aside.
  • Integration When you have pending changes that are not ready for check in but you need to share them with another team member, you can shelve your pending changes and ask your team member to unshelve them.
  • Review When you have pending changes that are ready for check-in and have to be code-reviewed, you can shelve your changes and inform the code reviewer of the shelveset.
  • Backup When you have work in progress that you want to back up, but are not ready to check in, you can shelve your changes to have them preserved on the Team Foundation server.
  • Handoff When you have work in progress that is to be completed by another team member, you can shelve your changes to make a handoff easier.

How shelves in Subversion work

In SVN, shelves can be implemented using short-living branches. To have a better distinction from branches, it’s advisable to create a new top-level directory shelves in your project, which will receive these branches. Also, shelves are usually assigned to individual users, thus introducing one more level of hierarchy to also keep a large amount of shelves manageable easily. Here is an excerpt of SmartSVN’s own repository structure:


/smartsvn
 + branches
   + release-6.6
   ...
 + shelves
   + marc
     + svn-1.7
     ...
   + tom
     + quaqua
     + docking-manager
   ...
 + tags
   + release-6.6.0
   + release-6.6.1
   ...
 + trunk

How to use shelves in SmartSVN

In SmartSVN, you have to configure the tag-branch-layout of your project to recognize shelves as well: use Tag+Branch|Configure Layout and enter branches/*, shelves/*/* in the Branches input field.

Now you can shelve your local changes by Tag+Branch|Add Branch. Enter a reasonable Name for the shelve there, in our example e.g. shelves/marc/log-refactoring. Have the Source set to Working Copy and have Skip local changes selected, to start a clean branch. Select Switch to branch and finally create the shelf using Add Branch.

After the shelf has been created and the working copy has been switched to the shelf, you can commit your local changes using one or more commits, whatever will be appropriate for the purpose of the shelf. You can finally switch back (Modify|Switch) to the trunk resp. the former branch you had been working and start a new task.

To reintegrate your changes into the desired branch, switch to the desired branch, use Modify|Merge and pick the shelf.

Hide menu items in SmartSVN

To hide SmartSVN, the default plug-in hideMenuItems.jar is responsible.
This means, that this tip only works with SmartSVN Professional or Enterprise which can launch plug-ins.
If not already available, SmartSVN will create the file menuItemsToHide.config in its settings directory on application start and fill it with all known menu item IDs:


# Uncomment entries to hide them
#add
#annotate
#apply-patch
#changeset-delete
...

To hide a menu item, you have to open this file in a text editor and remove the leading comment character # in front of the lines containing the ID of the menu item to hide, e.g.:


# Uncomment entries to hide them
#add
#annotate
apply-patch
#changeset-delete
...

Save the file and restart SmartSVN.