~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/status.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-09-01 08:02:42 UTC
  • mfrom: (5390.3.3 faster-revert-593560)
  • Revision ID: pqm@pqm.ubuntu.com-20100901080242-esg62ody4frwmy66
(spiv) Avoid repeatedly calling self.target.all_file_ids() in
 InterTree.iter_changes. (Andrew Bennetts)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
import sys
18
18
 
20
20
    delta as _mod_delta,
21
21
    log,
22
22
    osutils,
23
 
    tree,
24
23
    tsort,
25
24
    revision as _mod_revision,
26
25
    )
27
26
import bzrlib.errors as errors
28
 
from bzrlib.osutils import is_inside_any
29
 
from bzrlib.symbol_versioning import (deprecated_function,
30
 
        )
31
27
from bzrlib.trace import mutter, warning
32
28
 
33
29
# TODO: when showing single-line logs, truncate to the width of the terminal
34
30
# if known, but only if really going to the terminal (not into a file)
35
31
 
36
32
 
 
33
def report_changes(to_file, old, new, specific_files, 
 
34
                   show_short_reporter, show_long_callback, 
 
35
                   short=False, want_unchanged=False, 
 
36
                   want_unversioned=False, show_ids=False):
 
37
    """Display summary of changes.
 
38
 
 
39
    This compares two trees with regards to a list of files, and delegates 
 
40
    the display to underlying elements.
 
41
 
 
42
    For short output, it creates an iterator on all changes, and lets a given
 
43
    reporter display these changes.
 
44
 
 
45
    For stantard output, it creates a delta of the changes, and forwards it
 
46
    to a callback
 
47
 
 
48
    :param to_file: If set, write to this file (default stdout.)
 
49
    :param old: Start tree for the comparison
 
50
    :param end: End tree for the comparison
 
51
    :param specific_files: If set, a list of filenames whose status should be
 
52
        shown.  It is an error to give a filename that is not in the working
 
53
        tree, or in the working inventory or in the basis inventory.
 
54
    :param show_short_reporter: Reporter in charge of display for short output
 
55
    :param show_long_callback: Callback in charge of display for normal output
 
56
    :param short: If True, gives short SVN-style status lines.
 
57
    :param want_unchanged: Deprecated parameter. If set, includes unchanged
 
58
        files.
 
59
    :param show_ids: If set, includes each file's id.
 
60
    :param want_unversioned: If False, only shows versioned files.
 
61
    """
 
62
 
 
63
    if short:
 
64
        changes = new.iter_changes(old, want_unchanged, specific_files,
 
65
            require_versioned=False, want_unversioned=want_unversioned)
 
66
        _mod_delta.report_changes(changes, show_short_reporter)
 
67
        
 
68
    else:
 
69
        delta = new.changes_from(old, want_unchanged=want_unchanged,
 
70
                              specific_files=specific_files,
 
71
                              want_unversioned=want_unversioned)
 
72
        # filter out unknown files. We may want a tree method for
 
73
        # this
 
74
        delta.unversioned = [unversioned for unversioned in
 
75
            delta.unversioned if not new.is_ignored(unversioned[0])]
 
76
        show_long_callback(to_file, delta, 
 
77
                           show_ids=show_ids,
 
78
                           show_unchanged=want_unchanged)
 
79
 
 
80
 
37
81
def show_tree_status(wt, show_unchanged=None,
38
82
                     specific_files=None,
39
83
                     show_ids=False,
42
86
                     revision=None,
43
87
                     short=False,
44
88
                     verbose=False,
45
 
                     versioned=False):
 
89
                     versioned=False,
 
90
                     show_long_callback=_mod_delta.report_delta):
46
91
    """Display summary of changes.
47
92
 
48
 
    By default this compares the working tree to a previous revision. 
49
 
    If the revision argument is given, summarizes changes between the 
 
93
    By default this compares the working tree to a previous revision.
 
94
    If the revision argument is given, summarizes changes between the
50
95
    working tree and another, or between two revisions.
51
96
 
52
 
    The result is written out as Unicode and to_file should be able 
 
97
    The result is written out as Unicode and to_file should be able
53
98
    to encode that.
54
99
 
55
100
    If showing the status of a working tree, extra information is included
56
101
    about unknown files, conflicts, and pending merges.
57
102
 
58
 
    :param show_unchanged: Deprecated parameter. If set, includes unchanged 
 
103
    :param show_unchanged: Deprecated parameter. If set, includes unchanged
59
104
        files.
60
105
    :param specific_files: If set, a list of filenames whose status should be
61
 
        shown.  It is an error to give a filename that is not in the working 
 
106
        shown.  It is an error to give a filename that is not in the working
62
107
        tree, or in the working inventory or in the basis inventory.
63
108
    :param show_ids: If set, includes each file's id.
64
109
    :param to_file: If set, write to this file (default stdout.)
71
116
    :param verbose: If True, show all merged revisions, not just
72
117
        the merge tips
73
118
    :param versioned: If True, only shows versioned files.
 
119
    :param show_long_callback: A callback: message = show_long_callback(to_file, delta, 
 
120
        show_ids, show_unchanged, indent, filter), only used with the long output
74
121
    """
75
122
    if show_unchanged is not None:
