Use Case for Path Tokens

Martin von Gagern Martin.vGagern at gmx.net
Wed Aug 20 19:49:13 BST 2008


Hello!

I think I have an interesting use case for the Path Tokens specification 
  from http://bazaar-vcs.org/DraftSpecs/PathTokens.

The general theme is that of a branch derived from a released tarball, 
and a different branch which is a clone of the offifial development 
trunk. While merging the tips of these two would simply be expressed as 
joining all the files with common paths into one, this approach might 
lose rename/move/copy/join operations performed in these branches since 
the time when they diverged, and would probably cause conflicts for 
every file changed in either branch, for lack of a common ancestor.

To take care of this, one might do the following:

bzr branch -r revno:1 release1 common
cd common
bzr merge --join --checkequal -r tag:release1 ../trunk
bzr commit -m "Established common ancestor for both branches"
bzr merge ../release1
bzr merge ../trunk
bzr ci -m "Combined trunk with tarball branch using common ancestor"

This would establish common as the state of the tree shared by both 
branches. The --join operation would indicate path-based joining of 
files from unrelated branches, as discussed in the parallel import 
scenario of the spec. The additional option --checkequal might ensure 
that the files are indeed equal, and report any file present in only one 
of the branches. So the merge --join --checkequal would merge two trees 
with exactly the same files, but with different file IDs.

Afterwards, the merges should propagate changes from both branches to 
the newly linked files. In the end, the changes from both branches 
should be present in the common branch, in a sensible way that allows 
further merges from either branch.

Of course the above command could prove useful enough that you would 
want to implement a syntax to merge a different branch to the current 
one and specify a revision in each branch with same content. This might 
turn the whole thing into a single merge and commit. Still, I think the 
commands above are a good guideline about what the result of such a 
merge should look like.

How should these branches be merged? What should the contents of the 
files look like after the merger, and which of them would contain 
conflicts? Again (like in my mail "Semantics for file copy" I'll send 
along with this one here) I would suggest the following guidline:

For every pair a and b of files with a common ancestor c, after the 
merge a should contain all changes applied to b since c, and b should 
contain all changes applied to a since then. This sounds a lot like a 
normal content merge, but due to the fact that here every file can be 
part of more than one pair, this means changes from possibly more than 
one line of modifications even during a single merge.

I combined the above commands with some construction and testing code, 
and also some more copy/join operations. I formulated the whole thing in 
something resembling a shell script, although I've never run it like 
this, and it might of course contain mistakes. It's rather lenghty, I fear.

I encurage discussion whether this is the behaviour you would expect. 
Additionally, the whole thing might get turned into a test case once 
things are under way.


# First we create a project with three equal sample files in it
bzr init trunk
cd trunk
cat > a <<EOF
one: unchanged
two: unchanged
three: unchanged
four: unchanged
EOF
bzr add
bzr ci -m "initial import"
bzr copy a b
bzr copy a c
bzr ci -m "trunk ready for release"

# Next we release the project, tagging it and creating a tarball
bzr tag release1
bzr export --root=release1 ../release1.tar

# We perform more operations on the files in trunk
sed -i 's/one:.*/one: trunk a/' a
sed -i 's/one:.*/one: trunk b/' b
sed -i 's/one:.*/one: trunk c/' c
bzr ci -m "content modifications one"
bzr copy a d
bzr join --into e b c
sed -i '/:/b;d' e # drop all lines without colon, i.e. conflict markup
bzr resolve e
bzr ci -m "file modifications in trunk"
sed -i 's/two:.*/two: trunk a/' a
sed -i 's/two:.*/two: trunk d/' d
sed -i 's/two:.*/two: trunk e/' e
bzr ci -m "content modifications two"

# Now the interesting files in trunk should look like this
diff -u - d <<EOF
one: trunk a
two: trunk d
three: unchanged
four: unchanged
EOF
diff -u - e <<EOF
one: trunk b
two: trunk e
three: unchanged
four: unchanged
one: trunk c
two: trunk e
three: unchanged
four: unchanged
EOF

# Now we turn the tarball into a branch
cd ..
tar xf release1.tar
cd release1
bzr init .
bzr add

# On this we perform similar operations than on the trunk
sed -i 's/three:.*/three: tarball a/' a
sed -i 's/three:.*/three: tarball b/' b
sed -i 's/three:.*/three: tarball c/' c
bzr ci -m "content modifications three"
bzr copy a f
bzr join --into g b c
sed -i '/:/b;d' g
bzr resolve g
bzr ci -m "file modifications in tarball"
sed -i 's/four:.*/four: tarball a/' a
sed -i 's/four:.*/four: tarball f/' f
sed -i 's/four:.*/four: tarball g/' g
bzr ci -m "content modifications four"

# Now we want to reconcile our two branches
cd ..
bzr branch -r revno:1 release1 common
cd common
bzr merge --join --checkequal -r tag:release1 ../trunk
bzr commit -m "Established common ancestor for both branches"
bzr merge ../release1
bzr merge ../trunk
bzr ci -m "Combined trunk with tarball branch using common ancestor"

# And this is how the common tree should look like in the end.
# Not really strict, as I removed clonflict markup and reordered lines
# in files with conflicts.

# a: in conflict
one: trunk a
two: trunk a
two: trunk d
three: tarball a
four: tarball a
four: tarball f

# b: clean
one: trunk b
two: unchanged
three: tarball b
four: unchanged

# c: clean
one: trunk c
two: unchanged
three: tarball c
four: unchanged

# d: in conflict
one: trunk a
two: trunk d
three: tarball a
four: tarball a
four: tarball f

# e: clean
one: trunk b
two: trunk e
three: tarball b
four: unchanged
one: trunk c
two: trunk e
three: tarball c
four: unchanged

# f: in conflict
one: trunk a
two: trunk a
two: trunk d
three: tarball a
four: tarball f

# g: clean
one: trunk b
two: unchanged
three: tarball b
four: tarball g
one: trunk c
two: unchanged
three: tarball c
four: tarball g

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 260 bytes
Desc: OpenPGP digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20080820/374cf44d/attachment.pgp 


More information about the bazaar mailing list