[svk-devel] Double merge?

Sylvain Beucler beuc at beuc.net
Tue Nov 28 09:43:56 EST 2006


Hi,

Yesterday I mentioned on #svk that it seems SVK can "double merge" if
you first pull from //local/repo/trunk, then from //local/repo/.

Actually it depends on how you initiated your repository. Here's how
to reproduce it. Basically I create a SVN repository, start a trunk,
branch it, then mirror the whole to a local SVK repository and work
only on the trunk/, merging changes from upstream.

Question is: is the bug in SVK or in my head? :)

(If you want to try this, BEWARE: I'm removing ~/.svk.
 Rename it first.)


# 1) Unclean: can pull/merge from //local/repo/trunk directly:

 cd ~/tests/svk/
 rm -rf ~/.svk repo repo.svn.wd/ trunk.svk/
 svk depotmap --init
 svnadmin create --fs-type=fsfs repo
 svn co file://`pwd`/repo repo.svn.wd
 cd repo.svn.wd
 ls
 mkdir trunk
 cd trunk/
 echo "1" > README
 cd ..
 svn add trunk/
 svn commit -m import
 cd ..
 svn cp -m "branched" file://`pwd`/repo/trunk file://`pwd`/repo/branch
 svk mirror file://`pwd`/repo/ //mirror/repo/
 svk sync //mirror/repo/
 svk cp -m "local branch" -p //mirror/repo //local/repo
 svk co //local/repo/trunk trunk.svk
 cd trunk.svk/
 svk pull

# Syncing file:///home/me/tests/svk/repo
# Auto-merging (2, 2) /mirror/repo/trunk to /local/repo/trunk (base
#   /mirror/repo/trunk:2).
# Empty merge.
# Syncing //local/repo/trunk(/local/repo/trunk) in
#   /home/me/tests/svk/trunk.svk to 4.

=> !OK, there're 2 merge points now:
   //local/repo and //local/repo/trunk.



Now, by performing the initial sync _after_ creating the local branch,
the relation between //mirror/repo/trunk and //local/mirror/trunk is
cut:

# 2) Cleaner: you can only pull from //local/repo

 cd ~/tests/svk/
 rm -rf ~/.svk repo repo.svn.wd/ trunk.svk/
 svk depotmap --init
 svnadmin create --fs-type=fsfs repo
 svn co file://`pwd`/repo repo.svn.wd
 cd repo.svn.wd
 ls
 mkdir trunk
 cd trunk/
 echo "1" > README
 cd ..
 svn add trunk/
 svn commit -m import
 cd ..
 svn cp -m "branched" file://`pwd`/repo/trunk file://`pwd`/repo/branch
 svk mirror file://`pwd`/repo/ //mirror/repo/
 svk cp -m "local branch" -p //mirror/repo //local/repo
 svk sync //mirror/repo/
 svk pull //local/repo/
 # or: svk smerge -m "merge mirror->local" //mirror/repo //local/repo
 svk co //local/repo/trunk trunk.svk
 cd trunk.svk/
 svk pull

# Syncing //local/repo/trunk(/local/repo/trunk) in
#   /home/me/tests/svk/trunk.svk to 5.

=> OK, no upstream pulling.
   Only one merge point = //local/repo



The problem is that when using the first "unclean" way, it apparently
allows for double merges:

# Create an upstream change:

 cd ~/tests/svk/repo.svn.wd/trunk
 echo "2" >> README
 svn commit -m "change2"

# Let's try a simple pull:

 $ cd ~/tests/svk/trunk.svk
 $ svk pull
 Syncing file:///home/me/tests/svk/repo
 Retrieving log information from 3 to 3
 Committed revision 5 from revision 3.
 Auto-merging (2, 5) /mirror/repo/trunk to /local/repo/trunk (base /mirror/repo/trunk:2).
 U   README
 New merge ticket: cf1c13ef-83d7-4676-b12f-1f778094201f:/trunk:3
 Committed revision 6.
 Syncing //local/repo/trunk(/local/repo/trunk) in /home/me/tests/svk/trunk.svk to 6.
 U   README
 
# There comes the double merge:

 $ svk pull //local/repo
 Auto-merging (3, 5) /mirror/repo to /local/repo (base /mirror/repo:3).
 g   trunk/README
 New merge ticket: cf1c13ef-83d7-4676-b12f-1f778094201f:/:3
 Committed revision 7.
 
# By comparison, here is a normal, empty later merge:

 $ svk pull //local/repo
 Auto-merging (5, 5) /mirror/repo to /local/repo (base /mirror/repo:5).
 Empty merge.

# The svk:merge property shows the double merge:

 $ svk pl -v //local/repo
 Properties on //local/repo:
   svk:merge: cf1c13ef-83d7-4676-b12f-1f778094201f:/:3
   svm:source: file:///home/me/tests/svk/repo!
   svm:uuid: cf1c13ef-83d7-4676-b12f-1f778094201f

 $ svk pl -v //local/repo/trunk
 Properties on //local/repo/trunk:
   svk:merge: cf1c13ef-83d7-4676-b12f-1f778094201f:/trunk:3


You start getting conflicts when sometimes you pull from the working
copy (-> //local/repo/trunk), and sometimes you directly smerge
//mirror/repo //local/repo. Or worse, when you pull _and push_ from
either location. When using 'svk push' and 'svk pull' you don't
specify targets explicitely, so you're likely to miss this issue until
there's a real conflict.


SVK won't allow that with the second "cleaner" method:
 $  svk smerge //mirror/repo/trunk //local/repo/trunk
 Can't find merge base for /mirror/repo/trunk and /local/repo/trunk
while with "unclean":
 $ svk smerge //mirror/repo/trunk //local/repo/trunk
 Auto-merging (2, 2) /mirror/repo/trunk to /local/repo/trunk (base /mirror/repo/trunk:2).
 Empty merge.


I understand that the initial problem is that I probably should create
a local branch of //mirror/repo/trunk, not of //mirror/repo - but this
seemingly inconsistent behavior doesn't feel right.

-- 
Sylvain


More information about the svk-devel mailing list