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

Re: deleted-with-history [sic] after merge

From: Erik Huelsmann <ehuels_at_gmail.com>
Date: Mon, 24 Mar 2008 09:40:53 +0100

> It seems that the merge code depends on the loophole in commit.

Well, if there's a loophole and whether merge depends on it, I don't
know, but ...

> The attached shell script demonstrates this by replacing a directory
> 'X' that contains a file 'foo'.

... the problem you describe below looks an awful lot like issue
19<some-value-i-told-you-earlier-tonight-but-can't-find-now>

> If the dir replacement is done manually via 'svn del' and 'svn add',
> the status is nominal:
>
> D 1 1 steve /tmp/del-w-hist/wc/A/X/foo
> A 0 ? ? /tmp/del-w-hist/wc/A/X/bar
> R 1 1 steve /tmp/del-w-hist/wc/A/X
> 1 1 steve /tmp/del-w-hist/wc/A
> Status against revision: 1
>
> and during commit, foo is implicitly deleted with its parent dir:
>
> Replacing tmp/del-w-hist/wc/A/X
> Adding tmp/del-w-hist/wc/A/X/bar
> Transmitting file data .
> Committed revision 2.
>
> If the dir replacement is done via 'svn merge', then the status looks
> rather strange (foo appears to be "deleted-with-history"):
>
> D + - 3 steve /tmp/del-w-hist/wc/B/X/foo
> A + - 2 steve /tmp/del-w-hist/wc/B/X/bar
> R + - 3 steve /tmp/del-w-hist/wc/B/X
> M 3 3 steve /tmp/del-w-hist/wc/B
> Status against revision: 3

The '+'-es come from svn_wc_add2() which marks the complete subtree as
COPIED==TRUE. (ouch!)

> and during commit, foo is deleted explicitly *after* its parent dir
> has been deleted.
>
> Sending tmp/del-w-hist/wc/B
> Replacing tmp/del-w-hist/wc/B/X
> Adding tmp/del-w-hist/wc/B/X/bar
> Deleting tmp/del-w-hist/wc/B/X/foo
> subversion/libsvn_client/commit.c:916: (apr_err=160028)
> svn: Commit failed (details follow):
> subversion/libsvn_repos/commit.c:125: (apr_err=160028)
> svn: File or directory '/B/X/foo' is out of date

The fact that the delete comes after the delete of the parent dir is
normal: that's how the svn_delta_path_driver works: depth-first,
processing tree nodes as they are passed

> This causes an error in my patched Subversion, which forbids
> committing a delete of an item that does not exist in the repository.

Right. Here you have the essence of the problem: in the wc-1.0 schema,
files which are part of the deleted subtree in a replaced subtree have
to be marked 'deleted'. If they were not, there would be no way to put
another file in its place.

However, a schedule delete is a valid state in a added-with-history
subtree too: you may want to delete part of the subtree before you
commit.

So, what we're facing here is: we want to be able to tell the file is
part of a deleted subtree *and* we want to be able to tell a file has
been removed from the add-with-history subtree we copied on top of it.
The problem is that we do that with the same schedule-delete status of
the file, which then becomes ambiguous.

> Comparing the working copies before the commits, I noticed something
> odd in /B/X/.svn/entries: the file foo is marked as "copied". This
> explains the 'D +' above. It contradicts the .entries format rules
> in subversion/libsvn_wc/README:
>
> copied:
> A boolean: true if this entry was added with history; only allowed
> when schedule is add. (### Why aren't the copyfrom attributes
> enough for this?)

This is plain wrong: files which are part of a
schedule-add-with-history subtree are marked schedule-normal, but have
the 'copied' flag. (Not that I actually like this design, but that's
how it is now.)

> Certainly we should not mark schedule-delete items as "copied". Is
> there a good reason for merge to cause commit to visit all items in a
> tree that is already deleted?

No, there is not. The copied flag comes from svn_wc_add2() which
markes all files in the subtree as copied (and rewrites their URL),
making this operation a *huge* problem for replaced subtrees.

> I suspect the practical reason for the current behavior is the code
> shared with diff, which certainly needs to visit everything. For more
> on the diff/merge dependency, see my earlier post at
> http://svn.haxx.se/dev/archive-2008-02/0776.shtml.

I wouldn't go this far: I think it should be possible to get the right
diffs and commits without a copied flag all over the place, but we'll
need to design what we want from our library.

HTH,

Erik.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-03-24 09:41:09 CET

This is an archived mail posted to the Subversion Dev mailing list.