Re: Move tracking -- concept demo
From: Julian Foad <julianfoad_at_btopenworld.com>
Date: Wed, 26 Nov 2014 16:53:00 +0000
Julian Foad wrote:
The purpose of this work is to explore the possibilities for move tracking in Subversion in the future, beyond the specific issues on the immediate horizon such as linking a copy to a delete or resolving a tree conflict.
This is looking at the relatively long term, not just the next release cycle. This should provide concepts for us to keep in mind, even if we choose to implement only a small incremental improvement at first, so that each step we take is not a random change but progress towards an ideal.
The 'svnmover' program in the 'move-tracking-2' branch is to help us try out the ideas. The user interface and metadata storage, as well as the concepts, are all open to being completely changed. Please feel free to go ahead and implement additional user interface styles, for example.
I can envisage a Subversion in which move tracking works something like this and merging produces far fewer conflicts than today.
Whether you are a regular contributor or not, above all I invite you to try it out and share your thoughts.
Moves should be versioned as solidly as any other kind of change.
In particular, merging with moves should be well defined, simple to understand, and efficient. For example, merging some changes inside a directory with some other changes that include renaming or moving that directory should just do the obvious thing, no matter how complex the changes and no matter how far apart the branches.
Move tracking is important mainly because of how it impacts merging. It becomes clear that branching and merging are inseparably bound up with move tracking, and so specific concepts of branching are introduced.
A "branch family" is a set of branches that share a set of "elements". An element of a branch family refers to a node that may be absent or present in each branch of that family in each revision. An element's node kind (file or directory) is fixed, whereas its name, parent-element and content (props, text) can vary across branches and across revisions.
To "move" an element means to change its name and/or its parent directory element. Children follow along with their parent unless separately moved.
Every node in the repository is an element of some branch. At the root directory of the repository the "root branch" is always present; it is a normal kind of branch but is the only branch in its family. Every other branch is nested inside the root branch or inside another branch.
In contrast to previous Subversion usage, a branch must be declared in advance. We will want to discuss implications such as how a user can start branching a subtree that was not declared as a branch, and how best to migrate history into the new scheme.
A branch family is created in some revision (the root family is created in r0) and its definition then lives forever, even if a commit deletes all branches of that family. Similarly, an element is created in some revision and its definition then lives forever, even if that element is deleted from every branch. Reverse merges, and selective merges from history, can always resurrect things that have been deleted, including whole subbranches.
Example of branch metadata, showing the corresponding paths at some particular revision:
Merging is defined within the context of a branch family. Each of the three "sides" (source, target, ancestor) can be any branch of the family at any revision. The basic operation is: for each element, locate this element in each of the three sides; merge the content changes and the moves (changes of name and/or parent-element) separately.
Branch families are nested in a tree hierarchy. The nesting of branches always matches the nesting of their families. For example, if family 0 is the parent family of family 44, then each branch of family 44 is nested (pathwise) inside a branch of family 0 at all times. In the outer branch, a "subbranch root" element (for example, family 0 element 5) defines the name and parent-element but not its content, while in the inner branch the root element (f44 e100) carries only its content (file/dir, props, text) but not its name and parent.
Other topics that I'm still working on include how the "copy" relationship fits in, how merge tracking will work, and how best to migrate data from the existing Subversion. There is also the user interface challenge: how to evolve our very path-focused UI to represent this kind of move tracking.
I recognize that this all seems a big change, but I think it's the most important thing Subversion needs, and I think we can do it. If you care about move tracking, please have a play with it and tell me what do you think.
This is an archived mail posted to the Subversion Dev mailing list.