[MERGE] Status should not special case conflicts

Aaron Bentley aaron.bentley at utoronto.ca
Mon Jul 24 15:05:34 BST 2006


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Here's where my thinking on conflicts has gotten to.

RevisionTrees are an idealized state.  With a RevisionTree, we know the
following things
 - The ID of each file
 - The name of each file
 - The parent directory of each file
 - The contents of each file

I will refer to this as the "contents state".

The contents state is a useful simplification.  It makes many operations
simpler to express and evaluate.

A working tree must account for more possibilities, because we do not
always know the contents state.  Whenever we do not know an aspect of
the contents state, we emit a conflict.  Therefore, if conflicts are
present, we do not know the contents state.

Our tree comparison functionality compares the data used by the contents
state.  When conflicts are present, this comparison is not, strictly, sane.

Consider a merge that produces a conflict in a symlink.  The symlink may
have the value 't/foo', or it may have the value 'r/bar', or perhaps
they should be combined as 't/bar' or 'r/foo'.  Our merger isn't smart
enough to know what the contents of the symlink should be.

The merge will emit symlink.BASE, symlink.THIS and symlink.OTHER.  The
file-id is assigned to symlink.OTHER.  This is an asymmetry of merge.
Where we must choose between THIS and OTHER, we choose OTHER, because it
 shows the maximum differences, and because it is generally easier to
revert the change to THIS, should the user choose that.

So, we have symlink.OTHER, but theoretically, we could just as easily
have symlink.THIS.  We need to store the file-id someplace, so we choose
OTHER, but this does not represent a decision that symlink.OTHER is in
fact correct.

Now, when we compare our tree to another tree, the comparison is made
against symlink.OTHER, regardless of the fact that symlink.THIS is just
as valid.  So, since this comparison is a comparison of contents state,
we need to indicate the fact that we don't actually have contents state
in our tree, which we do by listing all of the conflict state.

So conflict state should be treated as an indication that the contents
comparison is flawed.  Useful, perhaps, but flawed.

When comparing two trees that both have conflicts there may be four
possible comparisons to be made, and none is theoretically superior to
another:

a/symlink.OTHER vs b/symlink.OTHER
a/symlink.THIS vs b/symlink.THIS
a/symlink.OTHER vs b/symlink.THIS
a/symlink.THIS vs b/symlink.OTHER

However, what we actually get is
a/symlink.OTHER vs b/symlink.OTHER

If we were to compare conflicts as well, we would emit no conflicts,
because both trees have a conflict for symlink.  This is wrong, because
neither tree has unambiguous contents state.

In fact, we should emit conflicts each tree, because they are metadata
that indicate the flaws in the comparison.  It would be an error to
compare the conflicts in two trees, because that would reduce the number
of conflicts shown.

To return to your original concern, none of this means that you can't
avoid double handling when comparing trees for status.

But rather than comparing conflicts, you can simply add two members to
the delta object: this_conflicts and other_conflicts.

Similarly to diff, merge operates on contents state.  When there are
conflicts present, merge cannot produce reasonable results, so it should
not proceed.  Thus, in WorkingTree.update, it's not valid to do two
merges in a row, if the first merge produces conflicts.

I'm not as certain now that RevisionTree.conflicts is a bad idea.

Do-nothing methods that increase generality aren't something I see as
universally good or bad.  There are clear advantages to reducing the
number of code paths, but on the other hand, if RevisionTree didn't
provide conflicts(), then we would detect cases where we were
inappropriately treating a RevisionTree as a WorkingTree more easily.

Aaron
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFExNOu0F+nu1YWqI0RAiK5AJwIVb8Xh9AiFq7092Gs9sN3E4bFxwCfZZQ+
DEs4TCPRoE4C6Oo2871+D/0=
=eJM3
-----END PGP SIGNATURE-----




More information about the bazaar mailing list