Using editable_working_tree for not only update but also for revert and checkout should allow us to re-use conflict detection and resolution machinery. For now this page lists some things about the different types of conflicts that can occur and how we'll deal with them.
Issues
*are these all done? I think they might be.. -- DC *
create_file_node/create_dir_node
- create a new file or directory in _MTN/tmp/
- may be blocked by stale _MTN/tmp entries
- detect these early and fail by treating the existence of _MTN/tmp as a lock
- update workspace version and migrate_workspace to new format
- perhaps rename _MTN/tmp to something less tmp-ish ... _MTN/var ?
attach_node
- move _MTN/tmp/ to proper path
- may be blocked by an existing unversioned file or dir
- detect these in preliminary run of editable_working_tree against list of files/dirs from workspace
detach_node
- move path to _MTN/tmp/
- may be blocked by stale _MTN/tmp entries
- detect these early and fail by treating the existence of _MTN/tmp as a lock
- update workspace version and migrate_workspace to new format
- perhaps rename _MTN/tmp to something less tmp-ish ... _MTN/var ?
drop_detached_node
- remove _MTN/tmp/
- may be blocked by unversioned files in detached dir
- detect these in preliminary run of editable_working_tree against list of files/dirs from workspace
apply_delta
- apply delta to a file in place
- may be blocked if there is a directory in place of a file
- currenlty detected early in update_current_roster_from_filesystem
Todo
These are far from a complete solution but they should at least prevent update failing and leaving the workspace in an inconsistent state with files detached and left in _MTN/tmp
- remove the file munging line ending conversion stuff which is all tied up in this
- rename _MTN/tmp to _MTN/var (or something) and treat the existence of this dir as a workspace lock
- update workspace format and migrate_workspace
- add a new editable_tree implementation to do the preliminary run and check for attach and drop problems
- clean up the "up here, down there" stuff in editable_working_tree once tests no longer depend on clobbering behaviour
- add revert renames tests to see what happens when we have name conflicts
The editable_working_tree interface currently cannot create detached files in _MTN/tmp/ because it currently relys on the filename to determine line endings and encodings and file names are not known until attach time. We should probably move encoding/line-ending information into attrs in the roster so they are available when filenames are not.
Next Steps
- remove simulated_working_tree and run roster_merge on a roster that represents the complete workspace contents (including known changes and unknown files)
eg, for update, the full set of rosters involved looks like this:
B
|\
| \
| \
T W
\ |\
\ | \
\| \
U W+
\ |
\ |
\|
U+
- B is base revision workspace was checked out from
- W is the workspace revision (known-but-uncommitted content changes, rearrangements, attrs)
- T is the update target revision
- U is the updated workspace revision that includes the B->T changes (to be written out to _MTN/revision)
- W+ is the full workspace revision (including all unknown files and directories for collision detection)
- U+ is the updated workspace revision that includes all unknown files and directories
In the first pass, collision detection says that if there are any conflicts in U+, it's an error and we can't perform the update (or pluck, etc). Otherwise, we can, and we apply B->T to W to create U, and write that out.
Later, once we have a nice UI and agreed way to write out conflicts from a roster into a workspace for the user to resolve, these conflicts can be written out too. For example, this would allow both a newly added file in T and the unversioned blocker file in W+ to be written out as a conflict for the user to resolve.
Blue Sky
It would be nice to eventually allow for automated conflict resolovers. For example when updating wants to add a file that is blocked by an existing unversioned file we could:
- leave the existing file and rely on status to see where things are at
- clobber the existing file as we do now
- raise a conflict and ask the user what to do
It seems like we may eventually want a filesystem interface that can be plugged into editable_working_tree so we can run against a mock implementation first and then again against the true implementation.
Affected Commands
The following commands should all eventually use the editable_working_tree interface so that they can all use the common conflict resolution machinery once that exists.
- update currently does use the editable_working_tree interface
- pluck currently does use the editable_working_tree interface
- pivot_root currently does use the editable_working_tree interface
- checkout now does use this interface, based on the implementation from the net.venge.monotone.editable_tree.checkout branch
- revert does not yet use this interface but an alternate implementation exists on the net.venge.monotone.editable_tree.revert branch. this implementation is incomplete mainly due to the problems associated with workspace conflicts