Ben Collins-Sussman <sussman@collab.net> writes:
> PROBLEM 1 : the lagging parent directory
> ---------
>
> Assume my working copy has two directories both at revision 3:
>
> A/D : 3
> A/D/H : 3
>
> Now I `svn rm A/D/H` and commit, which produces revision 6 in the
> repository. My working copy now looks like:
>
> A/D : 3
>
> A/D/H is gone, because the RA layer told us it was a target that was
> successfully committed. The client routine log_do_committed() got
> this message, saw that the A/D/H entry was originally scheduled to be
> deleted, and so it took the liberty of actually removing it during
> commit cleanup.
>
> Now, when I `svn up` to revision 6, the client sends an incomplete
> report to the server on the working copy state:
>
> A/D : 3
>
> It's incomplete, because there's no mention of A/D/H anywhere. As a
> result, the repository *assumes* that the client still has A/D/H:3,
> and thus tells the client to remove A/D/H. This is an error -- A/D/H
> is already gone.
>
> (Incidentally, this bug would still be the same if H were a file,
> instead of a dir.)
This problem has actually been discussed and (I believe) solved
already:
After committing the deletion of A/D/H:3 (thus producing revision 6 in
the repository), the working copy must record that H is at revision 6
-- a revision in which H does not exist, but nonetheless it's a
perfectly valid thing to say. In other words, in A/D/SVN/entries, the
entry for H will still be present, and will claim the entry is at
revision 6, and there should also be a flag indicating that in that
revision, said entry does not exist. This flag will remain present
until the parent directory, A/D, is updated to revision 6 or beyond.
Oh. And now I see that this is exactly what you wrote. :-) There
were a few newlines separating the problems from the solutions, so I
didn't realize there was more to the mail until after I'd written the
above.
Moving on to Problem 2:
> PROBLEM 2 : the incomplete directory
> ---------
>
> Assume my working copy has a directory, everything at revision 3:
>
> A/D : 3
> A/D/H : 3
> A/D/foo.c : 3
>
> Now, unbeknownst to me, somebody else adds a new file `bar.c' to this
> directory, creating revision 4.
>
> Then I add a property to A/D and commit. The RA layer replies that
> A/D was successfully committed, creating revision 5, so
> log_do_committed() bumps A/D's revision to 5 in my working copy.
>
> Of course, this is completely bogus. My working copy does *not* have
> revision 5 of A/D -- it has no idea that `bar.c' exists.
I thought we decided that for changes to the directory _itself_ (i.e.,
property changes), the dir would need to be up-to-date, since such
changes are not auto-mergeable. (Yes, in fact this change *could* be
automerged with a later revision of the dir if that later revision
differs only in entries, not in properties, but if our rule at commit
time is simply "Don't commit changes to dir properties when the
directory is not completely up-to-date" then we're always safe.)
-Karl
>
>
>
>
> SOLUTION to Problem 1 (in progress)
> --------
>
> A subversion entry has more than just a "schedule" flag. It now has
> an "existence" flag, used specifically to describe an entry that is
> out-of-sync with its parent's revision.
>
>
> >> Adding a "deleted" flag
>
> Thus, when log_do_committed() is told that A/D/H was committed, and
> sees A/D/H was slated for deletion, it examines revision numbers. If
> the committed target's revision (6) is newer than the parent's
> revision (3), it marks the entry with "existence = deleted." (If the
> two revision numbers are the same, then the entry is removed instead.)
>
>
> >> Make state-reports smarter
>
> svn_wc_crawl_revisions now notices the "deleted" flag and gives an
> accurate working-copy report to the repository:
>
> A/D : 3
> A/D/H : missing
>
> And now the repository will *not* tell the client to remove A/D/H.
>
>
> >> Removing the "deleted" flag
>
> There are three scenarios whereby the "deleted" flag goes away:
>
> * updating parent to a revision where the entry exists
>
> Assume that A/D/H is re-added in revision 10, and we're updating
> to this revision. Or assume we're updating to revision 4, where
> the removal hasn't happened yet.
>
> The repository will tell the update-editor to re-add H. The
> update-editor notices that H already exists -- but instead of
> producing an "obstructed update" error, it sees the "deleted"
> flag and instead removes and re-writes the whole entry.
>
> * updating parent to a revision where the entry has been deleted
>
> After an update finishes, ensure_uniform_revision() sets all
> working-copy revisions to the same value. It notices a "deleted"
> entry, and if it's own revision is less than or equal to the new
> uniform revision, it can safely remove the entry. The parent has
> "caught up" with the child.
>
> * committing parent
>
> If the parent is committed, log_do_committed() will be informed
> that it was successfully committed to a new revision number.
> (This new revision number *must* be higher than 6, the
> deleted-child's revision!)
>
> So log_do_committed() will notice the parent's "deleted" child at
> revision 6, which is younger, and remove the entry altogether.
>
>
>
> SOLUTION to Problem 2
> --------
>
> Still thinking on this one. Yikes.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
> For additional commands, e-mail: dev-help@subversion.tigris.org
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:36:33 2006