[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

question relating SVN file/directory merges and tree conflicts

From: Rastetter, Martin <martin.rastetter_at_verigy.com>
Date: Tue, 21 Jul 2009 08:17:59 -0500

Hi Subversion Adepts,
In some situations we're at a loss to figure out ourselves how to perform merges between the trunk (or codelines) to branches.
Even after reading following sources thoroughly :-)
and your explanations about merging structural changes http://www.nabble.com/resolving-tree-conflicts-td24459864.html
Consider a tiny trunk like this: (svn version 1.6.3)
svnadmin create /tmp/repo
svn co file:///tmp/repo repo
cd repo; svn mkdir branches tags trunk/foo --parents
cd trunk/foo; echo "main source file" > hallo.c ; echo "main config file" > config ; echo "main doc file" > readme ; svn add *
cd ../.. ; svn ci -m "mainline + basic structure"
cd ..
Then a feature branch of it:
svn copy file:///tmp/repo/trunk file:///tmp/repo/branches/b1m -m "first branch from mainline"
svn co file:///tmp/repo/branches/b1m feat ; cd feat
Now do some reorganisation, refactoring, implementations or modifications of such a kind:
svn mkdir src doc conf
svn mv foo/hallo.c src ; echo "new features added" >> src/hallo.c
svn mv foo/config conf/feature.conf ; echo "feature config replaces main config" > conf/feature.conf
svn mv foo/readme doc/readme.txt ; echo "additional options" >> doc/readme.txt
svn rm foo
svn ci -m "features now developed in branch b1m"
Q1 : despite the files below foo have been marked deleted, they'd been again marked as deleted by "svn rm foo" command
Meanwhile trunk development proceeded:
cd .. ; svn co file:///tmp/repo/trunk main ; cd main
echo "more main config" >> foo/config ; echo "more main code" >> foo/hallo.c ; echo "more main doc" >> foo/readme
svn mv foo/readme .
svn ci -m "mainline changed"
This should now be merged into the branch based on this mainline - but that's quite a bit painful :-)
svn merge ^/trunk --depth infinity --dry-run
--- Merging r2 through r4 into '.':
   C foo
A readme
Summary of conflicts:
  Tree conflicts: 1

Q2: why readme appears here ? - it should be related to doc/readme.txt instead - at least the log reveals their relationship
svn log -v | grep readme ; echo "-----" ; svn log ^/trunk -v | grep readme
   A /branches/b1m/doc/readme.txt (from /branches/b1m/foo/readme:2)
   A /trunk/foo/readme
   D /trunk/foo/readme
   A /trunk/readme (from /trunk/foo/readme:3)
   A /trunk/foo/readme

Looking at this, a merge at this level might not lead to the result the developer is aiming for.
Thus stepping into the directories below ....
cd src
svn merge ^/trunk/foo --depth files --dry-run
--- Merging r2 through r4 into 'hallo.c':
C hallo.c
--- Merging r2 through r4 into '.':
   C config
   C readme
Summary of conflicts:
  Text conflicts: 1
  Tree conflicts: 2

That looks feasible, thus going forward whith the merge ...
svn merge ^/trunk/foo --depth files (perform the file merge on hallo.c eg. via edit & resolve)
svn resolve --accept mine-full --depth files .

Next directory ....
cd ../conf
svn merge ^/trunk/foo --depth files --dry-run
--- Merging r2 through r4 into '.':
   C hallo.c
   C config
   C readme
Summary of conflicts:
  Tree conflicts: 3

Q3: why feature.conf isn't going to be merged with its ancestor config, but encountering a tree conflict instead
Q4: how a new developer becomes informed that conf/feature.conf in this branch originally stems from foo/config from the trunk without reading the complete log
svn log -r4 -v ^/trunk/foo
r4 | mrastett | 2009-07-21 09:49:10 +0200 (Tue, 21 Jul 2009) | 1 line
Changed paths:
   M /trunk/foo/config
   M /trunk/foo/hallo.c
   D /trunk/foo/readme
   A /trunk/readme (from /trunk/foo/readme:3)
svn merge -c4 ^/trunk/foo --depth files --dry-run
--- Merging r4 into '.':
   C hallo.c
   C config
   C readme
Summary of conflicts:
  Tree conflicts: 3

Q5: why running into the same merge results/problems, if focussing only on the changes made in the files in commit 4
Possible consequence could be that a developer who knows about the details about the mainline will remember the rename and perform a file merge between feature.conf and config. Whereas a developer who only want to integrate new data from the trunk has to ask around for advice or receives unwanted files.
svn merge -c4 ^/trunk/foo --depth files --accept theirs-conflict .
--- Merging r4 into '.':
   C hallo.c
   C config
   C readme
Summary of conflicts:
  Tree conflicts: 3

svn status -v
 M 4 3 mrastett .
! C readme
> local delete, incoming delete upon merge
! C hallo.c
> local missing, incoming edit upon merge
! C config
> local missing, incoming edit upon merge
 M 4 3 mrastett feature.conf

But no changes yet. I'd reckoned that I received some files from the trunk automatically, because I asked to merge on conflict with the trunk files.
Q6: why not?
svn resolve --accept theirs-full readme
Resolved conflicted state of 'readme'

svn resolve --accept theirs-full hallo.c
Resolved conflicted state of 'hallo.c'

svn resolve --accept theirs-full config
Resolved conflicted state of 'config'

Although the file feature.conf had been tagged as modified, an I committed it back ...
svn log -v ^/branches
r5 | mrastett | 2009-07-21 13:04:03 +0200 (Tue, 21 Jul 2009) | 1 line
Changed paths:
   M /branches/b1m/conf
   M /branches/b1m/conf/feature.conf
.... it still hasn't been updated, modified or replaced by the trunk data.
svn diff ^/trunk/foo/config_at_4 ^/branches/b1m/conf/feature.conf
Index: config
--- config (.../trunk/foo/config) (revision 4)
+++ config (.../branches/b1m/conf/feature.conf) (revision 5)
@@ -1,2 +1 @@
 main config file
-more main config
Property changes on: config
Added: svn:mergeinfo
   Merged /trunk/foo/feature.conf:r2-4

Q7: why these differences remain?
Looking at the mergeinfo property leads to more questions ....
cd ..
svn pg svn:mergeinfo . -R
conf/feature.conf - /trunk/foo/feature.conf:2-5
conf - /trunk/foo:2-5*
src - /trunk/foo:2-4*
src/hallo.c - /trunk/foo/hallo.c:2-4

Q8: there is no /trunk/foo/feature.conf which could have been merged, it ought to be foo/config instead - where does this come from?
My conjecture is that I make something basically wrong with directory merging. As long as the directory structure and filenames aren't touched, subversion works satisfactory and predictable. But in all other cases it causes quite a lot of efforts to track down which changes in which file belong to another one.
Could you please help me or direct to a resource which describes best practices handling structural changes and merging in subversion.
Kind regards,


To unsubscribe from this discussion, e-mail: [users-unsubscribe_at_subversion.tigris.org].
Received on 2009-07-21 15:29:36 CEST

This is an archived mail posted to the Subversion Users mailing list.