Thursday, May 19, 2011

Why Subversion conflict resolution suxx?

Because conflict resolution choice is confusing (for non-English natives for sure):
$ svn up
U    bitten\
G    bitten\tests\
Conflict discovered in 'bitten/'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options:

Should you select "theirs conflict" or "mine confict" to fix your code? In situation when you feel that incoming change is right you may want to select "mine conflict" as the change that conflicts and should be removed as a result. But the correct answer it to select "theirs conflict" as the change to be incorporated in your code. Subversion developers think that you're are not removing conflicts, but incorporating them into your code. If they could think of user action - it is removing or resolving conflict in high-level terminology, or selecting correct change in low-level description.

Let's see the help:
Conflict discovered in 'bitten/'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: s
  (e)  edit             - change merged file in an editor
  (df) diff-full        - show all changes made to merged file
  (r)  resolved         - accept merged version of file
  (dc) display-conflict - show all conflicts (ignoring merged version)
  (mc) mine-conflict    - accept my version for all conflicts (same)
  (tc) theirs-conflict  - accept their version for all conflicts (same)
  (mf) mine-full        - accept my version of entire file (even non-conflicts)
  (tf) theirs-full      - accept their version of entire file (same)
  (p)  postpone         - mark the conflict to be resolved later
  (l)  launch           - launch external tool to resolve conflict
  (s)  show all         - show this list

Frankly, I can't understand how (mc) is different from (mf) if both versions accept all changes. (same) marker doesn't add much sense either. But even if help doesn't describe anything - these options were still added for a reason, and if we meditate a bit on them starting from the bottom comment to (mf) help, it becomes clear that:

1. (mf) throws away any incoming changes for the given file even if some of them were merged successfully
2. that means (mc) probably keeps the changes that were merged successfully
3. that means (df) shows more changes than (dc) output

Recommendations? Introduce `change` and `conflict` terminology earlier, i.e. show info like `3 changes, 2 conflicts`. It will also allow incremental conflict resolution, like if you (e)dited the counter is changed to `4 changes, 1 conflict` etc. Final recommendation if to replace `(ignoring merged version)` with `(ignoring merged changes)` string. There are surely more ways to improve this.