Mergeinfo the versioned property svn:mergeinfo
, is the history of merges made into a given file or directory.
When a path has the mergeinfo property set on it, that path is said to have explicit mergeinfo. The path can be a folder or a file.
Normally mergeinfo is set only on the merge target. Subtree mergeinfo occurs:
There are a few cases where a merge won't create or modify mergeinfo:
--ignore-ancestry
optionIf a path doesn't have explicit mergeinfo it can still have inherited mergeinfo if it has a parent (or grandparent, or great-grandparent, etc.) with explicit mergeinfo. The concept of "nearest parent" is not limited to the working copy. When determining the inherited mergeinfo on a path with no explicit mergeinfo, Subversion will first crawl as far up the working copy as it can looking for a parent with explicit mergeinfo. If it reaches the top of the working copy and can't find such a parent, it will then ask the repository about any other parent paths, going as far as the root of the repository if necessary. Only if no inheritable mergeinfo is found in the repository can we finally say the path has no mergeinfo whatsoever. When a path inherits mergeinfo, it does so only from its nearest parent with explicit mergeinfo.
Empty mergeinfo is a svn:mergeinfo
property which has the empty string as a value. It simply means the state of this path is as if nothing was ever merged into it.
At the end of every merge Subversion tries to "consolidate" any redundant subtree mergeinfo. This consolidation process is called elision. Once a merge is completed, Subversion walks the working copy tree rooted at the merge target. If it finds a path with explicit mergeinfo which has a subtree with equivalent explicit mergeinfo, then the subtree's mergeinfo is elided (removed).
Suppose you are working on a feature branch copied from your trunk. During the development process you regularly merge all new changes from trunk to your branch so that the branch stays in "synch" with the work occurring on trunk. When you eventually merge your branch back to trunk, that is called a reflective (or cyclic) merge. Reflective merge has problems:
Subversion already has a technique that does the right thing with reflective merges. It is the one we used prior to 1.5 and is called a 2-URL merge (Reintegrate).
An important thing to point out is that once a branch is reintegrated, it should really be deleted. If more work needs to happen, create it again with a fresh copy. There are two reasons for this:
The new reintegrate option is a shorthanded version of the 2-URL merge plus some safety checks. The checks make sure the working copy is at a single revision, with no switched children, and is not a sparse checkout (i.e. working copy depth is infinity). The most controversial reintegrate check is that the merge source does not have any subtree mergeinfo. Without these checks the 2-URL merge is prone to errors such as using from URL or wrong revision number. More on reintagrate can be found in Subversion merge reintegrate, section "Reintegrate to the Rescue".
Get mergeinfo on all tree, the XML format is needed to create readable output:svn propget svn:mergeinfo --recursive --xml
Delete mergeinfo on tree except root (the merge target)svn propdel --recursive svn:mergeinfo ./*
Subversion merge reintegrate
Subversion 1.5 Mergeinfo - Understanding the Internals
Comments
Alternative for svn propdel --recursive
I noticed that svn propdel --recursive doesn't work if the properties are not set on files at the top level. If you want to delete all svn:mergeinfo from any subtree or file inside the branch, it's best to create a list of files on which to delete the property individually:
svn propget -R svn:mergeinfo --xml ./*
gives you output containing among others this list of files. If you're on unix, you can use grep and sed to massage the output so that all lines looking like
path="path/to/some/file">
will be converted to
svn propdel svn:mergeinfo "path/to/some/file"
following line passes this output directly through bash so that it gets executed immediately:
svn propget -R svn:mergeinfo --xml ./*|grep ' path="'|sed -e 's/ path="/svn propdel svn:mergeinfo "/'|sed -e 's/>$//'|bash
Users of other platforms will have to use some advanced text editor, or install ports of grep and sed for their platform.
Before committing, it's best to verify you didn't miss any properties due to possible weirdness in the xml output, so run
svn propget -R svn:mergeinfo --xml ./*
again to double-check.
Simpler option
If I'm not mistaken this does the same as the above:
svn propdel -R svn:mergeinfo .
svn revert .
Invalid link to CollabNet article on SVN merge reintegrate
Link:
http://blogs.open.collab.net/svn/2008/07/subversion-merg.html
is invalid, use this one instead:
http://blogs.collab.net/subversion/2008/07/subversion-merg/
Updated, thanks for reminding
Updated, thanks for reminding me
As I am not confident with
As I am not confident with blind svn:merge-info property deletion, I have implemented a tool to analyze the current situation on a working copy and remove as much merge revisions as possible from non-root merge-info properties. After additional human checks and controls, the changes on the working copy can be committed.
Here it is: https://github.com/ymartin59/svn-clean-mergeinfo
Do not hesitate to report any issue about its usage to get it improved.