Somewhat recently, we removed the entry `deleted' attribute, the one
that used to indicate that the deletion of the entry was committed
from this working copy, such that the entry is now at the new revision
(the revision in which it does not exist). I believe we removed the
flag because doing so simplified some entry bookkeeping and made it
easier to map SVN semantics onto DAV. [Could be wrong about the
motivation, someone who remembers more can correct me.]
So now, instead of keeping the entry, but marking it as being at the
new revision and having the `deleted' flag, we just remove the entry.
I believe this can lead to a serious bug, one that we haven't
encountered yet but which will bite us eventually.
To give complete background, I'll describe the way things used to work
with the `deleted' flag, and the way they work now:
Here's an example entries file in summarized format:
".": rev=9
"foo": rev=9
"bar": rev=9
"baz": rev=9
and let's say 9 is the head revision. In the old days, when we used
the `deleted' flag, running
$ svn rm foo
$ svn ci -m "Removed foo."
would result in this entries file:
"." : rev=9
"foo": rev=10, existence=deleted (or "deleted=true", whatever)
"bar": rev=9
"baz": rev=9
But nowadays, the result of that command would simply be
"." : rev=9
"bar": rev=9
"baz": rev=9
The entry for "foo" is gone. Now suppose you run
$ svn update
In the old days, the client would have sent a working copy state
report claiming that "." is at revision 9, while entry "foo" is at rev
10, in which it is deleted. The server, knowing that "foo" doesn't
exist in 10, could remove "foo" from the svn txn (the working copy
reflection) it's building, and thus when the server sent the tree
delta between the txn and revision 10, there would be no mention of
deleting "foo". And the client, seeing that the directory was now at
a revision equal to or greater than the revision of `deleted' entry
"foo", could finally remove the entry altogether.
But these days, the state report never mentions the "foo" exception.
The server builds a txn in which foo:9 still exists, and thus the tree
delta from txn to rev 10 reports the deletion of "foo". Fortunately,
we've changed our client to handle a request to delete a non-existent
entry (just do nothing), so everything works out. We still print out
the deletion, though, which is confusing but hardly a showstopper.
So far so good... except for the fact (are alarm bells going off in
your head yet?) that the client is sending a blatantly inaccurate
state report to the server. The client is implicitly claiming to have
foo:9, when it does not. Can this lead to a problem? Yes, I think
so:
$ svn rm foo
$ svn ci -m "Removed foo."
Next, someone else resurrects the foo:9 line in revision 11. Never
mind the mechanism by which they do this (we may not have one
presently), it's still a perfectly reasonable VC operation and one
which will be supported if it's not already. So in revision 11,
"foo" exists again, and knows that it is related to foo:9 -- that
is, if some client claims to have foo:9, then the server is
justified in sending a diff against foo:9 to create foo:11.
$ svn up
You see the problem -- the update will fail, because there will be no
foo:9 text-base for the incoming delta to use.
I'm not saying that we have to go back to the old way. But the client
must *somehow* send an accurate state report -- must inform the server
that it does not have `foo'. In general, if the server thinks you
have a certain file, then it is allowed to make use of that fact to
transmit less data. If you turn out not to have that file, then
you're hosed. The above scenario is merely the most obvious example,
but it is not the only one (think: copyfrom args).
Principle: "Lying to the server is bad." :-) We need to stop doing it;
what's the best way?
-Karl
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Mar 18 02:58:17 2002