33
36
        (oldpath, newpath, id, kind, text_modified, meta_modified)
 
35
 
        (path, id, old_kind, new_kind)
 
37
38
        (path, id, kind, text_modified, meta_modified)
 
43
44
    Each id is listed only once.
 
45
46
    Files that are both modified and renamed are listed only in
 
46
47
    renamed, with the text_modified flag true. The text_modified
 
47
 
    applies either to the content of the file or the target of the
 
 
48
    applies either to the the content of the file or the target of the
 
48
49
    symbolic link, depending of the kind of file.
 
50
51
    Files are only considered renamed if their name has changed or
 
 
103
104
            if v[1] == file_id:
 
 
109
    def show(self, to_file, show_ids=False, show_unchanged=False,
 
 
110
             short_status=False, indent=''):
 
 
111
        """output this delta in status-like form to to_file."""
 
 
112
        def show_list(files, short_status_letter=''):
 
 
114
                path, fid, kind = item[:3]
 
 
116
                if kind == 'directory':
 
 
118
                elif kind == 'symlink':
 
 
121
                if len(item) == 5 and item[4]:
 
 
125
                    to_file.write(indent + '%s  %-30s %s\n' % (short_status_letter,
 
 
128
                    to_file.write(indent + '%s  %s\n' % (short_status_letter, path))
 
 
132
                to_file.write(indent + 'removed:\n')
 
 
133
                show_list(self.removed)
 
 
135
                show_list(self.removed, 'D')
 
 
139
                to_file.write(indent + 'added:\n')
 
 
140
                show_list(self.added)
 
 
142
                show_list(self.added, 'A')
 
 
147
            short_status_letter = 'R'
 
 
149
                to_file.write(indent + 'renamed:\n')
 
 
150
                short_status_letter = ''
 
 
151
            for (oldpath, newpath, fid, kind,
 
 
152
                 text_modified, meta_modified) in self.renamed:
 
 
153
                if text_modified or meta_modified:
 
 
154
                    extra_modified.append((newpath, fid, kind,
 
 
155
                                           text_modified, meta_modified))
 
 
159
                    to_file.write(indent + '%s  %s => %s %s\n' % (
 
 
160
                        short_status_letter, oldpath, newpath, fid))
 
 
162
                    to_file.write(indent + '%s  %s => %s\n' % (
 
 
163
                        short_status_letter, oldpath, newpath))
 
 
165
        if self.kind_changed:
 
 
167
                short_status_letter = 'K'
 
 
169
                to_file.write(indent + 'kind changed:\n')
 
 
170
                short_status_letter = ''
 
 
171
            for (path, fid, old_kind, new_kind) in self.kind_changed:
 
 
176
                to_file.write(indent + '%s  %s (%s => %s)%s\n' % (
 
 
177
                    short_status_letter, path, old_kind, new_kind, suffix))
 
 
179
        if self.modified or extra_modified:
 
 
180
            short_status_letter = 'M'
 
 
182
                to_file.write(indent + 'modified:\n')
 
 
183
                short_status_letter = ''
 
 
184
            show_list(self.modified, short_status_letter)
 
 
185
            show_list(extra_modified, short_status_letter)
 
 
187
        if show_unchanged and self.unchanged:
 
 
189
                to_file.write(indent + 'unchanged:\n')
 
 
190
                show_list(self.unchanged)
 
 
192
                show_list(self.unchanged, 'S')
 
 
195
            to_file.write(indent + 'unknown:\n')
 
 
196
            show_list(self.unversioned)
 
107
198
    def get_changes_as_text(self, show_ids=False, show_unchanged=False,
 
110
201
        output = StringIO.StringIO()
 
111
 
        report_delta(output, self, short_status, show_ids, show_unchanged)
 
 
202
        self.show(output, show_ids, show_unchanged, short_status)
 
112
203
        return output.getvalue()
 
 
209
298
                              'unversioned': '?', # versioned in neither
 
211
300
        self.unversioned_filter = unversioned_filter
 
212
 
        if view_info is None:
 
213
 
            self.view_name = None
 
216
 
            self.view_name = view_info[0]
 
217
 
            self.view_files = view_info[1]
 
218
 
            self.output("Operating on whole tree but only reporting on "
 
219
 
                        "'%s' view." % (self.view_name,))
 
221
302
    def report(self, file_id, paths, versioned, renamed, modified, exe_change,
 
223
304
        """Report one change to a file
 
225
306
        :param file_id: The file_id of the file
 
226
 
        :param path: The old and new paths as generated by Tree.iter_changes.
 
 
307
        :param path: The old and new paths as generated by Tree._iter_changes.
 
227
308
        :param versioned: may be 'added', 'removed', 'unchanged', or
 
229
310
        :param renamed: may be True or False
 
230
311
        :param modified: may be 'created', 'deleted', 'kind changed',
 
231
312
            'modified' or 'unchanged'.
 
232
313
        :param exe_change: True if the execute bit has changed
 
233
 
        :param kind: A pair of file kinds, as generated by Tree.iter_changes.
 
 
314
        :param kind: A pair of file kinds, as generated by Tree._iter_changes.
 
234
315
            None indicates no file present.
 
238
317
        if paths[1] == '' and versioned == 'added' and self.suppress_root_add:
 
240
 
        if self.view_files and not osutils.is_inside_any(self.view_files,
 
243
319
        if versioned == 'unversioned':
 
244
320
            # skip ignored unversioned files if needed.
 
245
321
            if self.unversioned_filter is not None:
 
 
332
409
        versioned_change = versioned_change_map[versioned]
 
333
410
        reporter.report(file_id, path, versioned_change, renamed, modified,
 
334
411
                        exe_change, kind)
 
336
 
def report_delta(to_file, delta, short_status=False, show_ids=False, 
 
337
 
         show_unchanged=False, indent='', filter=None):
 
338
 
    """Output this delta in status-like form to to_file.
 
340
 
    :param to_file: A file-like object where the output is displayed.
 
342
 
    :param delta: A TreeDelta containing the changes to be displayed
 
344
 
    :param short_status: Single-line status if True.
 
346
 
    :param show_ids: Output the file ids if True.
 
348
 
    :param show_unchanged: Output the unchanged files if True.
 
350
 
    :param indent: Added at the beginning of all output lines (for merged
 
353
 
    :param filter: A callable receiving a path and a file id and
 
354
 
        returning True if the path should be displayed.
 
357
 
    def decorate_path(path, kind, meta_modified=None):
 
358
 
        if kind == 'directory':
 
360
 
        elif kind == 'symlink':
 
366
 
    def show_more_renamed(item):
 
367
 
        (oldpath, file_id, kind,
 
368
 
         text_modified, meta_modified, newpath) = item
 
369
 
        dec_new_path = decorate_path(newpath, kind, meta_modified)
 
370
 
        to_file.write(' => %s' % dec_new_path)
 
371
 
        if text_modified or meta_modified:
 
372
 
            extra_modified.append((newpath, file_id, kind,
 
373
 
                                   text_modified, meta_modified))
 
375
 
    def show_more_kind_changed(item):
 
376
 
        (path, file_id, old_kind, new_kind) = item
 
377
 
        to_file.write(' (%s => %s)' % (old_kind, new_kind))
 
379
 
    def show_path(path, file_id, kind, meta_modified,
 
380
 
                  default_format, with_file_id_format):
 
381
 
        dec_path = decorate_path(path, kind, meta_modified)
 
383
 
            to_file.write(with_file_id_format % dec_path)
 
385
 
            to_file.write(default_format % dec_path)
 
387
 
    def show_list(files, long_status_name, short_status_letter,
 
388
 
                  default_format='%s', with_file_id_format='%-30s',
 
393
 
                prefix = short_status_letter
 
396
 
            prefix = indent + prefix + '  '
 
399
 
                path, file_id, kind = item[:3]
 
400
 
                if (filter is not None and not filter(path, file_id)):
 
402
 
                if not header_shown and not short_status:
 
403
 
                    to_file.write(indent + long_status_name + ':\n')
 
407
 
                    meta_modified = item[4]
 
409
 
                to_file.write(prefix)
 
410
 
                show_path(path, file_id, kind, meta_modified,
 
411
 
                          default_format, with_file_id_format)
 
412
 
                if show_more is not None:
 
415
 
                    to_file.write(' %s' % file_id)
 
418
 
    show_list(delta.removed, 'removed', 'D')
 
419
 
    show_list(delta.added, 'added', 'A')
 
421
 
    # Reorder delta.renamed tuples so that all lists share the same
 
422
 
    # order for their 3 first fields and that they also begin like
 
423
 
    # the delta.modified tuples
 
424
 
    renamed = [(p, i, k, tm, mm, np)
 
425
 
               for  p, np, i, k, tm, mm  in delta.renamed]
 
426
 
    show_list(renamed, 'renamed', 'R', with_file_id_format='%s',
 
427
 
              show_more=show_more_renamed)
 
428
 
    show_list(delta.kind_changed, 'kind changed', 'K',
 
429
 
              with_file_id_format='%s',
 
430
 
              show_more=show_more_kind_changed)
 
431
 
    show_list(delta.modified + extra_modified, 'modified', 'M')
 
433
 
        show_list(delta.unchanged, 'unchanged', 'S')
 
435
 
    show_list(delta.unversioned, 'unknown', ' ')