On 19/6/02 5:24 PM, "Ben Collins-Sussman" <sussman@collab.net> wrote:
> And we *don't*
> allow something to be copied twice. In other words:
>
> svn cp A B
> svn cp B C
>
> is illegal, and needs to be prevented by libsvn_wc...
I'm not sure I agree with this as a long term design decision. As a short
term "we're not supporting this for 1.0" maybe, but not long term.
> Here's a comment from our code, at the bottom of libsvn_wc/copy.c:
>
> /*
> Rabbinic Commentary
>
>
> 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.)
This sounds fine to me.
> For one, this is not what the user would expect. That's
> certainly not what the user typed!
How is it not what the user would expect? You have a current working
copy... You make some changes... Each time you commit you get to add log
information. At the time you do the second 'cp', foo2 has the same log
information as 'foo'. This seems entirely consistent to me. It works
because of transitivity as the comment said.
> 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.
I can see two possible semantics for this solution:
Case 1) (when something is copied it gets its history from the last thing
in the repository with history - transitivity happens at copy time)
(file Foo exists and has history)
svn cp Foo Foo2 (file Foo2 gets its history from Foo)
svn cp Foo2 Foo3 (file Foo3 gets its history from Foo as Foo2 hasn't been
committed - As far as the entries file is concerned, foo3 might as well have
been copied from foo.)
svn commit Foo2 (foo2 is committed with reference to foo's history. Foo3
still references the history of foo)
svn commit Foo3 (foo3 is committed with reference to foo's history - this
is the history that foo2 had when foo3 is copied.
Note that it doesn't matter which order things are committed - both foo2 and
foo3 reference the history of foo, the only history that existed when they
were created.
Case 2) (when something is copied the working copy stores a ref to the
thing it was copied from, that ref is resolved at commit time - transitivity
happens at commit time)
Example I)
(file Foo exists and has history)
svn cp Foo Foo2 (file Foo2 gets its history from Foo)
svn cp Foo2 Foo3 (file Foo3 gets its history from Foo2, even though foo2
only exists in the working copy)
svn commit Foo2 (file Foo2 gets committed with a reference to the history in
Foo. Nothing changes WRT Foo3.)
svn commit Foo3 (file Foo3 gets committed. As it is being committed, the
client notices that Foo2 has been committed and so takes its history from
foo2.)
Example II)
(file Foo exists and has history)
svn cp Foo Foo2 (file Foo2 gets its history from Foo)
svn cp Foo2 Foo3 (file Foo3 gets its history from Foo2, even though foo2
only exists in the working copy)
svn commit Foo3 (file Foo3 gets committed. As it is being committed, the
client notices that it was copied from Foo2, which is an uncommitted copy of
Foo. The client does the transitivity and commits with a reference to the
history in Foo.)
svn commit Foo2 (file Foo2 gets committed with a reference to the history in
Foo. Nothing changes WRT Foo3.)
> 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.
All your objections refer to case 2). While I think it could be made to
work, I agree with you that it is ugly. I think that case 1) is viable. If
you say that 'svn cp' copies the last committed history at copy time, then
everything is consistent.
And I certainly prefer to this to "you can't copy things more than once".
The failure of "svn mv a b; svn mv b c" is annoying - I've already hit this.
More annoying is that I know that I could replace the pair with a single
"svn mv a c" if I could just remember how to revert the first mv that you've
already done... But reverting mv's is not trivial. You have to revert both
source and target of the move. And you have to delete the copy (see the
example below). I think adding the ability to move twice is very useful in
this situation and I think the problems you're pointing out only exist with
one of the possible sets of semantics.
Later,
\x/ill :-}
E.g (trying to revert a mv):
% mkdir svntest
[will@BATFISH:~:Thu 20, 9:20PM]
% cd svntest
[will@BATFISH:~/svntest:Thu 20, 9:20PM]
% svnadmin create repos
[will@BATFISH:~/svntest:Thu 20, 9:21PM]
% svn co file://`pwd`/repos -d root
Checked out revision 0.
[will@BATFISH:~/svntest:Thu 20, 9:21PM]
% cd root
[will@BATFISH:~/svntest/root:Thu 20, 9:21PM]
% ls
[will@BATFISH:~/svntest/root:Thu 20, 9:21PM]
% touch a
% svn add a
A a
[will@BATFISH:~/svntest/root:Thu 20, 9:22PM]
% svn commit a -m ""
Adding a
Transmitting file data .
Committed revision 1.
[will@BATFISH:~/svntest/root:Thu 20, 9:22PM]
% svn mv a b
A b
D a
[will@BATFISH:~/svntest/root:Thu 20, 9:22PM]
% ls -l
total 0
-rw-r--r-- 1 will staff 0 Jun 20 21:22 b
[will@BATFISH:~/svntest/root:Thu 20, 9:22PM]
% svn revert b
Reverted b
[will@BATFISH:~/svntest/root:Thu 20, 9:22PM]
% ls -la
total 0
drwxr-xr-x 5 will staff 126 Jun 20 21:22 .
drwxr-xr-x 4 will staff 92 Jun 20 21:21 ..
drwxr-xr-x 12 will staff 364 Jun 20 21:22 .svn
-rw-r--r-- 1 will staff 0 Jun 20 21:22 b
[will@BATFISH:~/svntest/root:Thu 20, 9:22PM]
% svn revert a
Reverted a
[will@BATFISH:~/svntest/root:Thu 20, 9:22PM]
% ls -la
total 0
drwxr-xr-x 5 will staff 126 Jun 20 21:22 .
drwxr-xr-x 4 will staff 92 Jun 20 21:21 ..
drwxr-xr-x 12 will staff 364 Jun 20 21:22 .svn
-rw-r--r-- 1 will staff 0 Jun 20 21:22 a
-rw-r--r-- 1 will staff 0 Jun 20 21:22 b
[will@BATFISH:~/svntest/root:Thu 20, 9:22PM]
% svn st
? ./b
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Jun 21 03:33:50 2002