> -----Original Message-----
> From: Philip Martin [mailto:philip.mar...@wandisco.com]
> Sent: vrijdag 6 september 2013 17:50
> To: Greg Stein
> Cc: dev@subversion.apache.org
> Subject: Re: Move using initial state
> 
> Philip Martin <philip.mar...@wandisco.com> writes:
> 
> > What about alter_dir?  I think the rule is that alter_dir on a directory
> > should occur before add or delete affects the children of the directory.
> > There is also a rule:
> >
> >  * - The ancestor of an added, copied-here, moved-here, or
> >  *   modified node may not be deleted. The ancestor may not be moved
> >  *   (instead: perform the move, *then* the edits).
> 
> I've been thinking about alter_dir and I see no reason, in the update
> editor at least, for a rule that requires alter_dir before adding or
> removing children.  The Ev2 "once" rule is designed to ensure that Ev2
> actions can be applied to the nodes in the working copy as the actions
> are received and that the working copy nodes will always reflect
> repository nodes.  This doesn't require alter_dir on the parent before
> add/delete of children.

Shouldn't alter_dir get the complete list of directories when children are
added/removed?

With editor v1 the list of children *must be* updated before we 'close' the
directory, by remove the incomplete flag. If we don't do this then an
interrupted update can't be restarted.

A similar scheme should also apply for editor v2. If children are added or
removed without bringing the parent in a 'being modified state', it is
neither in the original revision, nor in the final revision.

The alter_dir method would allow bringing it to completion directly by
giving it the complete final revision state, with the knowledge about which
children need a separate update to complete the entire tree.

        Bert

> 
> Consider a working copy with three nodes:
> 
>    A@6
>    A/B@6
>    A/C@6
> 
> that gets updated to
> 
>    A@8
>    A/D@8
>    A/E@8
> 
> That's two adds, two deletes and an alter and the update editor can
> handle them in any order, even this order:
> 
>    add_dir A/D
>    delete A/B
>    alter_dir A, children=D,E
>    add_dir A/E
>    delete A/C
> 
> Lets see how NODES would work:
> 
>      relpath  rev  status
>      A         6   normal
>      A/B       6   normal
>      A/C       6   normal
> 
>    add_dir A/D
> 
>      relpath  rev  status
>      A         6   normal
>      A/B       6   normal
>      A/C       6   normal
>      A/D       8   normal
> 
>    delete A/B
> 
>      relpath  rev  status
>      A         6   normal
>      A/B       6   not-present
>      A/C       6   normal
>      A/D       8   normal
> 
>    alter_dir A
> 
>      relpath  rev  status
>      A         8   normal
>      A/C       6   normal
>      A/D       8   normal
>      A/E       8   incomplete
> 
>    add_dir A/E
> 
>      relpath  rev  status
>      A         8   normal
>      A/C       6   normal
>      A/D       8   normal
>      A/E       8   normal
> 
>    delete A/C
> 
>      relpath  rev  status
>      A         8   normal
>      A/D       8   normal
>      A/E       8   normal
> 
> Every intermediate state has NODES rows that reflect repository nodes.
> If interrupted every intermediate state can be correctly updated to
> either r6, r8 or any other revision.
> 
> The delete introduces a not-present node if the parent revision is
> different from the target revision, otherwise it simply removes the
> node.
> 
> The alter removes any not-present children and introduces incomplete for
> any missing children.
> 
> Any children that are replaced, i.e. add with replaces-rev set, do not
> require alter_dir on the parent at all, although some other change to
> the parent may require it.
> 
> > It's not clear where alter_dir should occur w.r.t the moves in my
> > example.  Does alter_dir count as an edit that should occur after move?
> > Do we pass initial state paths:
> >
> >    alter_dir .,     children='A'
> >    alter_dir A,     children=''
> >    alter_dir A/B,   children='C'
> >    alter_dir A/B/C, children='B'
> >
> > or final_state paths:
> >
> >    alter_dir .,     children='A'
> >    alter_dir A,     children='B'
> >    alter_dir A/B,   children='C'
> >    alter_dir A/B/C, children=''
> 
> So we don't necessarily have to do alter_dir on the parent before moving
> children.  What about alter on the moved node itself?  Perhaps we do
> that between move_away and move_here.
> 
>      relpath    rev  status       repo
>      A           6   normal       A
>      A/B         6   normal       A/B
>      A/B/C       6   normal       A/B/C
> 
>    move_away A/B/C, id=1
> 
>      relpath    rev  status       repo
>      A           6   normal       A
>      A/B         6   normal       A/B
>      A/B/C       6   not-present  A/B/C
> 
>    move_away A/B, id=2
> 
>      relpath    rev  status       repo
>      A           6   normal       A
>      A/B         6   not-present  A/B
> 
>    move_away A, id=3
> 
>      relpath    rev  status       repo
>      A           6   not-present  A
> 
>    alter_dir id=1, children=B
>    move_here id=1, A
> 
>      relpath    rev  status      repo
>      A           8   normal      A
>      A/B         8   incomplete  A
> 
>    alter_dir id=2, children=C
>    move_here id=2, A/B
> 
>      relpath    rev  status      repo
>      A           8   normal      A
>      A/B         8   normal      A/B
>      A/B/C       8   incomplete  A/B/C
> 
>    alter_dir id=3, children=
>    move_here id=3, A/B/C
> 
>      relpath    rev  status      repo
>      A           8   normal      A
>      A/B         8   normal      A/B
>      A/B/C       8   normal      A/B/C
> 
> That looks like the set of NODES tables that we want. At each stage the
> NODES rows reflect nodes in the repository and if interrupted an update
> to any revision is possible.
> 
> This also means that NODES.repos_path and NODE.revision in the NODES
> table always reflect nodes in the repository.  If we try to do alter
> before or after move we end up with things that look switched or nodes
> that are not valid.  Consider an update that moves A/B to A/C:
> 
>      relpath    rev  status       repo
>      A           6   normal       A
>      A/B         6   normal       A/B
> 
> If we move before alter we either get
> 
>    move A/B A/C
> 
>      relpath    rev  status       repo
>      A           6   normal       A
>      A/C         6   normal       A/C
> 
> or
> 
>      relpath    rev  status       repo
>      A           6   normal       A
>      A/C         6   normal       A/B
> 
> The first has an invalid row A/C@6 the second has A/C switched.  If we
> alter before move we either get
> 
>    alter_dir C, children=
> 
>      relpath    rev  status       repo
>      A           6   normal       A
>      A/B         8   normal       A/B
> 
> or
> 
>      relpath    rev  status       repo
>      A           6   normal       A
>      A/B         8   normal       A/C
> 
> again either invalid or switched. This implies that if we want to
> combine
> 
>      move_away A, id=1
>      move_here id=1, B
> 
> into a single
> 
>      move A, B
> 
> then move and alter need to be combined:
> 
>      move_dir  A, B, children=, props=
>      move_file A, B, checksum=, props=
> 
> --
> Philip Martin | Subversion Committer
> WANdisco // *Non-Stop Data*

Reply via email to