/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/patiencediff.py

  • Committer: Jelmer Vernooij
  • Date: 2019-02-04 01:01:24 UTC
  • mto: This revision was merged to the branch mainline in revision 7268.
  • Revision ID: jelmer@jelmer.uk-20190204010124-ni0i4qc6f5tnbvux
Fix source tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
 
 
18
from __future__ import absolute_import
18
19
 
19
 
from bzrlib.lazy_import import lazy_import
 
20
from .lazy_import import lazy_import
20
21
lazy_import(globals(), """
21
22
import os
22
23
import sys
25
26
""")
26
27
 
27
28
 
28
 
__all__ = ['PatienceSequenceMatcher', 'unified_diff', 'unified_diff_files']
 
29
__all__ = ['PatienceSequenceMatcher', 'unified_diff', 'unified_diff_bytes',
 
30
           'unified_diff_files']
29
31
 
30
32
 
31
33
# This is a version of unified_diff which only adds a factory parameter
73
75
     four
74
76
    """
75
77
    if sequencematcher is None:
76
 
        import difflib
77
78
        sequencematcher = difflib.SequenceMatcher
78
79
 
79
80
    if fromfiledate:
82
83
        tofiledate = '\t' + str(tofiledate)
83
84
 
84
85
    started = False
85
 
    for group in sequencematcher(None,a,b).get_grouped_opcodes(n):
 
86
    for group in sequencematcher(None, a, b).get_grouped_opcodes(n):
86
87
        if not started:
87
88
            yield '--- %s%s%s' % (fromfile, fromfiledate, lineterm)
88
89
            yield '+++ %s%s%s' % (tofile, tofiledate, lineterm)
89
90
            started = True
90
91
        i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]
91
 
        yield "@@ -%d,%d +%d,%d @@%s" % (i1+1, i2-i1, j1+1, j2-j1, lineterm)
 
92
        yield "@@ -%d,%d +%d,%d @@%s" % (i1 + 1, i2 - i1, j1 + 1, j2 - j1, lineterm)
92
93
        for tag, i1, i2, j1, j2 in group:
93
94
            if tag == 'equal':
94
95
                for line in a[i1:i2]:
102
103
                    yield '+' + line
103
104
 
104
105
 
 
106
def unified_diff_bytes(a, b, fromfile=b'', tofile=b'', fromfiledate=b'',
 
107
                       tofiledate=b'', n=3, lineterm=b'\n', sequencematcher=None):
 
108
    r"""
 
109
    Compare two sequences of lines; generate the delta as a unified diff.
 
110
 
 
111
    Unified diffs are a compact way of showing line changes and a few
 
112
    lines of context.  The number of context lines is set by 'n' which
 
113
    defaults to three.
 
114
 
 
115
    By default, the diff control lines (those with ---, +++, or @@) are
 
116
    created with a trailing newline.  This is helpful so that inputs
 
117
    created from file.readlines() result in diffs that are suitable for
 
118
    file.writelines() since both the inputs and outputs have trailing
 
119
    newlines.
 
120
 
 
121
    For inputs that do not have trailing newlines, set the lineterm
 
122
    argument to "" so that the output will be uniformly newline free.
 
123
 
 
124
    The unidiff format normally has a header for filenames and modification
 
125
    times.  Any or all of these may be specified using strings for
 
126
    'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.  The modification
 
127
    times are normally expressed in the format returned by time.ctime().
 
128
 
 
129
    Example:
 
130
 
 
131
    >>> for line in bytes_unified_diff(b'one two three four'.split(),
 
132
    ...             b'zero one tree four'.split(), b'Original', b'Current',
 
133
    ...             b'Sat Jan 26 23:30:50 1991', b'Fri Jun 06 10:20:52 2003',
 
134
    ...             lineterm=b''):
 
135
    ...     print line
 
136
    --- Original Sat Jan 26 23:30:50 1991
 
