When I started writing this mail, it was a question: "Should we bump
the wc format number for 1.5?"
Now I've done some investigation, and I think it's a statement
instead. Despite my ardent desire that we not bump the format number,
we may have to. (There *might* be a way to conditionalize it; search
for "escape hatch" later in this mail to read about that.)
The Problem:
============
In 1.5, we're adding a 'depth' field to the .svn/entries entry spec.
The depth field has a default value of svn_depth_infinity -- if depth
is not mentioned, it is assumed to be infinity. For details on this,
see http://svn.collab.net/repos/svn/trunk/subversion/libsvn_wc/README.
We haven't yet bumped the WC format version number, though. This
means that if a 1.4.x client touches a depth-non-infinity working copy
(created by 1.5), then when the 1.4.x client writes .svn/entries back
out, the entries will all effectively have svn_depth_infinity.
Of course, svn_depth_infinity doesn't mean anything to 1.4, but when
the 1.5 client comes back and reads that working copy, it will now
think that the entries -- in particular, the "this dir" entry -- are
all at depth infinity.
Unfortunately, when a "this dir" entry is at (say) depth=empty, the
.svn/entries file doesn't list all the missing entries. So the 1.5
client won't know that it's missing a bunch of entries! The working
copy is now corrupt.
Here's a demonstration. (I had to jump through some hoops to test
this, because of dual-version shared library interferences; this
included at one point manually un-sharding an FSFS repository. I'm
pretty sure the test results are valid, though, despite my manual
mucking about.)
$ cd wc
$ grep empty .svn/entries
empty
$
# Okay, we're in a working copy created by a 1.5 client, at depth=empty.
# Let's do some stuff in there with a 1.4.5 build.
$ svn --version | grep " version"
svn, version 1.4.5 (dev build)
$ svn up
At revision 2.
$
# Hmmm, I wanted to receive some more entries there. This doesn't
# look promising. And we're probably not still at depth=empty, right?
$ grep empty .svn/entries
$
# Right. We're at depth=infinity now. What entries do we have?
$ cat .svn/entries
8
dir
2
file:///[..long path omitted..]/svn-test-work/repositories/depth_tests-24
file:///[..long path omitted..]/svn-test-work/repositories/depth_tests-24
2007-10-04T01:11:46.667224Z
2
jrandom
svn:special svn:externals svn:needs-lock
c6aa9240-7216-11dc-807e-5370e284c666
$
# That's everything. No more entries. They won't come down no matter
# how many times I run update:
$ svn up
At revision 2.
$
# Okay, what happens if I try again with a 1.5 client this time?
$ svn --version | grep " version"
svn, version 1.5.0 (dev build)
$ svn up
At revision 2.
$ svn up --depth=infinity
At revision 2.
$
# Uh-oh. Even 1.5 can't get the missing entries, because it now
# thinks the directory is at depth=infinity! Let's see how it would
# behave if it knew the working copy were at depth=empty, by trying
# the same command in a duplicate working copy I saved, one that was
# never touched by 1.4.x:
$ cd ../wc2
$ grep empty .svn/entries
empty
$ svn up --depth=infinity
A A
A A/B
A A/B/lambda
A A/B/E
A A/B/E/alpha
A A/B/E/beta
A A/B/F
A A/mu
A A/C
A A/D
A A/D/gamma
A A/D/G
A A/D/G/pi
A A/D/G/rho
A A/D/G/tau
A A/D/H
A A/D/H/chi
A A/D/H/omega
A A/D/H/psi
A iota
Fetching external item into 'A/C/D_ext'
A A/C/D_ext/gamma
A A/C/D_ext/G
A A/C/D_ext/G/pi
A A/C/D_ext/G/rho
A A/C/D_ext/G/tau
A A/C/D_ext/H
A A/C/D_ext/H/chi
A A/C/D_ext/H/omega
A A/C/D_ext/H/psi
Updated external to revision 2.
Updated to revision 2.
$
# Yup, there's everyone.
Conclusion:
===========
As you can see, letting a 1.4.x client touch a depth=empty directory
even once is dangerousbadnastysucksuckevilevilevil. I didn't have
time to test whether the same would be true for other non-infinity
depths (there are reasons why it might or might not).
The easy answer is to just bump the format number, so the 1.4.x client
errors out the moment it tries to do anything in the working copy.
Other Conclusion:
=================
A somewhat better answer would be the following escape hatch: only
bump a particular working copy directory's format number when the 1.5
client is actually writing out a depth other than infinity. That way,
only those who actually use the sparse directories features would pay
the no-downgrading price.
I have no idea how hard this would be. I'm not sure we always *know*
the depth at the time we create the working copy administrative area,
and if we later go back and rewrite the format number, I'm worried
about creating race conditions. It might be better to be hard-nosed
but correct, than forgiving but corruptible.
Thoughts? Should we just bump it?
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Thu Oct 4 08:07:56 2007