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

fourth tree: "INHERITED" (was: wc-ng base/working nodes in a copied tree)

From: Greg Stein <gstein_at_gmail.com>
Date: Wed, 7 Apr 2010 16:15:01 -0400

On Wed, Apr 7, 2010 at 04:52, Philip Martin <philip.martin_at_wandisco.com> wrote:
> Greg Stein <gstein_at_gmail.com> writes:
>
>> I believe that we have the following operations:
>>
>> add: plain old add
>> add-within-copy/move: add within a subtree
>
> Those two are much the same.  It makes little difference whether it's
> a plain add, an add within an add or an add within a copy/move.

Well... we couldn't distinguish these two cases before. With a few
additional presence values, we can.

>> replace: delete-base + add
>> replace-within-copy/move: delete-child + add
>
> There is also
>
> replace: base node not-present + add
>
> the old deleted=true state.  This is explicitly excluded from being a
> replace in svn_wc__internal_is_replaced but that may be a bug (it
> causes revert to erroneously remove the not-present base node).

It is excluded from being svn_wc_schedule_replace. I'd prefer to
ignore that fact.

>
>> delete-base: deleting a base node
>> delete-child: deleting a child of an add/copy/move
>> copy(-within): same as add•
>> moved-here(-within): same as add*
>> moved-away(-within): same as delete*
>>
>> I'm thinking that we add the following presence values (for
>> WORKING_NODE.presence):
>>
>> "added": same as "normal" today. clarifies what this really means. we
>> map this to status_added, so why not use this for the presence
>> anyways? no need to "minimize/conserve" the set of presence values.
>>
>> "replaced": indicates an added/copied-here/moved-here node that
>> replaces a child of a copied-here/moved-here subtree.
>>
>> "deleted": same as "not-present" today. clarifies what this really means.
>>
>> "inherit": applied to children of copied-here/moved-here and
>> deleted/base-deleted nodes. implies that no commit operations are
>> required for these nodes.
>
> Being able to distinguish add and replace is not enough for full 1.6
> compatibility.  When a node replaces a copied child it overwrites the
> child's data, things like checksum and properties.  This data is not
> derived or inherited from the copied parent, so it cannot be restored
> after being overwriten.  In 1.6 it is possible to revert the replace
> and restore to the copied child.

Urgh. Yeah. I've only ever looked at that scenario as "no partial
reverts (yet). revert the whole thing". In that case, meaning the
whole copy. But that's not right, if the user is reverting
SOME/SUBDIR/PATH. Only the change(s) to the child should be reverted.

> Another problem is a copy of a mixed revision tree that includes base
> nodes that are not-present.  In 1.6 we represent these as "fake"
> schedule deletes in the copy, so that they are explicitly deleted when
> the copy is committed.  This works but has problems, the main one
> being that if one tries to revert the delete the full node information
> is not available (because the not-present source doesn't have it).
> Perhaps we should have a distinct presence for this type of node?
> There are similar questions about absent and excluded nodes.

Okay. In this case, reverting the delete should result in an excluded
node. That's the best we can do. "svn update --depth=infinity
NOTPRESENT" can restore the file.

Note that we *could* revert a replaced-child into an excluded node,
too. That would be a feature loss compared to 1.6, however.

It seems like we need one more tree, to hold "inherit" data. If you do
a further operation on an operation-root (something in WORKING_NODE),
then it will alter that node and all inherited nodes. But if you
perform an operation on an inherited node, then you're establishing a
new operation-root in WORKING_NODE. The inherited data can still
remain elsewhere, but WORKING_NODE now refers to a new operation-root.
Reverting that operation would bring back the inherited node.

Thus, WORKING_NODE would become *just* explicit operations. ie. the
stuff we send during a commit.

Hmm. Almost...

A delete operation could mark the root in WORKING_NODE (we'd probably
want a new name for this!), and then drop a bunch of markers in
WORKING_NODE to occlude any children present in the inherited tree and
the BASE tree. Those markers couldn't be individually reverted
however, and they don't represent data to send during commit. We
*could* alter a presence-like flag in the inherited tree instead, yet
leave all the data intact for a revert. Or place markers in the
inherited tree to occlude the BASE nodes.

Thoughts?

Cheers,
-g
Received on 2010-04-07 22:15:28 CEST

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