/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 bzrlib/delta.py

  • Committer: Robert Collins
  • Date: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
from __future__ import absolute_import
18
 
 
19
 
from breezy import (
 
17
from bzrlib import (
20
18
    osutils,
21
19
    )
22
 
from .sixish import (
23
 
    StringIO,
24
 
    )
25
 
from .trace import is_quiet
 
20
from bzrlib.trace import is_quiet
26
21
 
27
22
 
28
23
class TreeDelta(object):
66
61
        self.modified = []
67
62
        self.unchanged = []
68
63
        self.unversioned = []
69
 
        self.missing = []
70
64
 
71
65
    def __eq__(self, other):
72
66
        if not isinstance(other, TreeDelta):
112
106
 
113
107
    def get_changes_as_text(self, show_ids=False, show_unchanged=False,
114
108
                            short_status=False):
115
 
        output = StringIO()
 
109
        import StringIO
 
110
        output = StringIO.StringIO()
116
111
        report_delta(output, self, short_status, show_ids, show_unchanged)
117
112
        return output.getvalue()
118
113
 
142
137
            else:
143
138
                delta.removed.append((path[0], file_id, kind[0]))
144
139
        elif fully_present[0] is False:
145
 
            delta.missing.append((path[1], file_id, kind[1]))
 
140
            continue
146
141
        elif name[0] != name[1] or parent_id[0] != parent_id[1]:
147
142
            # If the name changes, or the parent_id changes, we have a rename
148
143
            # (if we move a parent, that doesn't count as a rename for the
165
160
    delta.removed.sort()
166
161
    delta.added.sort()
167
162
    delta.renamed.sort()
168
 
    def missing_key(change):
169
 
        return (change[0] or '', change[1])
170
 
    delta.missing.sort(key=missing_key)
171
163
    # TODO: jam 20060529 These lists shouldn't need to be sorted
172
164
    #       since we added them in alphabetical order.
173
165
    delta.modified.sort()
174
166
    delta.unchanged.sort()
175
 
    delta.unversioned.sort()
176
167
 
177
168
    return delta
178
169
 
181
172
    """Report changes between two trees"""
182
173
 
183
174
    def __init__(self, output=None, suppress_root_add=True,
184
 
                 output_file=None, unversioned_filter=None, view_info=None,
185
 
                 classify=True):
 
175
                 output_file=None, unversioned_filter=None, view_info=None):
186
176
        """Constructor
187
177
 
188
178
        :param output: a function with the signature of trace.note, i.e.
197
187
        :param view_info: A tuple of view_name,view_files if only
198
188
            items inside a view are to be reported on, or None for
199
189
            no view filtering.
200
 
        :param classify: Add special symbols to indicate file kind.
201
190
        """
202
191
        if output_file is not None:
203
192
            if output is not None:
206
195
                output_file.write((fmt % args) + '\n')
207
196
        self.output = output
208
197
        if self.output is None:
209
 
            from . import trace
 
198
            from bzrlib import trace
210
199
            self.output = trace.note
211
200
        self.suppress_root_add = suppress_root_add
212
201
        self.modified_map = {'kind changed': 'K',
213
202
                             'unchanged': ' ',
214
203
                             'created': 'N',
215
204
                             'modified': 'M',
216
 
                             'deleted': 'D',
217
 
                             'missing': '!',
218
 
                             }
 
205
                             'deleted': 'D'}
219
206
        self.versioned_map = {'added': '+', # versioned target
220
207
                              'unchanged': ' ', # versioned in both
221
208
                              'removed': '-', # versioned in source
222
209
                              'unversioned': '?', # versioned in neither
223
210
                              }
224
211
        self.unversioned_filter = unversioned_filter
225
 
        if classify:
226
 
            self.kind_marker = osutils.kind_marker
227
 
        else:
228
 
            self.kind_marker = lambda kind: ''
229
212
        if view_info is None:
230
213
            self.view_name = None
231
214
            self.view_files = []
280
263
            # if the file is not missing in the source, we show its kind
281
264
            # when we show two paths.
282
265
            if kind[0] is not None:
283
 
                old_path += self.kind_marker(kind[0])
 
266
                old_path += osutils.kind_marker(kind[0])
284
267
            old_path += " => "
285
268
        elif versioned == 'removed':
