[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[RFC] Tree conflict resolver spec.

From: Daniel Näslund <daniel_at_longitudo.com>
Date: Fri, 22 Jan 2010 12:12:26 +0100

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
Received on 2010-01-22 12:13:06 CET

This is an archived mail posted to the Subversion Dev mailing list.