~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

  • Committer: John Arbash Meinel
  • Date: 2008-07-11 21:28:36 UTC
  • mto: This revision was merged to the branch mainline in revision 3543.
  • Revision ID: john@arbash-meinel.com-20080711212836-1ehghrnzgaioqwou
Handle more edge cases.

Specifically, we don't have to switch on the whole-ancestry logic until we have
3 or more LCAs, we were doing it when there was 2.
However, when we do switch on the whole ancestry logic, it is possible to
get extra 'tails' which have ancestors that are in the ancestry of the
unique lca, but they themselves do not terminate on the unique lca.
The current code is a bit of a compromise, as we probably should chase down
more nodes to include. If we include more than 1 lca, then we run into the
same problem, where common lines have to have one side 'win' and the other 'lose'.
A different possibility would be to create an artificial ancestor node,
which uses the common lines from the different LCAs, so that it is assumed they
all come from the same source. This would end up ignoring cases where changes
were reverted and then reintroduced.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1449
1449
            elif len(next_lcas) == 1:
1450
1450
                parent_map[list(next_lcas)[0]] = ()
1451
1451
                break
1452
 
            else:
 
1452
            elif len(next_lcas) > 2:
1453
1453
                # More than 2 lca's, fall back to grabbing all nodes between
1454
1454
                # this and the unique lca.
1455
1455
                mutter('More than 2 LCAs, falling back to all nodes for: %s',
1492
1492
            parent_map = self.graph.get_parent_map(interesting)
1493
1493
            parent_map[base_key] = ()
1494
1494
        culled_parent_map = {}
 
1495
        extra_base_ancestors = set()
1495
1496
        for key, parent_keys in parent_map.iteritems():
1496
1497
            culled_parent_keys = tuple([p for p in parent_keys
1497
1498
                                           if p in parent_map])
 
1499
            if not culled_parent_keys and key is not base_key:
 
1500
                # We have another 'tail', make sure to bring it into the
 
1501
                # ancestry, so that we don't think all of its lines are unique.
 
1502
                lcas = self.graph.find_lca(key, base_key)
 
1503
                if lcas == set([NULL_REVISION]):
 
1504
                    lcas = ()
 
1505
                if len(lcas) == 0:
 
1506
                    # Nothing to do, no common ancestor
 
1507
                    pass
 
1508
                else:
 
1509
                    # Technically, this isn't 100% correct, but it is better
 
1510
                    # than nothing. If we have more than 1 LCA, we probably
 
1511
                    # should keep tracking the rabbit down the hole, so that we
 
1512
                    # get proper annotations for lines.  For now, though, we
 
1513
                    # just add the first lca, and live with it
 
1514
                    lca = list(lcas)[0]
 
1515
                    extra_base_ancestors.add(lca)
 
1516
                    culled_parent_keys = (lca,)
 
1517
                    if lca not in culled_parent_map:
 
1518
                        culled_parent_map[lca] = ()
1498
1519
            culled_parent_map[key] = culled_parent_keys
 
1520
        if extra_base_ancestors:
 
1521
            culled_parent_map[base_key] = self.graph.find_merge_order(base_key,
 
1522
                                                            extra_base_ancestors)
1499
1523
        return culled_parent_map
1500
1524
 
1501
1525
    def _get_interesting_texts(self, parent_map):