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

Stage 1 of true rename support.

From: <kfogel_at_collab.net>
Date: 2005-05-20 19:17:40 CEST

History of the problem:

Subversion's implementation of renames is problematic. We implement
'svn rename foo bar' as 'svn copy foo bar; svn delete foo'. This is
speaking loosely; we don't actually turn one client operation into
two, of course. But the effect is the same. In the repository, a
rename looks like two events that happen as part of one commit: a copy
of SRC to DST, and a removal of SRC.

The reason we do things this way is, well, stupid. Basically, we let
a detail of working copy implementation impose itself on core
Subversion. The motivating scenario was this:

   $ svn mv foo bar
   $ svn ci -m "Committing only one side of a rename." bar

(Could just as easily be 'foo' instead of 'bar' in the commit.)

We thought, "Well, if we just treat rename as copy+delete, then the
above scenario works consistently, no matter whether the user
specifies both SRC and DST or just one." Of course, this solution
makes it difficult to distinguish between renames and copies/deletes
in the repository, and it loses object identity (!). Somehow we
thought that was okay at the time. I don't know what we were smoking.

I was one of the advocates of this line of thinking, perhaps the
principal advocate, and I hereby recant. I was wrong. I was so
wrong. Honey, can you ever forgive me for what I did? Can't we make
this work, somehow?

A Multi-Staged Solution:

Fixing rename should happen in stages, because it involves several
entirely separable tasks. The stages I have in mind are:

   1. Implement true renames in the repository. That is, implement
      svn_fs_rename() and whatever associated machinery goes along
      with it, and make 'svn rename URL1 URL2' use it.

      Search in issue #898 for the word "subtle", and you will see a
      big diagram from me and Mike Pilato that shows why implementing
      svn_fs_rename() is not quite as trivial as one might think.


      Commits from a working copy would not use this functionality
      yet. That comes in stage 2. Also, updates would not try to do
      any fancy copying to be efficient; they'd continue to receive a
      'delete' directive and an 'add with history' directive, and get
      the whole new file from the RA layer, just as they do now.
      Making updates more efficient is stage 3.

   2. Support true renames from working copy commits. This means that
      when you do 'svn rename foo bar' in a working copy, foo's entry
      knows this it is a rename source and knows the dest, and bar's
      entry knows it is a rename dest and knows the source.

      If you try to commit just one side of a rename, the client
      library will error articulately, telling you that you must
      commit either all or none of a rename, and pointing you to the
      other side. I think this is appropriate, because by running
      'svn rename' (or the GUI equivalent), the user has expressed
      their intention that this is all one operation. The client
      library should protect the user from contradicting themselves

      This stage would also have to ensure support for the
      rename+modification scenario described in issue #898. As the
      issue says, there really aren't any major complications there,
      it really should just work "out of the box". However, stage 2
      is the first moment where this becomes an issue, so we should

   3. (optional) Support efficient use of working-copy-side data when
      update receives a rename. This is merely a matter of
      performance, not correctness. The idea is that if the RA layer
      transmits a rename from server to client, and the client already
      has the source, then the server can just tell the client to mv
      the source to the dest, and maybe apply a diff if there are
      modifications too.

What To Do Right Now:

I think we should aim to do stage 1 for Subversion 1.3.

That means finding a solution for the repository node-revision ID
problem described in issue #898.

I'm not going to resummarize here the problem described in the issue,
or the solutions outlined there. Anyone who cares about this enough
to enter the discussion, please just look at #898. Note that the
diagram is in the extra-formal style preferred by me and (apparently)
no one else: the path components do not label the directories they
appear in, but rather represent directory *entries* and name the thing
they're pointing to in the next level down. Thus, all rectangular
objects are directories, and the lone file just appears as "(file)".

So, seeing the problem there, does anyone have any thoughts for an
elegant solution?


To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri May 20 19:57:17 2005

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.