sageserpent-open / kineticMerge

Merge a heavily refactored codebase and stay sane.
MIT License
9 stars 1 forks source link

User can resolve divergent code motion. #6

Open sageserpent-open opened 1 year ago

sageserpent-open commented 1 year ago

When code motion of the same section occurs on both branches but leads to different destinations, then there is a divergence. This is a separate notion from that of a conflict, where the same section of code in a potentially merged file would have different edits from the two branches - here the destination itself is in question.

In simple cases it might be possible to represent divergences by making two separate conflict entries, one at each location such that one side of the conflict contains the moved code and the other is empty. The problem is that if there are edits involved in both branches that cannot be cleanly merged, then we have to represent a conflict inside a conflict to model this - and that is not feasible with existing tools (and would be an eyesore anyway).

Kinetic Merge should prompt the user to manually resolve divergence prior to attempting merges. If divergences are detected, they are presented via console output and resolved in a command line session (or the entire merge is aborted, leaving the repository in the state prior to attempting merging).

Code motion divergence can be resolved by selecting either 'our' destination, 'their' destination, or treating the two moves as independent edits, essentially copying each branch's idea of the code (and thus avoiding merging the edits from both branches together). One last variation is to duplicate the merge and send it to both destinations as copies. Hmm.

In order to make it clearer what's going on, Kinetic Merge should should a divergence in the format: <file>, <line> [- <line>] <--- <file>, <line> [- <line>] ---> <file>, <line> [- <line>]

A given code movement can be inspected as a context diff of the code in at its destination, the diff content providing some idea of how the code looks there with just the changes contributed by the branch that wants to move to that destination. The context lines provide an indication of where the content has been moved to.

The section of code that has moved should also be viewed as a three-way merge in isolation - this permits inspection of the code and also of any conflicts that would arise in an accepted move. The diff3 merged output is used for this.

sageserpent-open commented 1 year ago

Given divergences are detected, then the user is presented with an indication that this has happened and needs resolving.

A numbered list of divergences is shown, each being marked as unresolved.

Until all divergences have been resolved or the merge is aborted, Kinetic merge will keep prompting.

Commands are entered followed by 'ENTER', these are:

Command Meaning
<divergence number>|Focus on a specific divergence; the divergence is shown as [UN]RESOLVED: <file>, <line> [- <line>] <--- <file>, <line> [- <line>] ---> <file>, <line> [- <line>] in response
al Accept left move or deletion
ar Accept right move or deletion
cl Print context diff of left move with just the left branch's changes
cr Print context diff of right move with just the right branch's changes
+|Increase lines of context for diff of previous c command
-|Decrease lines of context for diff of previous c command
s Split left and right moves into independent edits with changes confined to the respective branch - not applicable for a move versus deletion divergence
w|Three way diff - hopefully the w looks a bit like a trident, a metaphor for a three-way edit view
n Focus on next divergence
p Focus on previous divergence
u List all unresolved divergences
r List all resolved divergences
d List all divergences, showing whether each is resolved or unresolved, like at the beginning of the session
ENTER Show current divergence
q Quit the entire merge
h Help - show this documentation for the command set

Typing incomplete command stems leaves the prompt waiting to complete the command.

The user is stuck in this command mode until they explicitly decide to quit via q - this gives them a chance to review and redo any divergence resolution, so one can cycle between al, ar and s for the same divergence. It is not possible, nor is it necessary to undo a resolution, as the only way to complete a merge is to choose one of the permitted resolution methods.

If there are unresolved divergences, the user should be prompted to confirm that the merge should be aborted and the repository left in the same state as prior to attempting the merge.

If all divergences are resolved, the user should be prompted to confirm that the resolutions are good.

NOTE: The terminology used here is left for 'our' branch and right for 'their' branch - this seems to fit the implied visual metaphor better, rather than 'ours' and 'theirs' as per the Git merge documentation.

sageserpent-open commented 1 year ago

For now, the three-way diff output is in the same format as in the default for git merge. There should be another story for configuring diff3 or zdiff3 style.

sageserpent-open commented 2 months ago

See here for some thoughts on resolution of divergence: https://github.com/sageserpent-open/kineticMerge/issues/37#issuecomment-2061420545.