> -----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*