Julian Foad wrote:
> (First question: "So what are these concepts and goals?")

Briefly, then...


OUTLOOK

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.


GOALS

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.


CONCEPTS

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:
family 0
  branch at '/'
    e0 -> .
    e2 -> branches
    e5 -> trunk
    e6 -> branches/br1
family 44
  branch at '/trunk'
    e100 -> .
    e101 -> foo
    e103 -> bar
  branch at '/branches/br1'
    e100 -> .
    e101 -> foo

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.

- Julian

Reply via email to