/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5273.1.5 by Vincent Ladeuil
Merge bzr.dev into cleanup
1
# Copyright (C) 2006, 2009, 2010 Canonical Ltd
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
16
#
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
17
# Author: Martin Pool <mbp@canonical.com>
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
18
#         Aaron Bentley <aaron.bentley@utoronto.ca>
19
6379.6.3 by Jelmer Vernooij
Use absolute_import.
20
from __future__ import absolute_import
1551.6.13 by Aaron Bentley
Cleanup
21
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
22
from .lazy_import import lazy_import
5279.1.1 by Andrew Bennetts
lazy_import most things in merge.py; add a few representative modules to the import tariff tests; tweak a couple of other modules so that patiencediff is not necessarily imported; remove a bunch of unused imports from test_knit.py.
23
lazy_import(globals(), """
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
24
from breezy import patiencediff
5279.1.1 by Andrew Bennetts
lazy_import most things in merge.py; add a few representative modules to the import tariff tests; tweak a couple of other modules so that patiencediff is not necessarily imported; remove a bunch of unused imports from test_knit.py.
25
""")
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
26
27
28
class TextMerge(object):
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
29
    """Base class for text-mergers
30
    Subclasses must implement _merge_struct.
1551.6.13 by Aaron Bentley
Cleanup
31
32
    Many methods produce or consume structured merge information.
33
    This is an iterable of tuples of lists of lines.
34
    Each tuple may have a length of 1 - 3, depending on whether the region it
35
    represents is conflicted.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
36
1551.6.13 by Aaron Bentley
Cleanup
37
    Unconflicted region tuples have length 1.
38
    Conflicted region tuples have length 2 or 3.  Index 1 is text_a, e.g. THIS.
39
    Index 1 is text_b, e.g. OTHER.  Index 2 is optional.  If present, it
40
    represents BASE.
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
41
    """
1551.6.13 by Aaron Bentley
Cleanup
42
    # TODO: Show some version information (e.g. author, date) on conflicted
43
    # regions.
6963.2.10 by Jelmer Vernooij
Fix a bunch of tests.
44
    A_MARKER = b'<<<<<<< \n'
45
    B_MARKER = b'>>>>>>> \n'
46
    SPLIT_MARKER = b'=======\n'
7143.15.2 by Jelmer Vernooij
Run autopep8.
47
1551.6.14 by Aaron Bentley
Tweaks from merge review
48
    def __init__(self, a_marker=A_MARKER, b_marker=B_MARKER,
49
                 split_marker=SPLIT_MARKER):
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
50
        self.a_marker = a_marker
51
        self.b_marker = b_marker
52
        self.split_marker = split_marker
53
1551.6.14 by Aaron Bentley
Tweaks from merge review
54
    def _merge_struct(self):
55
        """Return structured merge info.  Must be implemented by subclasses.
56
        See TextMerge docstring for details on the format.
57
        """
58
        raise NotImplementedError('_merge_struct is abstract')
59
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
60
    def struct_to_lines(self, struct_iter):
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
61
        """Convert merge result tuples to lines"""
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
62
        for lines in struct_iter:
63
            if len(lines) == 1:
64
                for line in lines[0]:
65
                    yield line
66
            else:
67
                yield self.a_marker
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
68
                for line in lines[0]:
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
69
                    yield line
70
                yield self.split_marker
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
71
                for line in lines[1]:
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
72
                    yield line
73
                yield self.b_marker
74
75
    def iter_useful(self, struct_iter):
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
76
        """Iterate through input tuples, skipping empty ones."""
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
77
        for group in struct_iter:
78
            if len(group[0]) > 0:
79
                yield group
80
            elif len(group) > 1 and len(group[1]) > 0:
81
                yield group
82
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
83
    def merge_lines(self, reprocess=False):
