|
Version Control with Subversion - Copying Changes Between Branches - Merge Conflicts
Merge Conflicts
Just like the
svn update
command,
svn merge
applies changes to your working
copy. And therefore it's also capable of creating
conflicts. The conflicts produced by
svn
merge
, however, are sometimes different, and this
section explains those differences.
To begin with, assume that your working copy has no
local edits. When you
svn update
to a
particular revision, the changes sent by the server will
always apply “cleanly” to your working copy.
The server produces the delta by comparing two trees: a
virtual snapshot of your working copy, and the revision tree
you're interested in. Because the left-hand side of the
comparison is exactly equal to what you already have, the
delta is guaranteed to correctly convert your working copy
into the right-hand tree.
But
svn merge
has no such guarantees
and can be much more chaotic: the user can ask the server to
compare
any
two trees at all, even ones
that are unrelated to the working copy! This means there's
large potential for human error. Users will sometimes
compare the wrong two trees, creating a delta that doesn't
apply cleanly.
svn merge
will do its
best to apply as much of the delta as possible, but some
parts may be impossible. Just like the Unix
patch
command sometimes complains about
“failed hunks”,
svn merge
will complain about “skipped targets”:
$ svn merge -r 1288:1351 https://svn.example.com/repos/branch
U foo.c
U bar.c
Skipped missing target: 'baz.c'
U glub.c
C glorb.h
$
In the previous example it might be the case that
baz.c exists in both snapshots of the
branch being compared, and the resulting delta wants to
change the file's contents, but the file doesn't exist in
the working copy. Whatever the case, the
“skipped” message means that the user is most
likely comparing the wrong two trees; they're the classic
sign of driver error. When this happens, it's easy to
recursively revert all the changes created by the merge
(
svn revert --recursive
), delete any
unversioned files or directories left behind after the
revert, and re-run
svn merge
with
different arguments.
Also notice that the previous example shows a conflict
happening on glorb.h . We already
stated that the working copy has no local edits: how can a
conflict possibly happen? Again, because the user can use
svn merge
to define and apply any old
delta to the working copy, that delta may contain textual
changes that don't cleanly apply to a working file, even if
the file has no local modifications.
Another small difference between
svn
update
and
svn merge
are the
names of the full-text files created when a conflict
happens. In
the section called “Resolve Conflicts (Merging Others' Changes)”, we saw
that an update produces files named
filename.mine ,
filename.rOLDREV , and
filename.rNEWREV . When
svn
merge
produces a conflict, though, it creates
three files named filename.working ,
filename.left , and
filename.right . In this case, the
terms “left” and “right” are
describing which side of the double-tree comparison the file
came from. In any case, these differing names will help you
distinguish between conflicts that happened as a result of an
update versus ones that happened as a result of a
merge.
[an error occurred while processing this directive]
|
|