137
    +++ Current Fri Jun 06 10:20:52 2003
 
138
    @@ -1,4 +1,4 @@
 
139
    +zero
 
140
     one
 
141
    -two
 
142
    -three
 
143
    +tree
 
144
     four
 
145
    """
 
146
    if sequencematcher is None:
 
147
        sequencematcher = difflib.SequenceMatcher
 
148
 
 
149
    if fromfiledate:
 
150
        fromfiledate = b'\t' + bytes(fromfiledate)
 
151
    if tofiledate:
 
152
        tofiledate = b'\t' + bytes(tofiledate)
 
153
 
 
154
    started = False
 
155
    for group in sequencematcher(None, a, b).get_grouped_opcodes(n):
 
156
        if not started:
 
157
            yield b'--- %s%s%s' % (fromfile, fromfiledate, lineterm)
 
158
            yield b'+++ %s%s%s' % (tofile, tofiledate, lineterm)
 
159
            started = True
 
160
        i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]
 
161
        yield b"@@ -%d,%d +%d,%d @@%s" % (i1 + 1, i2 - i1, j1 + 1, j2 - j1, lineterm)
 
162
        for tag, i1, i2, j1, j2 in group:
 
163
            if tag == 'equal':
 
164
                for line in a[i1:i2]:
 
165
                    yield b' ' + line
 
166
                continue
 
167
            if tag == 'replace' or tag == 'delete':
 
168
                for line in a[i1:i2]:
 
169
                    yield b'-' + line
 
170
            if tag == 'replace' or tag == 'insert':
 
171
                for line in b[j1:j2]:
 
172
                    yield b'+' + line
 
173
 
 
174
 
105
175
def unified_diff_files(a, b, sequencematcher=None):
106
176
    """Generate the diff for two files.
107
177
    """
123
193
        time_b = os.stat(b).st_mtime
124
194
 
125
195
    # TODO: Include fromfiledate and tofiledate
126
 
    return unified_diff(file_a.readlines(), file_b.readlines(),
127
 
                        fromfile=a, tofile=b,
128
 
                        sequencematcher=sequencematcher)
 
196
    return unified_diff_bytes(file_a.readlines(), file_b.readlines(),
 
197
                              fromfile=a, tofile=b,
 
198
                              sequencematcher=sequencematcher)
129
199
 
130
200
 
131
201
try:
132
 
    from bzrlib._patiencediff_c import (
 
202
    from ._patiencediff_c import (
133
203
        unique_lcs_c as unique_lcs,
134
204
        recurse_matches_c as recurse_matches,
135
205
        PatienceSequenceMatcher_c as PatienceSequenceMatcher
136
206
        )
137
207
except ImportError:
138
 
    from bzrlib._patiencediff_py import (
 
208
    from ._patiencediff_py import (
139
209
        unique_lcs_py as unique_lcs,
140
210
        recurse_matches_py as recurse_matches,
141
211
        PatienceSequenceMatcher_py as PatienceSequenceMatcher
142
 
        )
 
212
        )  # noqa: F401
143
213
 
144
214
 
145
215
def main(args):
151
221
    p.add_option('--difflib', dest='matcher', action='store_const', const='difflib',
152
222
                 default='patience', help='Use python\'s difflib algorithm')
153
223
 
154
 
    algorithms = {'patience':PatienceSequenceMatcher, 'difflib':difflib.SequenceMatcher}
 
224
    algorithms = {'patience': PatienceSequenceMatcher,
 
225
                  'difflib': difflib.SequenceMatcher}
155
226
 
156
227
    (opts, args) = p.parse_args(args)
157
228
    matcher = algorithms[opts.matcher]
158
229
 
159
230
    if len(args) != 2:
160
 
        print 'You must supply 2 filenames to diff'
 
231
        print('You must supply 2 filenames to diff')
161
232
        return -1
162
233
 
163
234
    for line in unified_diff_files(args[0], args[1], sequencematcher=matcher):