76
123
        warn("show_tree_status with show_unchanged has been deprecated "
78
125
 
79
126
    if to_file is None:
80
127
        to_file = sys.stdout
81
 
    
 
128
 
82
129
    wt.lock_read()
83
130
    try:
84
131
        new_is_working_tree = True
106
153
            specific_files, nonexistents \
107
154
                = _filter_nonexistent(specific_files, old, new)
108
155
            want_unversioned = not versioned
109
 
            if short:
110
 
                changes = new.iter_changes(old, show_unchanged, specific_files,
111
 
                    require_versioned=False, want_unversioned=want_unversioned)
112
 
                reporter = _mod_delta._ChangeReporter(output_file=to_file,
113
 
                    unversioned_filter=new.is_ignored)
114
 
                _mod_delta.report_changes(changes, reporter)
115
 
            else:
116
 
                delta = new.changes_from(old, want_unchanged=show_unchanged,
117
 
                                      specific_files=specific_files,
118
 
                                      want_unversioned=want_unversioned)
119
 
                # filter out unknown files. We may want a tree method for
120
 
                # this
121
 
                delta.unversioned = [unversioned for unversioned in
122
 
                    delta.unversioned if not new.is_ignored(unversioned[0])]
123
 
                delta.show(to_file,
124
 
                           show_ids=show_ids,
125
 
                           show_unchanged=show_unchanged,
126
 
                           short_status=False)
 
156
 
 
157
            # Reporter used for short outputs
 
158
            reporter = _mod_delta._ChangeReporter(output_file=to_file,
 
159
                unversioned_filter=new.is_ignored)
 
160
            report_changes(to_file, old, new, specific_files, 
 
161
                           reporter, show_long_callback, 
 
162
                           short=short, want_unchanged=show_unchanged, 
 
163
                           want_unversioned=want_unversioned, show_ids=show_ids)
 
164
 
 
165
            # show the ignored files among specific files (i.e. show the files
 
166
            # identified from input that we choose to ignore). 
 
167
            if specific_files is not None:
 
168
                # Ignored files is sorted because specific_files is already sorted
 
169
                ignored_files = [specific for specific in
 
170
                    specific_files if new.is_ignored(specific)]
 
171
                if len(ignored_files) > 0 and not short:
 
172
                    to_file.write("ignored:\n")
 
173
                    prefix = ' '
 
174
                else:
 
175
                    prefix = 'I  '
 
176
                for ignored_file in ignored_files:
 
177
                    to_file.write("%s %s\n" % (prefix, ignored_file))
 
178
 
127
179
            # show the new conflicts only for now. XXX: get them from the
128
180
            # delta.
129
181
            conflicts = new.conflicts()
156
208
                to_file.write("%s %s\n" % (prefix, nonexistent))
157
209
            if (new_is_working_tree and show_pending):
158
210
                show_pending_merges(new, to_file, short, verbose=verbose)
 
211
            if nonexistents:
 
212
                raise errors.PathsDoNotExist(nonexistents)
159
213
        finally:
160
214
            old.unlock()
161
215
            new.unlock()
162
 
            if nonexistents:
163
 
              raise errors.PathsDoNotExist(nonexistents)
164
216
    finally:
165
217
        wt.unlock()
166
218
 
197
249
    if len(parents) < 2:
198
250
        return
199
251
 
200
 
    # we need one extra space for terminals that wrap on last char
201
 
    term_width = osutils.terminal_width() - 1
 
252
    term_width = osutils.terminal_width()
 
253
    if term_width is not None:
 
254
        # we need one extra space for terminals that wrap on last char
 
255
        term_width = term_width - 1
202
256
    if short:
203
257
        first_prefix = 'P   '
204
258
        sub_prefix = 'P.   '
206
260
        first_prefix = '  '
207
261
        sub_prefix = '    '
208
262
 
 
263
    def show_log_message(rev, prefix):
 
264
        if term_width is None:
 
265
            width = term_width
 
266
        else:
 
267
            width = term_width - len(prefix)
 
268
        log_message = log_formatter.log_string(None, rev, width, prefix=prefix)
 
269
        to_file.write(log_message + '\n')
 
270
 
209
271
    pending = parents[1:]
210
272
    branch = new.branch
211
273
    last_revision = parents[0]
213
275
        if verbose:
214
276
            to_file.write('pending merges:\n')
215
277
        else:
216
 
            to_file.write('pending merge tips: (use -v to see all merge revisions)\n')
 
278
            to_file.write('pending merge tips:'
 
279
                          ' (use -v to see all merge revisions)\n')
217
280
    graph = branch.repository.get_graph()
218
281
    other_revisions = [last_revision]
219
282
    log_formatter = log.LineLogFormatter(to_file)
227
290
            continue
228
291
 
229
292
        # Log the merge, as it gets a slightly different formatting
230
 
        log_message = log_formatter.log_string(None, rev,
231
 
                        term_width - len(first_prefix))
232
 
        to_file.write(first_prefix + log_message + '\n')
 
293
        show_log_message(rev, first_prefix)
233
294
        if not verbose:
234
295
            continue
235
296
 
267
328
            if rev is None:
268
329
                to_file.write(sub_prefix + '(ghost) ' + sub_merge + '\n')
269
330
                continue
270
 
            log_message = log_formatter.log_string(None,
271
 
                            revisions[sub_merge],
272
 
                            term_width - len(sub_prefix))
273
 
            to_file.write(sub_prefix + log_message + '\n')
 
331
            show_log_message(revisions[sub_merge], sub_prefix)
274
332
 
275
333
 
276
334
def _filter_nonexistent(orig_paths, old_tree, new_tree):