Description

Merges and Moves

A common desire is to refactor source code, especially
in Java-based software projects. Files and directories are
shuffled around and renamed, often causing great disruption
to everyone working on the project. Sounds like a perfect
case to use a branch, doesn't it? Just create a branch,
shuffle things around, then merge the branch back to the
trunk, right?

Alas, this scenario doesn't work so well right now and
is considered one of Subversion's current weak spots. The
problem is that Subversion's update
command isn't as robust as it should be, particularly when
dealing with copy and move operations.

When you use svn copy to duplicate a
file, the repository remembers where the new file came from,
but it fails to transmit that information to the client which
is running svn update or svn
merge. Instead of telling the client, “Copy
that file you already have to this new location,” it
instead sends down an entirely new file. This can lead to
problems, especially because the same thing happens with
renamed files. A lesser-known fact about Subversion is that
it lacks “true renames”—the svn
move command is nothing more than an aggregation
of svn copy and svn
delete.

For example, suppose that while working on your private
branch, you rename integer.c
to whole.c. Effectively you've created
a new file in your branch that is a copy of the original
file, and deleted the original file. Meanwhile, back
on trunk, Sally has committed some
improvements to integer.c. Now you
decide to merge your branch to the trunk:

This doesn't look so bad at first glance, but it's also
probably not what you or Sally expected. The merge operation
has deleted the latest version of
the integer.c file (the one containing
Sally's latest changes), and blindly added your
new whole.c file—which is a
duplicate of the older version
of integer.c. The net effect is that
merging your “rename” to the branch has removed
Sally's recent changes from the latest revision!

This isn't true data loss; Sally's changes are still in
the repository's history, but it may not be immediately
obvious that this has happened. The moral of this story is
that until Subversion improves, be very careful about
merging copies and renames from one branch to
another.