I know this post is long, but I couldn't think of any way to explain
the situation other than to transcribe it. Once you've read it, a
summary would make sense, but not before :-).
This is about a semi-corruption bug: the working copy and repository
can get out-of-sync with each other and not know it. (See issue #3282.)
The question at hand is, how should Subversion behave when it receives
an update to a file that is already schedule-replace? (I realize as I
ask this that it's sort of a tree-conflict issue.)
The right answer, I think, is that:
a) First of all, a schedule-replace file should have .svn-revert
base files instead of .svn-base (obviously), and
b) After being updated, the file should still be schedule-replace,
with its revert-bases still in place, but those bases should
have the new text and new props. In other words, it should be
just as though the user "replaced" the new file.
Does this sound sane?
Now let's look at what actually happens. The following sequence of
commands sets up the scenario:
svn co $repos_url wc1
svn co $repos_url wc2
cd wc1
echo "original foo" > foo
svn add foo
svn propset p v foo
svn ci -m "Create foo, with both text and properties."
cd ..
cd wc2
svn up
echo "change to foo, made in the other wc" > foo
svn ci -m "Change foo from wc2."
cd ..
cd wc1
svn rm foo
echo "replace foo, in original wc" > foo
svn add foo
# Now update, receiving changes (to old foo) on top of the
# schedule-replace (new) foo:
svn up
cd ..
Here's what happens currently:
Right after the replacement, but *before* that final 'svn up' in wc1,
this is the situation in wc1:
$ cat .svn/entries | imagine-fancy-grep-command-for-entry-foo
foo
file
1
replace
2008-09-10T20:24:31.000000Z
2008-09-10T20:24:31.292007Z
1
kfogel
[... many blank lines omitted ...]
13 # (that's the number of bytes, if you didn't remember)
$ ls .svn/text-base/
foo.svn-base
$ ls .svn/prop-base/
foo.svn-base
$ ls .svn/props/
$ cat .svn/text-base/foo.svn-base
original foo
$ cat .svn/prop-base/foo.svn-base
K 1
p
V 1
v
END
$
Before we run the 'svn up', note some things:
1. Despite the the fact that foo is schedule-replace, its text-base
and prop-base files are still in their original locations (i.e.,
'foo.svn-base', not 'foo.svn-revert'). I think this is wrong,
as per issue #3282, and am trying to fix it.
2. Note that the 'foo' entry lists no checksum (it would be where
the blank line is between the two dates). This is expected:
when a file become schedule-replace, the entry loses its
checksum.
Okay, now we run 'svn up' and receive the changes from wc2 on top of
the schedule-replace 'foo' (in wc1):
$ svn up
Conflict discovered in 'foo'.
Select: (p) postpone, (df) diff-full, (e) edit,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options: p
C foo
Updated to revision 2.
$ cat .svn/entries | imagine-fancy-grep-command-for-entry-foo
foo
file
replace
2008-09-10T20:24:33.224621Z
2
kfogel
has-prop-mods
foo.r1
foo.r2
foo.mine
$ ls .svn/text-base/
foo.svn-base
$ ls .svn/prop-base/
foo.svn-base
$ ls .svn/props/
foo.svn-work
$ cat .svn/text-base/foo.svn-base
change foo in the other wc
$ cat .svn/prop-base/foo.svn-base
K 1
p
V 1
v
END
$ cat .svn/props/foo.svn-work
$ ls -l .svn/props/foo.svn-work
-r--r--r-- 1 kfogel kfogel 0 2008-09-10 16:37 .svn/props/foo.svn-work
$ svn st -vu
CM 2 2 kfogel foo
? foo.r1
? foo.r2
? foo.mine
2 2 kfogel .
Status against revision: 2
$
So, most signs that this file was ever scheduled for replacement are
gone. It now has a working props file, and the entry says it
'has-props' (meaning there are mods w.r.t. the prop-base). But
although the .svn/props/foo.svn-work file exists, it is empty.
My patch (in progress) for issue #3282 solves the "replacment doesn't
move old base files aside" problem: the old foo.svn-base files will
now become foo.svn-revert files as soon as we add the replacement foo.
But when we update, the new changes come in and affect the revert
files, which would be fine if the file stayed schedule-replace, but it
doesn't. Well here, maybe it's better if I show you what happens with
my patch:
Again, this is right after the replacement but before the update:
$ cat .svn/entries | imagine-fancy-grep-command-for-entry-foo
foo
file
1
replace
2008-09-10T20:54:49.000000Z
2008-09-10T20:54:49.310135Z
1
kfogel
[...]
13
$ ls .svn/text-base/
foo.svn-revert
$ ls .svn/prop-base/
foo.svn-revert
$ ls .svn/props/
$ cat .svn/text-base/foo.svn-revert
original foo
$ cat .svn/prop-base/foo.svn-revert
K 1
p
V 1
v
END
$
Good! I think that's exactly how things should look, for a
schedule-replace file (i.e. the replacement has not been committed).
Now let's run 'svn up' and see what happens:
$ svn up
Conflict discovered in 'foo'.
Select: (p) postpone, (df) diff-full, (e) edit,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options: p
CU foo
Updated to revision 2.
$ cat .svn/entries | imagine-fancy-grep-command-for-entry-foo
foo
file
2008-09-10T20:54:51.241517Z
2
kfogel
has-props
foo.r1
foo.r2
foo.mine
$ ls .svn/text-base/
foo.svn-revert
$ ls .svn/prop-base/
foo.svn-base foo.svn-revert
$ ls .svn/props/
$ cat .svn/text-base/foo.svn-revert
change foo in the other wc
$ cat .svn/prop-base/foo.svn-base
K 1
p
V 1
v
END
$ cat .svn/prop-base/foo.svn-revert
K 1
p
V 1
v
END
$ svn st -vu
C 2 2 kfogel foo
? foo.r1
? foo.r2
? foo.mine
2 2 kfogel .
Status against revision: 2
$
There is so much wrongness here I don't know where to start :-).
(Some of it might be due to my patch, and it would be interesting to
run the 'svn up' part using a pristine Subversion, but I don't want to
make this mail more complicated than it already is.)
Some things to note:
1. Again, the file no longer thinks it's schedule-replace after the
update. That seems bad.
2. We have revert-base files for both text and props, but we *also*
have a regular base file for props now (and it contains the same
text as the revert-base). WTF?
3. This time, the update printed 'CU' instead of just 'C'. It
thinks it received a prop update. I don't know why.
4. But 'svn st' thinks the file has only a textual conflict now,
with no property modification. That's good, I guess.
Anyway, now we're back to my original question: what should happen?
My answer is that the file should still be schedule-replace, still
have revert-bases (and no regular bases), the revert-bases should have
the new content. The working file should *not* be in conflict, but
should simply have the same replacement text it had before the update.
Does anyone think that's the wrong goal?
-Karl
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-09-10 23:30:52 CEST