Experimental work to prototype a model of move-tracking and branching is mostly contained in: notes/move-tracking/ subversion/include/private/svn_branch*.h, svn_element.h subversion/libsvn_delta/branch*.c, element.c subversion/tests/cmdline/svnmover_tests.py tools/dev/svnmover/ This work started out on the 'move-tracking-2' branch. Reviewing: Please do try out the 'svnmover' utility, explore how branching and subbranching and moving interact, and review and discuss the behavioural aspects of the model being prototyped here. Please don't review for 'quality of implementation' issues, not even big-O complexity concerns etc. The goal of this work is for us to learn about the behavioural model that we want. Designing a proper implementation will come later. The model: Imagine a user who: - is familiar with version control concepts - is not familiar with Subversion specifics - expects directories to be versioned (not just files) - expects move tracking (as opposed to move 'detection') The design aims to satisfy such a user. See 'notes/move-tracking/element-model/moves-element-model.html' for a description. Work on this experiment: * 'svnmover' A proof-of-concept utility for playing with moves and branching. 'svnmover' is a user interface that lets us try out scenarios in which branching and moving are significant, to see what we expect and see if we can write code that delivers it. 'svnmover' operates directly on a repo, like 'svnmucc', without using a working copy on disk. However, it simulates a short-lived working copy, in memory. It processes a series of commands given on the command line or interactively. These commands change the state of the simulated WC. The changes are committed on exit or whenever the 'commit' command is given. Advanced working copy facilities -- mixed-rev states, sparse checkouts, conflicts, and so on -- are initially not supported. Such facilities may be introduced to 'svnmover' in due course in order to explore how they would work. (A working copy is, in essence, a tool for viewing and making changes to the versioned data, and so its facilities need to be redesigned to support the new versioned data model.) The implementation stores metadata either in revprops or in flat files in the repository directory; the metadata is the same in either case. STATUS This is my current focus. Implemented: basic edits: add file/dir, move, copy, delete branching: branch, create new branch, list branches diff merge commit update, switch revert UI things to do: add a 'parallel mode' UI as an alternative to the sequential mode - started, by removing the automatic commit after each line - look up given paths in the base state rather than in the current txn - this would make more sense in conjunction with element-addressing UI provide a way to specify a mixed-rev base state provide a UI for element-based addressing ('mv e101:foo e103:foo'?) "mktbranch" -- make a new (empty, unrelated) top-level branch "rmtbranch" -- remove a top-level branch Bigger things to do: heuristic conversion of old repositories: synthesize element tracking info (instead of aborting) when reading a revision that was committed by a non-move-tracking client - Started, by using log scanning code from the 'moves-scan-log' branch and starting to write an Ev1-to-Ev3 converter that uses that info. - Currently triggered by a 'migrate' subcommand. Make machine parsable serial input and output for diffs etc. - This may help with prototyping by allowing easier connection to external scripts etc. Persist WC on disk. Tidying things to do: (none listed) * The model. To do: - clarify the sequencing requirements of editing: for example, requesting the full path to an element implies finalization of at least it and all its parent elements The editor currently includes a 'sequence_point' method. This is a broken bit of design. It was an attempt to allow 'flattening' the txn state into a tree on demand, so the client (especially a client like svnmover) can query the txn by path. The client should never make a query that involves paths on a txn that is in an arbitrary state (some elements edited, some yet to be edited). The 'sequence_point' method should go away. Instead, the client should request a (read-only) snapshot of the state (e.g. svn_branch_subtree_t) at an appropriate time, and query that. Any 'svn_branch' APIs that look up by path or yield a path should not be used on a txn in an arbitrary state, but only on a 'flat' snapshot state (e.g. svn_branch_subtree_t). Need to decide whether to use a single data type for both txn and flat-tree, or separate types as currently done ('svn_branch_state_t' and 'svn_branch_subtree_t'), and go fully with whichever way we decide. copying: model copying as a (tree) relationship between elements that is the same across all branches in a family? STRUCTURE svn_element.h Defines the 'element' and other basic concepts including 'payload' (files and directories), identifiers, etc. svn_branch.h: svn_branch_txn_t: a transaction that defines a new 'commit', or 'head' state, based on a previous one svn_branch_state_t: defines the state of one branch svn_branch_nested.h Redefines 'branch txn' to support nesting of branches. svn_branch_repos.h Access to revisions in a repository. The 'branch txn' can be used for commit, in which it represents a new head revision based on a previous revision. The 'branch txn' can be used for updating a WC. The WC contains a base state and a txn that represents the working state relative to the base state. (This txn is persistent on disk.) To update the WC to a new base state, we first build a new transaction in the WC to represent the new base state, based on the old base state. Then we merge these two txns to produce the txn that represents the new working state. (The original 'update editor' had a peculiarity in that it used the same API underneath but operating on WC paths rather than repository paths/nodes. We should try to use exactly the same API for update, commit, diff, merge, etc. as far as possible.)