Hi! This is a spin-off from Julians thoughts in notes/tree-conflicts/resolution.txt. I've tried to make the states more explicit using the new WC-NG terminology.
I feel fairly confident about the update scenarios (and just as confident knowing that, that statement will jump back and bite me). The merge scenarios is subject to change I guess. I haven't entirely grasped the inner workings of the merge functionality (has anyone, really?). A lot of the conflicts will disappear once we have editor-v2. Things to do ============= Clairify what state the wc is in during a tree conflict and what options we have (This is what this post is about). Investigate if the use cases will stand their ground when more complexity is added. I'm thinking of multiple nested tree conflicts and combination with text conflicts. Determine if creating a storage for the THEIRS tree is doable and how our code should interact with that storage. Agreeing on a user interface. If we can store all conflict info in the db, then we could run the resolver when we want to and not just on a up/sw/merge operation. That would allow us to make the UI simpler. Whip out my editor and start coding. So here's my spec: [[[ Design spec for tree conflict resolution in the commandline client ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The hard part is figuring out in what state the wc is in during the different user cases. The main difference between update/switch and merge is that we don't have somewhere to store the incoming changes during a merge. It would be nice if we could save a THEIRS tree. ### What if we have more than one conflict at a time? One at the top of ### a tree and another nested below. Can that happen? Contents ========= Problem definition Requirements Use cases update/switch Use cases merge API changes User interface Problem definition ========================= Users are having problems understanding how to resolve tree conflicts. For some operations they may not know how to get back to a previous state. They don't always know how to view the changes causing a conflict. Requirements ===================== It should be easy for the user to understand why the conflict has happened and how to resolv it. Update, switch and merge should be reversible. That is; going back to the former revision in the wc should restore the contents to the original. The solution should work for both files and dirs. The resolver should not handle moves since we have no way to track those. When I say handle moves I mean "do something about the other end not affected by this conflict". We will apply give the option to apply changes elswehere and do renames but we will leave some files behind for the user to clean up. ### There should be a good way to view what has caused a conflict. ### Perhaps some info from 'svn info'. The tree conflict resolver interface should be consistent with the existing resolver. It should provide {postpone,theirs,mine,diff}-options. ### The user should be able to run the conflict resolver at any time. ### We have to fix libsvn_wc/conflicts.c first. Not really ### specific to this feature. Use cases update/switch ======================== Since we don't know how to follow moves we just leave the add-half as is. The user can remove it manually. Once we have editor-v2 this would work automatically. ### Will it be awkvard to leave the add-half? Will the ### user understand what has happened?. I'm not sure I would! Local add, incoming add ------------------------- THEIRS: Put new BASE file/dir in WORKING. MINE: Keep current WORKING file/dir. RENAME-MINE: Move WORKING file/dir to <user-suggest>. Replace WORKING file/dir with the BASE-TARGET file/dir. MERGE Merge BASE file1 onto WORKING file2. ### There may exist copyfrom info and it may not. How handle the ### different cases? ### We don't want any svn:mergeinfo recorded. Local del, incoming del ------------------------- THEIRS: Nothing to do. MINE: Nothing to do. RENAME: If renamed to two different names. Merge BASE-TARGET <moved> onto WORKING <moved>. ### We need the user to tell us the add-half of a rename until ### editor-v2 is here. Until then <moved> must be a user suggestion. Local del, incoming edit ------------------------- THEIRS: Replace the deleted WORKING file/dir with edited BASE file/dir. MINE: Keep current WORKING file/dir. ELSEWHERE: Merge BASE file/dir onto WORKING <user-suggest>. ### editor-v2 will automatically find a move. No need for this ### option? Local edit, incoming del -------------------------- THEIRS: Delete the file/dir from WORKING and ACTUAL. MINE: Keep current WORKING file/dir. MOVE-MY-MODS: Schedule BASE add-half for addition. Merge WORKING file/dir to add-half. (Must be suggested by user. We can't track add-halfs right now. Use cases merge ======================= ### Should we give a message telling the user to not merge with local ### changes in wc? ### julianf wrote: How can we most easily implement an extension of "svn ### merge" that achieves a copyfrom-history-sensitive diff (between WC ### items) rather than an unaware diff? We often have to do a new merge after the original operation. We want to rename a file/dir or apply changes elsewhere. Then we don't want to use merge-tracking for the subsequent merge operations. More of an implementation issue I guess. Local add, incoming add ------------------------- THEIRS: Replace WORKING with BASE. Merge START to END into WORKING. MINE: Keep current WORKING file/dir. RENAME-MINE: Move WORKING file/dir to <user-suggest>. Merge START to END into WORKING. Local del, incoming del ------------------------- THEIRS: Nothing to do. MINE: Nothing to do. ELSEWHERE: MERGE START to END from THEIRS <user-suggest> into WORKING <user-suggest>. ### This will be handled automatically when we can handle moves. Local del, incoming edit ------------------------- ### Should we need some way to merge with copyfrom info? THEIRS: Copy THEIRS to ACTUAL. Add to WORKING. MINE: Nothing to do. ELSEWHERE1: Merge WORKING add-half onto THEIRS file/dir. Copy THEIRS to WORKING delete-half. ### This is in case of a move with mods. The user would have to ### supply the path to the add-half. Editor-v2 will resolve this ### automatically. ELSEWHERE2: Merge THEIRS file/dir onto WORKING add-half. ### The add-half would have to be supplied by the user. Locale edit, incoming del -------------------------- THEIRS: Remove WORKING file/dir. MINE: Nothing to do. RENAME1: Merge START to END from THEIRS add-half onto WORKING. RENAME2: Merge START to END from WORKING file/dir onto THEIRS add-half. API changes ================== We have -------- 1) We already know which operations has caused the conflict. It's in svn_wc_operation_t. In case some cases will need to differ between sw/up and merge which I think will be the case. 2) We know which type of tree conflict svn_wc_conflict_reason_t, svn_wc_conflict_action_t 3) We have conflict choises already svn_wc_conflict_choise_t { svn_wc_conflict_choose_postpone svn_wc_conflict_choose_base, /* original version */ svn_wc_conflict_choose_theirs_full, /* incoming version */ svn_wc_conflict_choose_mine_full, /* own version */ svn_wc_conflict_choose_theirs_conflict, /* incoming (for conflicted hunks) */ svn_wc_conflict_choose_mine_conflict, /* own (for conflicted hunks) */ svn_wc_conflict_choose_merged /* merged version */ } 4) A code structure for invoking interactive commands, displaying diffs and choosing versions. We need -------- 1) svn_cl__conflict_handler must use svn_wc_conflict_description2_t for some additional tree conflict info. 2) Handle the cases we can in svn_cl__conflict_handler, let the other fall through. (Or return svn_wc_conflict_choose_postpone). I'm thinking of letting all dir conflicts fall through as a first step. 3) Add some choises to svn_wc_conflict_choise_t. svn_wc_conflict_choose_{rename,elsewhere,my_moved_mods}? 4) Add calls to eb->conflict_resolver if check_tree_conflict() returns a conflict in: libsvn_wc/update_editor.c do_entry_deletion() add_directory() open_directory() add_file_with_history() open_file() Or are we supposed to call the conflict resolver after we have done the whole operation? 5) Create code to handle and execute the svn_wc_conflict_choise_t choises. in libsvn_wc/update_editor.c 6) Test to verify the interactive callback. Some detection tests needs to use the --non-interactive flag. 7) It would be nice to be able to store the THEIRS tree in the wc db when we get a tree conflict during a merge operation. User interface ====================== TODO: We need a way to allow the user to tell us the add-half path of a rename. ]]] Daniel