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

Re: corrupted text-base files not being detected and/or repaired

From: Richard Carlsson <richard.carlsson_at_iar.se>
Date: 2007-06-19 17:43:24 CEST

Hi! Thanks for answering.

Ben Collins-Sussman wrote:
> I think we need more information here. We *do* watch the text-base
> files very carefully for corruption. [...] When that happens, you'll
> see a real text-base checksum error when attempting to commit or
> update, and the operation will abort. You claim that one can
> "manually change a text-base file" and nothing will notice the
> problem, but that's not true. Try it now. I just tried it myself.

Commit, yes. Update, no, not if there have been no new changes.
See the transcript below.

> In any case, your scenario sounds like something more subtle, that
> the text-base file was a correct copy of version X of the file, but
> the .svn/entries file believed the text-base to be version Y? We've
> never heard of such a bug before. How did you come to this
> conclusion? Is there any way to reproduce?

We have preserved the broken working copy, and can send you the
relevant parts if you want to look at it, but we don't know when
or how it got to this state.

> What you're describing isn't a corruption in the text-base file
> itself, but a corruption of the .svn/entries metadata.

It seems that you're right. In either case, there should be some way
of detecting the problem and fixing it automatically.

Below are the details that I could find. I think all this boils down
to a single philosophical question: should you be able to trust that
your working copy is up to date and matching the repository, if both
svn update and svn st -u are quiet?

For performance reasons, I understand that you don't want to
recompute checksums on text-base files for common operations, but
possibly, svn st -u could be an exception, and maybe svn update. And
I suppose it would be reasonable for svn cleanup to both detect and
fix such problems automatically, by default (without the need for an
additional option). Another solution is, of course, to make sure
that all handling of .svn files is atomic and bulletproof. I don't
know if you thought you already had reached this goal, or if it is
at all reachable, but apparently, sometimes things go wrong.

     /Richard

----
- The problem occurred on Windows using Tortoise svn 1.4.3.
- The person who packed the release was not the same person who had
   last modified (and tested) the file that got out of sync; he had
   merely checked out the files.
- The working copy had been around for a couple of months at least,
   and the person who did the packing has normally no reason to look at
   or test those particular files, so we don't know at what point the
   wc was corrupted.
- When packing up the files, he did not use svn export to get fresh
   copies, but simply took them from his working copy.
- The wc contained a file whose contents were not up to date with
   respect to the head revision (and whose text-base file was identical
   to the wc file), but the .svn/entries metadata said that the file
   had a greater revision number than any change; presumably, this
   means that svn never bothers to check any further. Try as I might, I
   could not make svn realize that the file needed refreshing, short of
   deleting the entire directory along with its .svn subdirectory.
- The following transcript shows some weaknesses of the current
   behaviour. It is of course reassuring that svn ci could not be
   tricked into checking in a faulty change, but that was the only
   point where I could trigger an error message.
--------
[richardc@localhost ~]$ svn --version
svn, version 1.4.3 (r23084)
    compiled Mar 30 2007, 06:03:06
[richardc_at_localhost ~]$ svn co http://svn.iar.se/user/svntest/trunk wc
Checked out revision 1.
[richardc@localhost ~]$ cd wc/
[richardc@localhost wc]$ ls    # empty directory
[richardc@localhost wc]$ echo 'Hello,
 > world!' > test.txt
[richardc@localhost wc]$ cat test.txt
Hello,
world!
[richardc@localhost wc]$ svn add test.txt
A         test.txt
[richardc@localhost wc]$ svn ci -m "blah" test.txt
Adding         test.txt
Transmitting file data .
Committed revision 2.
[richardc@localhost wc]$ emacs .svn/text-base/test.txt.svn-base  # mutate
[richardc@localhost wc]$ diff .svn/text-base/test.txt.svn-base test.txt
1c1
< Hell,
---
 > Hello,
[richardc@localhost wc]$ svn st
[richardc@localhost wc]$ svn st -u
Status against revision:      2
[richardc@localhost wc]$ svn update
At revision 2.
[richardc@localhost wc]$ svn diff
[richardc@localhost wc]$ svn cleanup
[richardc@localhost wc]$ diff .svn/text-base/test.txt.svn-base test.txt
1c1
< Hell,
---
 > Hello,
[richardc@localhost wc]$ svn revert test.txt  # does nothing
[richardc@localhost wc]$ diff .svn/text-base/test.txt.svn-base test.txt
1c1
< Hell,
---
 > Hello,
[richardc@localhost wc]$ svn ci  # does nothing
[richardc@localhost wc]$ emacs test.txt  # make a wc modification
[richardc@localhost wc]$ diff .svn/text-base/test.txt.svn-base test.txt
1,2c1,2
< Hell,
< world!
---
 > Hello,
 > word!
[richardc@localhost wc]$ svn st
M      test.txt
[richardc@localhost wc]$ svn st -u
M               2   test.txt
[richardc@localhost wc]$ svn update
At revision 2.
[richardc@localhost wc]$ svn diff
Index: test.txt
===================================================================
--- test.txt    (revision 2)
+++ test.txt    (working copy)
@@ -1,2 +1,2 @@
-Hell,
-world!
+Hello,
+word!
[richardc@localhost wc]$ svn cleanup
[richardc@localhost wc]$ diff .svn/text-base/test.txt.svn-base test.txt
1,2c1,2
< Hell,
< world!
---
 > Hello,
 > word!
[richardc@localhost wc]$ cp test.txt test.txt.bak  # temporary backup
[richardc@localhost wc]$ svn revert test.txt  # quietly installs bad copy
Reverted 'test.txt'
[richardc@localhost wc]$ diff .svn/text-base/test.txt.svn-base test.txt
[richardc@localhost wc]$ cat test.txt
Hell,
world!
[richardc@localhost wc]$ mv test.txt.bak test.txt  # restore backup
[richardc@localhost wc]$ svn st
M      test.txt
[richardc@localhost wc]$ svn st -u
M               2   test.txt
Status against revision:      2
[richardc@localhost wc]$ svn diff    # creates a messed-up patch
Index: test.txt
===================================================================
--- test.txt    (revision 2)
+++ test.txt    (working copy)
@@ -1,2 +1,2 @@
-Hell,
-world!
+Hello,
+word!
[richardc@localhost wc]$ diff .svn/text-base/test.txt.svn-base test.txt
1,2c1,2
< Hell,
< world!
---
 > Hello,
 > word!
[richardc@localhost wc]$ svn ci -m "fubar" test.txt
Sending        test.txt
Transmitting file data .svn: Commit failed (details follow):
svn: Checksum mismatch for 
'/home/richardc/wc/.svn/text-base/test.txt.svn-base'; expected 
'335387a52cfc8f1d3fda510b12dfc200', actual: 
'6f0993c14a57e202d5a8ce3a874929b6'
--------
-- 
// ---------------------------------------------------------------------
Richard Carlsson <Richard.Carlsson@iar.se>                IAR Systems AB
Software Developer                                     http://www.iar.se
  -------------------------------------------------------------------- //
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue Jun 19 17:43:32 2007

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.