~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_annotator_py.py

  • Committer: John Arbash Meinel
  • Date: 2009-06-17 20:32:50 UTC
  • mto: This revision was merged to the branch mainline in revision 4522.
  • Revision ID: john@arbash-meinel.com-20090617203250-x0v6nnrrk7j4z173
New work on how to resolve conflict lines.

The new code doesn't try to do much resolution. All it does is
claim that both parents introduced the text. The conflict resolution
can be done just before displaying, rather than while building
up the annotations.
At least, that is the current idea.

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
            self._heads_provider = _mod_graph.KnownGraph(self._parent_map)
54
54
        return self._heads_provider
55
55
 
56
 
    def _reannotate_one_parent(self, annotations, lines, key, parent_key):
57
 
        """Reannotate this text relative to its first parent."""
 
56
    def _get_parent_annotations_and_matches(self, lines, parent_key):
58
57
        parent_lines = self._lines_cache[parent_key]
59
58
        parent_annotations = self._annotations_cache[parent_key]
60
59
        # PatienceSequenceMatcher should probably be part of Policy
61
60
        matcher = patiencediff.PatienceSequenceMatcher(None,
62
61
            parent_lines, lines)
63
62
        matching_blocks = matcher.get_matching_blocks()
 
63
        return parent_annotations, matching_blocks
 
64
 
 
65
    def _reannotate_one_parent(self, annotations, lines, key, parent_key):
 
66
        """Reannotate this text relative to its first parent."""
 
67
        parent_annotations, matching_blocks = self._get_parent_annotations_and_matches(
 
68
            lines, parent_key)
64
69
 
65
70
        for parent_idx, lines_idx, match_len in matching_blocks:
66
71
            # For all matching regions we copy across the parent annotations
67
72
            annotations[lines_idx:lines_idx + match_len] = \
68
73
                parent_annotations[parent_idx:parent_idx + match_len]
69
74
 
 
75
    def _reannotate_other_parents(self, annotations, lines, key, parent_key):
 
76
        """Reannotate this text relative to a second (or more) parent."""
 
77
        parent_annotations, matching_blocks = self._get_parent_annotations_and_matches(
 
78
            lines, parent_key)
 
79
 
 
80
        simple_key_ann = (key,)
 
81
        for parent_idx, lines_idx, match_len in matching_blocks:
 
82
            # For lines which match this parent, we will now resolve whether
 
83
            # this parent wins over the current annotation
 
84
            for idx in xrange(match_len):
 
85
                ann_idx = lines_idx + idx
 
86
                ann = annotations[ann_idx]
 
87
                par_ann = parent_annotations[parent_idx + idx]
 
88
                if ann == par_ann:
 
89
                    # Nothing to change
 
90
                    continue
 
91
                if ann == simple_key_ann:
 
92
                    # Originally claimed 'this', but it was really in this
 
93
                    # parent
 
94
                    annotations[ann_idx] = par_ann
 
95
                    continue
 
96
                # Now we have a conflict, both sides claim to have introduced
 
97
                # this line
 
98
                new_ann = set(ann)
 
99
                assert key not in new_ann
 
100
                # new_ann.discard(key)
 
101
                new_ann.update(par_ann)
 
102
                new_ann = tuple(sorted(new_ann))
 
103
                annotations[ann_idx] = new_ann
 
104
 
70
105
    def annotate(self, key):
71
106
        """Return annotated fulltext for the given key."""
72
107
        keys = self._get_needed_texts(key)
82
117
            if not parents:
83
118
                continue
84
119
            self._reannotate_one_parent(annotations, lines, key, parents[0])
 
120
            for parent in parents[1:]:
 
121
                self._reannotate_other_parents(annotations, lines, key, parent)
85
122
        try:
86
123
            annotations = self._annotations_cache[key]
87
124
        except KeyError: