~bzr-pqm/bzr/bzr.dev

4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2005-2010 Canonical Ltd
1185.13.2 by Robert Collins
Merge Aarons conflict plugin for 0.1rc1
2
#
362 by Martin Pool
- Import stat-cache code
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.
1185.13.2 by Robert Collins
Merge Aarons conflict plugin for 0.1rc1
7
#
362 by Martin Pool
- Import stat-cache code
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.
1185.13.2 by Robert Collins
Merge Aarons conflict plugin for 0.1rc1
12
#
362 by Martin Pool
- Import stat-cache code
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
362 by Martin Pool
- Import stat-cache code
16
1185.13.2 by Robert Collins
Merge Aarons conflict plugin for 0.1rc1
17
import sys
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
18
1551.10.7 by Aaron Bentley
Use new-style output for status
19
from bzrlib import (
20
    delta as _mod_delta,
5393.3.1 by Parth Malwankar
initial post_status hook is now working
21
    hooks as _mod_hooks,
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
22
    log,
3074.3.1 by John Arbash Meinel
Fix bug #172657, use Graph.find_difference() rather than ancestry set operations.
23
    osutils,
24
    tsort,
25
    revision as _mod_revision,
1551.10.7 by Aaron Bentley
Use new-style output for status
26
    )
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
27
import bzrlib.errors as errors
3224.5.19 by Andrew Bennetts
Move _raise_if_nonexistent into the only module that uses it, bzrlib.status.
28
from bzrlib.trace import mutter, warning
362 by Martin Pool
- Import stat-cache code
29
1185.33.70 by Martin Pool
Refactor status display code.
30
# TODO: when showing single-line logs, truncate to the width of the terminal
31
# if known, but only if really going to the terminal (not into a file)
32
465 by Martin Pool
- Move show_status() out of Branch into a new function in
33
5076.4.6 by Arnaud Jeansen
Go back to unified report_delta method (i.e. former TreeDelta.show())
34
def report_changes(to_file, old, new, specific_files, 
35
                   show_short_reporter, show_long_callback, 
36
                   short=False, want_unchanged=False, 
37
                   want_unversioned=False, show_ids=False):
5076.4.7 by Arnaud Jeansen
Add signature comments to report_changes in status.py
38
    """Display summary of changes.
39
40
    This compares two trees with regards to a list of files, and delegates 
41
    the display to underlying elements.
42
43
    For short output, it creates an iterator on all changes, and lets a given
44
    reporter display these changes.
45
46
    For stantard output, it creates a delta of the changes, and forwards it
47
    to a callback
48
49
    :param to_file: If set, write to this file (default stdout.)
50
    :param old: Start tree for the comparison
51
    :param end: End tree for the comparison
52
    :param specific_files: If set, a list of filenames whose status should be
53
        shown.  It is an error to give a filename that is not in the working
54
        tree, or in the working inventory or in the basis inventory.
55
    :param show_short_reporter: Reporter in charge of display for short output
56
    :param show_long_callback: Callback in charge of display for normal output
57
    :param short: If True, gives short SVN-style status lines.
58
    :param want_unchanged: Deprecated parameter. If set, includes unchanged
59
        files.
60
    :param show_ids: If set, includes each file's id.
61
    :param want_unversioned: If False, only shows versioned files.
62
    """
5076.4.2 by Arnaud Jeansen
Create a short show callback using the previously removed short code (it was not dead, only not used by status). Port log to directly call the callbacks.
63
64
    if short:
65
        changes = new.iter_changes(old, want_unchanged, specific_files,
66
            require_versioned=False, want_unversioned=want_unversioned)
67
        _mod_delta.report_changes(changes, show_short_reporter)
68
        
69
    else:
70
        delta = new.changes_from(old, want_unchanged=want_unchanged,
71
                              specific_files=specific_files,
72
                              want_unversioned=want_unversioned)
73
        # filter out unknown files. We may want a tree method for
74
        # this
75
        delta.unversioned = [unversioned for unversioned in
76
            delta.unversioned if not new.is_ignored(unversioned[0])]
77
        show_long_callback(to_file, delta, 
78
                           show_ids=show_ids,
79
                           show_unchanged=want_unchanged)
5076.4.1 by Arnaud Jeansen
Extract show() from TreeDelta and pass a callback instead
80
81
1773.1.2 by Robert Collins
Remove --all option from status.
82
def show_tree_status(wt, show_unchanged=None,
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
83
                     specific_files=None,
84
                     show_ids=False,
85
                     to_file=None,
86
                     show_pending=True,
2147.2.1 by Keir Mierle
Add a --short flag to status to get svn-style status
87
                     revision=None,
2318.2.1 by Kent Gibson
Apply status versioned patch
88
                     short=False,
3936.2.1 by Ian Clatworthy
verbose flag for status - code & tests
89
                     verbose=False,
5076.4.1 by Arnaud Jeansen
Extract show() from TreeDelta and pass a callback instead
90
                     versioned=False,
5076.4.4 by Arnaud Jeansen
Add a unified report_delta method
91
                     show_long_callback=_mod_delta.report_delta):
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
92
    """Display summary of changes.
93
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
94
    By default this compares the working tree to a previous revision.
95
    If the revision argument is given, summarizes changes between the
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
96
    working tree and another, or between two revisions.
97
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
98
    The result is written out as Unicode and to_file should be able
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
99
    to encode that.
100
1662.1.9 by Martin Pool
Give a clear error for bzr status of an unversioned, nonexistent file. (Malone #3619)
101
    If showing the status of a working tree, extra information is included
102
    about unknown files, conflicts, and pending merges.
103
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
104
    :param show_unchanged: Deprecated parameter. If set, includes unchanged
1773.1.2 by Robert Collins
Remove --all option from status.
105
        files.
106
    :param specific_files: If set, a list of filenames whose status should be
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
107
        shown.  It is an error to give a filename that is not in the working
1662.1.9 by Martin Pool
Give a clear error for bzr status of an unversioned, nonexistent file. (Malone #3619)
108
        tree, or in the working inventory or in the basis inventory.
1773.1.2 by Robert Collins
Remove --all option from status.
109
    :param show_ids: If set, includes each file's id.
110
    :param to_file: If set, write to this file (default stdout.)
111
    :param show_pending: If set, write pending merges.
3394.2.2 by Ian Clatworthy
show_tree_status docstring and deprecation cleanups
112
    :param revision: If None, compare latest revision with working tree
113
        If not None, it must be a RevisionSpec list.
114
        If one revision, compare with working tree.
115
        If two revisions, show status between first and second.
2318.2.1 by Kent Gibson
Apply status versioned patch
116
    :param short: If True, gives short SVN-style status lines.
3936.2.1 by Ian Clatworthy
verbose flag for status - code & tests
117
    :param verbose: If True, show all merged revisions, not just
118
        the merge tips
2318.2.1 by Kent Gibson
Apply status versioned patch
119
    :param versioned: If True, only shows versioned files.
5076.4.2 by Arnaud Jeansen
Create a short show callback using the previously removed short code (it was not dead, only not used by status). Port log to directly call the callbacks.
120
    :param show_long_callback: A callback: message = show_long_callback(to_file, delta, 
121
        show_ids, show_unchanged, indent, filter), only used with the long output
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
122
    """
1773.1.2 by Robert Collins
Remove --all option from status.
123
    if show_unchanged is not None:
3394.2.2 by Ian Clatworthy
show_tree_status docstring and deprecation cleanups
124
        warn("show_tree_status with show_unchanged has been deprecated "
1773.1.2 by Robert Collins
Remove --all option from status.
125
             "since bzrlib 0.9", DeprecationWarning, stacklevel=2)
126
127
    if to_file is None:
915 by Martin Pool
- add simple test case for bzr status
128
        to_file = sys.stdout
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
129
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
130
    wt.lock_read()
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
131
    try:
1185.1.35 by Robert Collins
Heikki Paajanen's status -r patch
132
        new_is_working_tree = True
133
        if revision is None:
2091.4.1 by wang
Pushing to a remote branch does not currently update the remote working
134
            if wt.last_revision() != wt.branch.last_revision():
135
                warning("working tree is out of date, run 'bzr update'")
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
136
            new = wt
1534.4.35 by Robert Collins
Give branch its own basis tree and last_revision methods; deprecated branch.working_tree()
137
            old = new.basis_tree()
1185.1.35 by Robert Collins
Heikki Paajanen's status -r patch
138
        elif len(revision) > 0:
139
            try:
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
140
                old = revision[0].as_tree(wt.branch)
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
141
            except errors.NoSuchRevision, e:
142
                raise errors.BzrCommandError(str(e))
1540.2.6 by Robey Pointer
make 'log' and 'status' treat '-r N..' as implicitly '-r N..-1'
143
            if (len(revision) > 1) and (revision[1].spec is not None):
1185.1.35 by Robert Collins
Heikki Paajanen's status -r patch
144
                try:
3655.3.1 by Lukáš Lalinský
Fix `bzr st -rbranch:PATH_TO_BRANCH`
145
                    new = revision[1].as_tree(wt.branch)
1185.1.35 by Robert Collins
Heikki Paajanen's status -r patch
146
                    new_is_working_tree = False
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
147
                except errors.NoSuchRevision, e:
148
                    raise errors.BzrCommandError(str(e))
1185.1.35 by Robert Collins
Heikki Paajanen's status -r patch
149
            else:
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
150
                new = wt
2255.2.80 by Robert Collins
In status, read lock the old and new trees being used to let data caching occur.
151
        old.lock_read()
152
        new.lock_read()
153
        try:
5393.3.7 by Parth Malwankar
added pre_status hook
154
            for hook in hooks['pre_status']:
155
                hook(StatusHookParams(old, new, to_file, versioned,
156
                    show_ids, short, verbose))
157
3930.2.2 by Karl Fogel
* bzrlib/status.py
158
            specific_files, nonexistents \
3930.2.4 by Karl Fogel
* bzrlib/status.py
159
                = _filter_nonexistent(specific_files, old, new)
2318.2.3 by Kent Gibson
merged bzr.dev
160
            want_unversioned = not versioned
5076.4.2 by Arnaud Jeansen
Create a short show callback using the previously removed short code (it was not dead, only not used by status). Port log to directly call the callbacks.
161
162
            # Reporter used for short outputs
163
            reporter = _mod_delta._ChangeReporter(output_file=to_file,
164
                unversioned_filter=new.is_ignored)
5076.4.6 by Arnaud Jeansen
Go back to unified report_delta method (i.e. former TreeDelta.show())
165
            report_changes(to_file, old, new, specific_files, 
5076.4.2 by Arnaud Jeansen
Create a short show callback using the previously removed short code (it was not dead, only not used by status). Port log to directly call the callbacks.
166
                           reporter, show_long_callback, 
167
                           short=short, want_unchanged=show_unchanged, 
168
                           want_unversioned=want_unversioned, show_ids=show_ids)
169
5137.2.5 by Arnaud Jeansen
Implement behaviour requested by mbp, in a way similar to the conflicts and non existent files' handling
170
            # show the ignored files among specific files (i.e. show the files
171
            # identified from input that we choose to ignore). 
172
            if specific_files is not None:
173
                # Ignored files is sorted because specific_files is already sorted
174
                ignored_files = [specific for specific in
175
                    specific_files if new.is_ignored(specific)]
176
                if len(ignored_files) > 0 and not short:
177
                    to_file.write("ignored:\n")
178
                    prefix = ' '
179
                else:
180
                    prefix = 'I  '
181
                for ignored_file in ignored_files:
182
                    to_file.write("%s %s\n" % (prefix, ignored_file))
183
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
184
            # show the new conflicts only for now. XXX: get them from the
185
            # delta.
186
            conflicts = new.conflicts()
187
            if specific_files is not None:
188
                conflicts = conflicts.select_conflicts(new, specific_files,
189
                    ignore_misses=True, recurse=True)[1]
190
            if len(conflicts) > 0 and not short:
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
191
                to_file.write("conflicts:\n")
1551.15.58 by Aaron Bentley
Status honours selected paths for conflicts (#127606)
192
            for conflict in conflicts:
2255.2.80 by Robert Collins
In status, read lock the old and new trees being used to let data caching occur.
193
                if short:
2255.2.83 by John Arbash Meinel
[merge] bzr.dev 2294
194
                    prefix = 'C  '
2255.2.80 by Robert Collins
In status, read lock the old and new trees being used to let data caching occur.
195
                else:
196
                    prefix = ' '
2911.6.1 by Blake Winton
Change 'print >> f,'s to 'f.write('s.
197
                to_file.write("%s %s\n" % (prefix, conflict))
3930.2.2 by Karl Fogel
* bzrlib/status.py
198
            # Show files that were requested but don't exist (and are
199
            # not versioned).  We don't involve delta in this; these
200
            # paths are really the province of just the status
201
            # command, since they have more to do with how it was
202
            # invoked than with the tree it's operating on.
203
            if nonexistents and not short:
204
                to_file.write("nonexistent:\n")
205
            for nonexistent in nonexistents:
3992.1.1 by Ian Clatworthy
Handle non-existent files in status (Karl Fogel, #306394)
206
                # We could calculate prefix outside the loop but, given
207
                # how rarely this ought to happen, it's OK and arguably
208
                # slightly faster to do it here (ala conflicts above)
3930.2.2 by Karl Fogel
* bzrlib/status.py
209
                if short:
210
                    prefix = 'X  '
211
                else:
212
                    prefix = ' '
213
                to_file.write("%s %s\n" % (prefix, nonexistent))
3636.1.1 by Robert Collins
Stop passing specific_file lists to show_tree_status when the specific
214
            if (new_is_working_tree and show_pending):
3936.2.1 by Ian Clatworthy
verbose flag for status - code & tests
215
                show_pending_merges(new, to_file, short, verbose=verbose)
4593.3.1 by Martin Pool
Avoid raising exceptions from inside finally blocks (see bug 403523)
216
            if nonexistents:
217
                raise errors.PathsDoNotExist(nonexistents)
5393.3.1 by Parth Malwankar
initial post_status hook is now working
218
            for hook in hooks['post_status']:
5393.3.7 by Parth Malwankar
added pre_status hook
219
                hook(StatusHookParams(old, new, to_file, versioned,
5393.3.6 by Parth Malwankar
verbose arg is now passed to post_status hook
220
                    show_ids, short, verbose))
2255.2.80 by Robert Collins
In status, read lock the old and new trees being used to let data caching occur.
221
        finally:
222
            old.unlock()
223
            new.unlock()
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
224
    finally:
1551.2.9 by Aaron Bentley
Fix status to work with checkouts
225
        wt.unlock()
1185.33.70 by Martin Pool
Refactor status display code.
226
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
227
228
def _get_sorted_revisions(tip_revision, revision_ids, parent_map):
229
    """Get an iterator which will return the revisions in merge sorted order.
230
231
    This will build up a list of all nodes, such that only nodes in the list
232
    are referenced. It then uses MergeSorter to return them in 'merge-sorted'
233
    order.
234
235
    :param revision_ids: A set of revision_ids
236
    :param parent_map: The parent information for each node. Revisions which
237
        are considered ghosts should not be present in the map.
3377.3.43 by John Arbash Meinel
Ian's review feedback
238
    :return: iterator from MergeSorter.iter_topo_order()
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
239
    """
3377.3.40 by John Arbash Meinel
a little bit more cleanup, change how ghosts are handled
240
    # MergeSorter requires that all nodes be present in the graph, so get rid
241
    # of any references pointing outside of this graph.
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
242
    parent_graph = {}
243
    for revision_id in revision_ids:
244
        if revision_id not in parent_map: # ghost
245
            parent_graph[revision_id] = []
246
        else:
247
            # Only include parents which are in this sub-graph
248
            parent_graph[revision_id] = [p for p in parent_map[revision_id]
249
                                            if p in revision_ids]
250
    sorter = tsort.MergeSorter(parent_graph, tip_revision)
251
    return sorter.iter_topo_order()
252
253
3936.2.1 by Ian Clatworthy
verbose flag for status - code & tests
254
def show_pending_merges(new, to_file, short=False, verbose=False):
1185.33.70 by Martin Pool
Refactor status display code.
255
    """Write out a display of pending merges in a working tree."""
3377.3.43 by John Arbash Meinel
Ian's review feedback
256
    parents = new.get_parent_ids()
257
    if len(parents) < 2:
258
        return
259
4747.3.6 by Vincent Ladeuil
terminal_width can now returns None.
260
    term_width = osutils.terminal_width()
261
    if term_width is not None:
262
        # we need one extra space for terminals that wrap on last char
263
        term_width = term_width - 1
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
264
    if short:
3377.3.42 by John Arbash Meinel
Get the tests to actually work, and get the code to go along with.
265
        first_prefix = 'P   '
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
266
        sub_prefix = 'P.   '
267
    else:
268
        first_prefix = '  '
269
        sub_prefix = '    '
3377.3.38 by John Arbash Meinel
Pull out terminal width from the inner loop of show_pending_merges
270
4747.3.6 by Vincent Ladeuil
terminal_width can now returns None.
271
    def show_log_message(rev, prefix):
272
        if term_width is None:
273
            width = term_width
274
        else:
275
            width = term_width - len(prefix)
276
        log_message = log_formatter.log_string(None, rev, width, prefix=prefix)
277
        to_file.write(log_message + '\n')
278
1908.6.9 by Robert Collins
Fix status to not use pending_merges.
279
    pending = parents[1:]
1185.33.70 by Martin Pool
Refactor status display code.
280
    branch = new.branch
1908.6.9 by Robert Collins
Fix status to not use pending_merges.
281
    last_revision = parents[0]
2147.2.2 by Keir Mierle
Fix spacing error and add tests for status --short command flag.
282
    if not short:
3936.2.1 by Ian Clatworthy
verbose flag for status - code & tests
283
        if verbose:
284
            to_file.write('pending merges:\n')
285
        else:
4747.3.6 by Vincent Ladeuil
terminal_width can now returns None.
286
            to_file.write('pending merge tips:'
287
                          ' (use -v to see all merge revisions)\n')
3074.3.1 by John Arbash Meinel
Fix bug #172657, use Graph.find_difference() rather than ancestry set operations.
288
    graph = branch.repository.get_graph()
3377.3.31 by John Arbash Meinel
change the status code to use find_unique_ancestors()
289
    other_revisions = [last_revision]
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
290
    log_formatter = log.LineLogFormatter(to_file)
1908.6.9 by Robert Collins
Fix status to not use pending_merges.
291
    for merge in pending:
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
292
        try:
293
            rev = branch.repository.get_revisions([merge])[0]
294
        except errors.NoSuchRevision:
295
            # If we are missing a revision, just print out the revision id
3377.3.40 by John Arbash Meinel
a little bit more cleanup, change how ghosts are handled
296
            to_file.write(first_prefix + '(ghost) ' + merge + '\n')
3377.3.39 by John Arbash Meinel
More tweaks for show_pending_merges
297
            other_revisions.append(merge)
298
            continue
299
300
        # Log the merge, as it gets a slightly different formatting
4747.3.6 by Vincent Ladeuil
terminal_width can now returns None.
301
        show_log_message(rev, first_prefix)
3936.2.1 by Ian Clatworthy
verbose flag for status - code & tests
302
        if not verbose:
303
            continue
304
3074.3.1 by John Arbash Meinel
Fix bug #172657, use Graph.find_difference() rather than ancestry set operations.
305
        # Find all of the revisions in the merge source, which are not in the
306
        # last committed revision.
3377.3.31 by John Arbash Meinel
change the status code to use find_unique_ancestors()
307
        merge_extra = graph.find_unique_ancestors(merge, other_revisions)
308
        other_revisions.append(merge)
3074.3.1 by John Arbash Meinel
Fix bug #172657, use Graph.find_difference() rather than ancestry set operations.
309
        merge_extra.discard(_mod_revision.NULL_REVISION)
3377.3.38 by John Arbash Meinel
Pull out terminal width from the inner loop of show_pending_merges
310
3074.3.1 by John Arbash Meinel
Fix bug #172657, use Graph.find_difference() rather than ancestry set operations.
311
        # Get a handle to all of the revisions we will need
1185.33.70 by Martin Pool
Refactor status display code.
312
        try:
3074.3.1 by John Arbash Meinel
Fix bug #172657, use Graph.find_difference() rather than ancestry set operations.
313
            revisions = dict((rev.revision_id, rev) for rev in
314
                             branch.repository.get_revisions(merge_extra))
315
        except errors.NoSuchRevision:
3377.3.40 by John Arbash Meinel
a little bit more cleanup, change how ghosts are handled
316
            # One of the sub nodes is a ghost, check each one
317
            revisions = {}
318
            for revision_id in merge_extra:
319
                try:
3377.3.42 by John Arbash Meinel
Get the tests to actually work, and get the code to go along with.
320
                    rev = branch.repository.get_revisions([revision_id])[0]
3377.3.40 by John Arbash Meinel
a little bit more cleanup, change how ghosts are handled
321
                except errors.NoSuchRevision:
322
                    revisions[revision_id] = None
323
                else:
324
                    revisions[revision_id] = rev
325
326
        # Display the revisions brought in by this merge.
327
        rev_id_iterator = _get_sorted_revisions(merge, merge_extra,
328
                            branch.repository.get_parent_map(merge_extra))
329
        # Skip the first node
330
        num, first, depth, eom = rev_id_iterator.next()
331
        if first != merge:
332
            raise AssertionError('Somehow we misunderstood how'
333
                ' iter_topo_order works %s != %s' % (first, merge))
334
        for num, sub_merge, depth, eom in rev_id_iterator:
335
            rev = revisions[sub_merge]
336
            if rev is None:
337
                to_file.write(sub_prefix + '(ghost) ' + sub_merge + '\n')
338
                continue
4747.3.6 by Vincent Ladeuil
terminal_width can now returns None.
339
            show_log_message(revisions[sub_merge], sub_prefix)
3224.5.19 by Andrew Bennetts
Move _raise_if_nonexistent into the only module that uses it, bzrlib.status.
340
341
3930.2.4 by Karl Fogel
* bzrlib/status.py
342
def _filter_nonexistent(orig_paths, old_tree, new_tree):
3930.2.15 by Karl Fogel
Part of bug #306394: Ensure sorted order for nonexistent file output.
343
    """Convert orig_paths to two sorted lists and return them.
3930.2.2 by Karl Fogel
* bzrlib/status.py
344
345
    The first is orig_paths paths minus the items in the second list,
346
    and the second list is paths that are not in either inventory or
347
    tree (they don't qualify if they exist in the tree's inventory, or
348
    if they exist in the tree but are not versioned.)
349
350
    If either of the two lists is empty, return it as an empty list.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
351
3224.5.19 by Andrew Bennetts
Move _raise_if_nonexistent into the only module that uses it, bzrlib.status.
352
    This can be used by operations such as bzr status that can accept
353
    unknown or ignored files.
354
    """
3930.2.2 by Karl Fogel
* bzrlib/status.py
355
    mutter("check paths: %r", orig_paths)
356
    if not orig_paths:
357
        return orig_paths, []
358
    s = old_tree.filter_unversioned_files(orig_paths)
3224.5.19 by Andrew Bennetts
Move _raise_if_nonexistent into the only module that uses it, bzrlib.status.
359
    s = new_tree.filter_unversioned_files(s)
3930.2.2 by Karl Fogel
* bzrlib/status.py
360
    nonexistent = [path for path in s if not new_tree.has_filename(path)]
361
    remaining   = [path for path in orig_paths if not path in nonexistent]
3930.2.15 by Karl Fogel
Part of bug #306394: Ensure sorted order for nonexistent file output.
362
    # Sorting the 'remaining' list doesn't have much effect in
363
    # practice, since the various status output sections will sort
364
    # their groups individually.  But for consistency of this
365
    # function's API, it's better to sort both than just 'nonexistent'.
366
    return sorted(remaining), sorted(nonexistent)
5393.3.1 by Parth Malwankar
initial post_status hook is now working
367
368
369
class StatusHooks(_mod_hooks.Hooks):
370
    """A dictionary mapping hook name to a list of callables for status hooks.
371
372
    e.g. ['post_status'] Is the list of items to be called when the
373
    status command has finished printing the status.
374
    """
375
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
376
    def __init__(self):
5393.3.1 by Parth Malwankar
initial post_status hook is now working
377
        """Create the default hooks.
378
379
        These are all empty initially, because by default nothing should get
380
        notified.
381
        """
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
382
        _mod_hooks.Hooks.__init__(self, "bzrlib.status", "hooks")
5622.3.2 by Jelmer Vernooij
Add more lazily usable hook points.
383
        self.add_hook('post_status',
5393.3.7 by Parth Malwankar
added pre_status hook
384
            "Called with argument StatusHookParams after Bazaar has "
385
            "displayed the status. StatusHookParams has the attributes "
386
            "(old_tree, new_tree, to_file, versioned, show_ids, short, "
387
            "verbose). The last four arguments correspond to the command "
388
            "line options specified by the user for the status command. "
389
            "to_file is the output stream for writing.",
5622.3.2 by Jelmer Vernooij
Add more lazily usable hook points.
390
            (2, 3))
391
        self.add_hook('pre_status',
5393.3.7 by Parth Malwankar
added pre_status hook
392
            "Called with argument StatusHookParams before Bazaar "
393
            "displays the status. StatusHookParams has the attributes "
5393.3.6 by Parth Malwankar
verbose arg is now passed to post_status hook
394
            "(old_tree, new_tree, to_file, versioned, show_ids, short, "
395
            "verbose). The last four arguments correspond to the command "
396
            "line options specified by the user for the status command. "
397
            "to_file is the output stream for writing.",
5622.3.2 by Jelmer Vernooij
Add more lazily usable hook points.
398
            (2, 3))
5393.3.1 by Parth Malwankar
initial post_status hook is now working
399
400
5393.3.7 by Parth Malwankar
added pre_status hook
401
class StatusHookParams(object):
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
402
    """Object holding parameters passed to post_status hooks.
403
404
    :ivar old_tree: Start tree (basis tree) for comparison.
405
    :ivar new_tree: Working tree.
5393.3.5 by Parth Malwankar
post_status hook now provies to_file as argument
406
    :ivar to_file: If set, write to this file.
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
407
    :ivar versioned: Show only versioned files.
408
    :ivar show_ids: Show internal object ids.
409
    :ivar short: Use short status indicators.
5393.3.6 by Parth Malwankar
verbose arg is now passed to post_status hook
410
    :ivar verbose: Verbose flag.
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
411
    """
412
5393.3.6 by Parth Malwankar
verbose arg is now passed to post_status hook
413
    def __init__(self, old_tree, new_tree, to_file, versioned, show_ids,
414
            short, verbose):
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
415
        """Create a group of post_status hook parameters.
416
417
        :param old_tree: Start tree (basis tree) for comparison.
418
        :param new_tree: Working tree.
5393.3.5 by Parth Malwankar
post_status hook now provies to_file as argument
419
        :param to_file: If set, write to this file.
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
420
        :param versioned: Show only versioned files.
421
        :param show_ids: Show internal object ids.
422
        :param short: Use short status indicators.
5393.3.6 by Parth Malwankar
verbose arg is now passed to post_status hook
423
        :param verbose: Verbose flag.
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
424
        """
425
        self.old_tree = old_tree
426
        self.new_tree = new_tree
5393.3.5 by Parth Malwankar
post_status hook now provies to_file as argument
427
        self.to_file = to_file
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
428
        self.versioned = versioned
429
        self.show_ids = show_ids
430
        self.short = short
5393.3.6 by Parth Malwankar
verbose arg is now passed to post_status hook
431
        self.verbose = verbose
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
432
433
    def __eq__(self, other):
434
        return self.__dict__ == other.__dict__
435
436
    def __repr__(self):
5393.3.6 by Parth Malwankar
verbose arg is now passed to post_status hook
437
        return "<%s(%s, %s, %s, %s, %s, %s, %s)>" % (self.__class__.__name__,
5393.3.5 by Parth Malwankar
post_status hook now provies to_file as argument
438
            self.old_tree, self.new_tree, self.to_file, self.versioned,
5393.3.6 by Parth Malwankar
verbose arg is now passed to post_status hook
439
            self.show_ids, self.short, self.verbose)
5393.3.2 by Parth Malwankar
added StatusPostHookParams and test cases
440
5418.4.1 by Parth Malwankar
post_status hook added to show shelve summary.
441
442
def _show_shelve_summary(params):
443
    """post_status hook to display a summary of shelves.
444
445
    :param params: StatusHookParams.
446
    """
5508.1.1 by John Arbash Meinel
Fix bug #662053, 'bzr status' shouldn't fail
447
    get_shelf_manager = getattr(params.new_tree, 'get_shelf_manager', None)
448
    if get_shelf_manager is None:
449
        return
450
    manager = get_shelf_manager()
5418.4.6 by Parth Malwankar
used active_shelves instead of creating a new function for listing shelves
451
    shelves = manager.active_shelves()
5418.4.1 by Parth Malwankar
post_status hook added to show shelve summary.
452
    if shelves:
5609.11.2 by Alexander Belchenko
correct singular form, thanks John
453
        singular = '%d shelf exists. '
5609.11.1 by Alexander Belchenko
use proper plural form to print status message about existing shelves.
454
        plural = '%d shelves exist. '
455
        if len(shelves) == 1:
456
            fmt = singular
457
        else:
458
            fmt = plural
459
        params.to_file.write(fmt % len(shelves))
460
        params.to_file.write('See "bzr shelve --list" for details.\n')
5418.4.1 by Parth Malwankar
post_status hook added to show shelve summary.
461
462
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
463
hooks = StatusHooks()
5622.3.2 by Jelmer Vernooij
Add more lazily usable hook points.
464
5622.3.11 by Jelmer Vernooij
Revert some unnecessary changes.
465
466
hooks.install_named_hook('post_status', _show_shelve_summary,
467
    'bzr status')
468