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

Re: [PATCH] Allow copy files that already copied

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: 2005-12-13 15:38:04 CET

Molle Bestefich wrote:
> Karl Fogel wrote:
>
>>I understand that this might make certain operations easier, but I
>>think we need solid theoretical grounding for any such change. Being
>>convenient (in some circumstances) is not the same as being correct.
>
> OTOH, it is ever so unambiguous from a user's POV. The rule would be
> that you can rename/copy+delete files locally all you want, and once
> you commit, the repo will reflect the files moved/copied as per the
> time you do the commit. Easy to understand.

That's not a precise enough description, but I accept that it could probably be
fairly simple and easy to understand.

> Also there's nothing technically hindering this functionality, so
> there's no good reason to disallow it.
[...]

You know, I'm really persuaded by Molle's arguments about how it would make
sense and save a lot of trouble for users, and I think we can come up with a
clean and logical specification for it.

First, note the two major approaches:

1) Make the second copy/move refer to the source of the first one.

2) Make the second copy/move refer to the intermediate URL that does not yet
exist (at least not with the required content) in the repository.

Approach (1) makes the behaviour just an issue of user-interface semantics on
the client, and this is what I will consider here.

Approach (2) requires the server to support copies from the current revision.
This is also worth considering, as there is a chance that it may be easy
(already there) and well-defined.

Examine this "Rabbinic Commentary" from subversion/libsvn_wc/copy.c:

> Q: Why can't we 'svn cp' something that we just copied?
> i.e. 'svn cp foo foo2; svn cp foo2 foo3"
>
> A: It leads to inconsistencies.
>
> In the example above, foo2 has no associated repository URL,
> because it hasn't been committed yet. But suppose foo3 simply
> inherited foo's URL (i.e. foo3 'pointed' to foo as a copy
> ancestor by virtue of transitivity.)
>
> For one, this is not what the user would expect. That's
> certainly not what the user typed!

On the contrary, the user gets an exact copy of the file and user properties
that he/she asked for; only a piece of system meta-data differs. Making that
acceptable is simply a matter of client education. As well as explaining it in
the book and the help, we could issue a warning or information message saying
something like "The copy source will be recorded as '%s' because the specified
source '%s' is not yet committed".

> Second, suppose that the
> user did a commit between the two 'svn cp' commands. Now foo3
> really *would* point to foo2, but without that commit, it
> pointed to foo. Ugly inconsistency, and the user has no idea
> that foo3's ancestor would be different in each case.

The "no idea" was solved above. The "inconsistency" is really not much of a
problem. There are plenty of situations where an intermediate commit affects
the result of a local operation, e.g.

   svn rm dir
   svn cp dir dir2

succeeds whereas, with an intermediate commit, it would fail. (Maybe the
current success is a bug.) There are also already cases where an intermediate
commit can change the committed result of a subsequent operation in terms of
metadata, ancestry, etc.

   svn cp file-with-local-changes foo2
   locally change foo2
   svn commit

This would record the two sets of changes to foo2 separably if an intermediate
commit were made, but as a single set of changes otherwise.

These situations can be called "ugly", but really they are just natural
consequences of the process and I don't imagine they really cause special
problems for users.

> And even if somehow we *could* make foo3 point to foo2 before
> foo2 existed in the repository... what's to prevent a user from
> committing foo3 first? That would break.

This could be handled. Here's one way: write the "copyfrom" source as "foo2"
in the WC initially, and at commit time see whether "foo2" is available (in the
repository or in the commit) and, if not, then follow the copyfrom source back
a step until reaching an item that is available. ("Yuck! What indeterminism!"
you cry.) Here's another way: disallow the commit if the copyfrom source isn't
available in it. That is analogous to what we may well do for true renames:
disallow a commit of one half of the rename. (In fact, we probably ought to
start doing that now, to move closer towards true rename semantics.)

OK, I haven't presented a specification or examined all the avenues, but I
think this could well be done.

- Julian

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Dec 13 15:41:14 2005

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