1551.6.14 by Aaron Bentley
Tweaks from merge review
84
        """Produce an iterable of lines, suitable for writing to a file
1551.6.13 by Aaron Bentley
Cleanup
85
        Returns a tuple of (line iterable, conflict indicator)
86
        If reprocess is True, a two-way merge will be performed on the
87
        intermediate structure, to reduce conflict regions.
88
        """
1551.6.11 by Aaron Bentley
Switched TextMerge_lines to work on a list
89
        struct = []
1551.6.12 by Aaron Bentley
Indicate conflicts from merge_lines, insead of guessing
90
        conflicts = False
1551.6.11 by Aaron Bentley
Switched TextMerge_lines to work on a list
91
        for group in self.merge_struct(reprocess):
92
            struct.append(group)
1551.6.12 by Aaron Bentley
Indicate conflicts from merge_lines, insead of guessing
93
            if len(group) > 1:
94
                conflicts = True
95
        return self.struct_to_lines(struct), conflicts
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
96
97
    def merge_struct(self, reprocess=False):
1551.6.13 by Aaron Bentley
Cleanup
98
        """Produce structured merge info"""
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
99
        struct_iter = self.iter_useful(self._merge_struct())
100
        if reprocess is True:
101
            return self.reprocess_struct(struct_iter)
102
        else:
103
            return struct_iter
104
105
    @staticmethod
106
    def reprocess_struct(struct_iter):
1551.6.14 by Aaron Bentley
Tweaks from merge review
107
        """ Perform a two-way merge on structural merge info.
1551.6.13 by Aaron Bentley
Cleanup
108
        This reduces the size of conflict regions, but breaks the connection
1551.6.14 by Aaron Bentley
Tweaks from merge review
109
        between the BASE text and the conflict region.
1551.6.13 by Aaron Bentley
Cleanup
110
111
        This process may split a single conflict region into several smaller
112
        ones, but will not introduce new conflicts.
113
        """
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
114
        for group in struct_iter:
115
            if len(group) == 1:
116
                yield group
117
            else:
118
                for newgroup in Merge2(group[0], group[1]).merge_struct():
119
                    yield newgroup
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
120
121
122
class Merge2(TextMerge):
1551.6.14 by Aaron Bentley
Tweaks from merge review
123
    """ Two-way merge.
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
124
    In a two way merge, common regions are shown as unconflicting, and uncommon
125
    regions produce conflicts.
126
    """
1551.6.13 by Aaron Bentley
Cleanup
127
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
128
    def __init__(self, lines_a, lines_b, a_marker=TextMerge.A_MARKER,
129
                 b_marker=TextMerge.B_MARKER,
1551.6.14 by Aaron Bentley
Tweaks from merge review
130
                 split_marker=TextMerge.SPLIT_MARKER):
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
131
        TextMerge.__init__(self, a_marker, b_marker, split_marker)
132
        self.lines_a = lines_a
133
        self.lines_b = lines_b
134
135
    def _merge_struct(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
136
        """Return structured merge info.
1551.6.13 by Aaron Bentley
Cleanup
137
        See TextMerge docstring.
138
        """
5279.1.1 by Andrew Bennetts
lazy_import most things in merge.py; add a few representative modules to the import tariff tests; tweak a couple of other modules so that patiencediff is not necessarily imported; remove a bunch of unused imports from test_knit.py.
139
        sm = patiencediff.PatienceSequenceMatcher(
140
            None, self.lines_a, self.lines_b)
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
141
        pos_a = 0
142
        pos_b = 0
143
        for ai, bi, l in sm.get_matching_blocks():
144
            # non-matching lines
145
            yield(self.lines_a[pos_a:ai], self.lines_b[pos_b:bi])
146
            # matching lines
7143.15.2 by Jelmer Vernooij
Run autopep8.
147
            yield(self.lines_a[ai:ai + l],)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
148
            pos_a = ai + l
1551.6.7 by Aaron Bentley
Implemented two-way merge, refactored weave merge
149
            pos_b = bi + l
150
        # final non-matching lines
151
        yield(self.lines_a[pos_a:-1], self.lines_b[pos_b:-1])