286
269
            # not present in target
295
278
            rename = self.versioned_map[versioned]
296
279
        # we show the old kind on the new path when the content is deleted.
297
280
        if modified == 'deleted':
298
 
            path += self.kind_marker(kind[0])
 
281
            path += osutils.kind_marker(kind[0])
299
282
        # otherwise we always show the current kind when there is one
300
283
        elif kind[1] is not None:
301
 
            path += self.kind_marker(kind[1])
 
284
            path += osutils.kind_marker(kind[1])
302
285
        if exe_change:
303
286
            exe = '*'
304
287
        else:
306
289
        self.output("%s%s%s %s%s", rename, self.modified_map[modified], exe,
307
290
                    old_path, path)
308
291
 
309
 
 
310
292
def report_changes(change_iterator, reporter):
311
293
    """Report the changes from a change iterator.
312
294
 
318
300
    :param reporter: The _ChangeReporter that will report the changes.
319
301
    """
320
302
    versioned_change_map = {
321
 
        (True, True): 'unchanged',
322
 
        (True, False): 'removed',
323
 
        (False, True): 'added',
 
303
        (True, True)  : 'unchanged',
 
304
        (True, False) : 'removed',
 
305
        (False, True) : 'added',
324
306
        (False, False): 'unversioned',
325
307
        }
326
 
    def path_key(change):
327
 
        if change[1][0] is not None:
328
 
            path = change[1][0]
329
 
        else:
330
 
            path = change[1][1]
331
 
        return osutils.splitpath(path)
332
308
    for (file_id, path, content_change, versioned, parent_id, name, kind,
333
 
         executable) in sorted(change_iterator, key=path_key):
 
309
         executable) in change_iterator:
334
310
        exe_change = False
335
311
        # files are "renamed" if they are moved or if name changes, as long
336
312
        # as it had a value
349
325
        else:
350
326
            if content_change:
351
327
                modified = "modified"
352
 
            elif kind[0] is None:
353
 
                modified = "missing"
354
328
            else:
355
329
                modified = "unchanged"
356
330
            if kind[1] == "file":
359
333
        reporter.report(file_id, path, versioned_change, renamed, modified,
360
334
                        exe_change, kind)
361
335
 
362
 
 
363
 
def report_delta(to_file, delta, short_status=False, show_ids=False,
364
 
        show_unchanged=False, indent='', predicate=None, classify=True):
 
336
def report_delta(to_file, delta, short_status=False, show_ids=False, 
 
337
         show_unchanged=False, indent='', filter=None):
365
338
    """Output this delta in status-like form to to_file.
366
339
 
367
340
    :param to_file: A file-like object where the output is displayed.
377
350
    :param indent: Added at the beginning of all output lines (for merged
378
351
        revisions).
379
352
 
380
 
    :param predicate: A callable receiving a path and a file id and
 
353
    :param filter: A callable receiving a path and a file id and
381
354
        returning True if the path should be displayed.
382
 
 
383
 
    :param classify: Add special symbols to indicate file kind.
384
355
    """
385
356
 
386
357
    def decorate_path(path, kind, meta_modified=None):
387
 
        if not classify:
388
 
            return path
389
358
        if kind == 'directory':
390
359
            path += '/'
391
360
        elif kind == 'symlink':
428
397
 
429
398
            for item in files:
430
399
                path, file_id, kind = item[:3]
431
 
                if (predicate is not None and not predicate(path, file_id)):
 
400
                if (filter is not None and not filter(path, file_id)):
432
401
                    continue
433
402
                if not header_shown and not short_status:
434
403
                    to_file.write(indent + long_status_name + ':\n')
443
412
                if show_more is not None:
444
413
                    show_more(item)
445
414
                if show_ids:
446
 
                    to_file.write(' %s' % file_id.decode('utf-8'))
 
415
                    to_file.write(' %s' % file_id)
447
416
                to_file.write('\n')
448
417
 
449
418
    show_list(delta.removed, 'removed', 'D')
450
419
    show_list(delta.added, 'added', 'A')
451
 
    show_list(delta.missing, 'missing', '!')
452
420
    extra_modified = []
453
421
    # Reorder delta.renamed tuples so that all lists share the same
454
422
    # order for their 3 first fields and that they also begin like