~bzr-pqm/bzr/bzr.dev

77 by mbp at sourcefrog
- split info command out into separate file
1
# Copyright (C) 2004, 2005 by Martin Pool
2
# Copyright (C) 2005 by Canonical Ltd
3
4
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
9
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
1534.5.1 by Robert Collins
Give info some reasonable output and tests.
19
__all__ = ['show_bzrdir_info']
20
77 by mbp at sourcefrog
- split info command out into separate file
21
import time
22
1534.5.1 by Robert Collins
Give info some reasonable output and tests.
23
24
import bzrlib.diff as diff
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
25
from bzrlib.errors import (NoWorkingTree, NotBranchError,
26
                           NoRepositoryPresent, NotLocalUrl)
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
27
from bzrlib.missing import find_unmerged
1694.2.6 by Martin Pool
[merge] bzr.dev
28
import bzrlib.osutils as osutils
1534.5.1 by Robert Collins
Give info some reasonable output and tests.
29
from bzrlib.symbol_versioning import *
77 by mbp at sourcefrog
- split info command out into separate file
30
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
31
1563.2.28 by Robert Collins
Add total_size to the revision_store api.
32
def plural(n, base='', pl=None):
33
    if n == 1:
34
        return base
35
    elif pl != None:
36
        return pl
37
    else:
38
        return 's'
39
40
1694.2.6 by Martin Pool
[merge] bzr.dev
41
def _repo_relpath(repo_path, path):
42
    """Return path with common prefix of repository path removed.
43
44
    If path is not part of the repository, the original path is returned.
45
    If path is equal to the repository, the current directory marker '.' is
46
    returned.
47
    """
48
    path = osutils.normalizepath(path)
49
    repo_path = osutils.normalizepath(repo_path)
50
    if path == repo_path:
51
        return '.'
52
    if osutils.is_inside(repo_path, path):
53
        return osutils.relpath(repo_path, path)
54
    return path
55
56
57
def _show_location_info(repository, branch=None, working=None):
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
58
    """Show known locations for working, branch and repository."""
1694.2.6 by Martin Pool
[merge] bzr.dev
59
    repository_path = repository.bzrdir.root_transport.base
1624.3.8 by Olaf Conradi
Adjust formatting. Start sections with a capital letter.
60
    print 'Location:'
1694.2.6 by Martin Pool
[merge] bzr.dev
61
    if working and branch:
62
        working_path = working.bzrdir.root_transport.base
63
        branch_path = branch.bzrdir.root_transport.base
64
        if working_path != branch_path:
65
            # lightweight checkout
66
            print '  light checkout root: %s' % working_path
67
            if repository.is_shared():
68
                # lightweight checkout of branch in shared repository
69
                print '    shared repository: %s' % repository_path
70
                print '    repository branch: %s' % (
71
                    _repo_relpath(repository_path, branch_path))
72
            else:
73
                # lightweight checkout of standalone branch
74
                print '   checkout of branch: %s' % branch_path
75
        elif repository.is_shared():
76
            # branch with tree inside shared repository
77
            print '    shared repository: %s' % repository_path
78
            print '  repository checkout: %s' % (
79
                _repo_relpath(repository_path, branch_path))
80
        elif branch.get_bound_location():
81
            # normal checkout
82
            print '       checkout root: %s' % working_path
83
            print '  checkout of branch: %s' % branch.get_bound_location()
84
        else:
85
            # standalone
86
            print '  branch root: %s' % working_path
1624.3.33 by Olaf Conradi
Simplified construct detection in location overview a lot.
87
    elif branch:
1694.2.6 by Martin Pool
[merge] bzr.dev
88
        # branch is part of shared repository
89
        assert repository.is_shared()
90
        branch_path = branch.bzrdir.root_transport.base
91
        print '  shared repository: %s' % repository_path
92
        print '  repository branch: %s' % (
93
            _repo_relpath(repository_path, branch_path))
94
    else:
95
        # shared repository
96
        assert repository.is_shared()
97
        print '  shared repository: %s' % repository_path
98
99
100
def _show_related_info(branch):
101
    """Show parent and push location of branch."""
102
    if branch.get_parent() or branch.get_push_location():
103
        print
104
        print 'Related branches:'
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
105
        if branch.get_parent():
1694.2.6 by Martin Pool
[merge] bzr.dev
106
            if branch.get_push_location():
107
                print '      parent branch: %s' % branch.get_parent()
108
            else:
109
                print '  parent branch: %s' % branch.get_parent()
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
110
        if branch.get_push_location():
1694.2.6 by Martin Pool
[merge] bzr.dev
111
            print '  publish to branch: %s' % branch.get_push_location()
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
112
113
114
def _show_format_info(control=None, repository=None, branch=None, working=None):
115
    """Show known formats for control, working, branch and repository."""
1624.3.4 by Olaf Conradi
Simplify construct detection. Make terms in user interface consistent.
116
    print
1624.3.8 by Olaf Conradi
Adjust formatting. Start sections with a capital letter.
117
    print 'Format:'
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
118
    if control:
119
        print '       control: %s' % control._format.get_format_description()
120
    if working:
121
        print '  working tree: %s' % working._format.get_format_description()
122
    if branch:
123
        print '        branch: %s' % branch._format.get_format_description()
124
    if repository:
125
        print '    repository: %s' % repository._format.get_format_description()
126
127
1694.2.6 by Martin Pool
[merge] bzr.dev
128
def _show_locking_info(repository, branch=None, working=None):
129
    """Show locking status of working, branch and repository."""
130
    if (repository.get_physical_lock_status() or
131
        (branch and branch.get_physical_lock_status()) or
132
        (working and working.get_physical_lock_status())):
133
        print
134
        print 'Lock status:'
135
        if working:
136
            if working.get_physical_lock_status():
137
                status = 'locked'
138
            else:
139
                status = 'unlocked'
140
            print '  working tree: %s' % status
141
        if branch:
142
            if branch.get_physical_lock_status():
143
                status = 'locked'
144
            else:
145
                status = 'unlocked'
146
            print '        branch: %s' % status
147
        if repository:
148
            if repository.get_physical_lock_status():
149
                status = 'locked'
150
            else:
151
                status = 'unlocked'
152
            print '    repository: %s' % status
153
154
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
155
def _show_missing_revisions_branch(branch):
156
    """Show missing master revisions in branch."""
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
157
    # Try with inaccessible branch ?
1624.3.2 by Olaf Conradi
Implemented table of constructs from BzrInfo specification.
158
    master = branch.get_master_branch()
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
159
    if master:
1624.3.2 by Olaf Conradi
Implemented table of constructs from BzrInfo specification.
160
        local_extra, remote_extra = find_unmerged(branch, master)
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
161
        if remote_extra:
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
162
            print
1587.1.14 by Robert Collins
Make bound branch creation happen via 'checkout'
163
            print 'Branch is out of date: missing %d revision%s.' % (
164
                len(remote_extra), plural(len(remote_extra)))
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
165
166
167
def _show_missing_revisions_working(working):
168
    """Show missing revisions in working tree."""
169
    branch = working.branch
170
    basis = working.basis_tree()
171
    work_inv = working.inventory
172
    delta = diff.compare_trees(basis, working, want_unchanged=True)
173
    history = branch.revision_history()
1624.3.11 by Olaf Conradi
Test cases exposed a bug in missing revisions count of working tree. It
174
    tree_last_id = working.last_revision()
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
175
1624.3.11 by Olaf Conradi
Test cases exposed a bug in missing revisions count of working tree. It
176
    if len(history) and tree_last_id != history[-1]:
177
        tree_last_revno = branch.revision_id_to_revno(tree_last_id)
178
        missing_count = len(history) - tree_last_revno
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
179
        print
1534.5.1 by Robert Collins
Give info some reasonable output and tests.
180
        print 'Working tree is out of date: missing %d revision%s.' % (
181
            missing_count, plural(missing_count))
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
182
183
184
def _show_working_stats(working):
185
    """Show statistics about a working tree."""
186
    basis = working.basis_tree()
187
    work_inv = working.inventory
188
    delta = diff.compare_trees(basis, working, want_unchanged=True)
189
190
    print
1624.3.8 by Olaf Conradi
Adjust formatting. Start sections with a capital letter.
191
    print 'In the working tree:'
463 by Martin Pool
- compare_trees() also reports unchanged files
192
    print '  %8s unchanged' % len(delta.unchanged)
462 by Martin Pool
- New form 'file_id in tree' to check if the file is present
193
    print '  %8d modified' % len(delta.modified)
194
    print '  %8d added' % len(delta.added)
195
    print '  %8d removed' % len(delta.removed)
196
    print '  %8d renamed' % len(delta.renamed)
197
198
    ignore_cnt = unknown_cnt = 0
199
    for path in working.extras():
200
        if working.is_ignored(path):
201
            ignore_cnt += 1
202
        else:
203
            unknown_cnt += 1
204
    print '  %8d unknown' % unknown_cnt
205
    print '  %8d ignored' % ignore_cnt
206
207
    dir_cnt = 0
208
    for file_id in work_inv:
209
        if work_inv.get_file_kind(file_id) == 'directory':
210
            dir_cnt += 1
211
    print '  %8d versioned %s' \
212
          % (dir_cnt,
213
             plural(dir_cnt, 'subdirectory', 'subdirectories'))
77 by mbp at sourcefrog
- split info command out into separate file
214
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
215
216
def _show_branch_stats(branch, verbose):
217
    """Show statistics about a branch."""
218
    repository = branch.repository
219
    history = branch.revision_history()
220
77 by mbp at sourcefrog
- split info command out into separate file
221
    print
1624.3.8 by Olaf Conradi
Adjust formatting. Start sections with a capital letter.
222
    print 'Branch history:'
77 by mbp at sourcefrog
- split info command out into separate file
223
    revno = len(history)
111 by mbp at sourcefrog
Make fields wider in 'bzr info' output to accomodate big trees
224
    print '  %8d revision%s' % (revno, plural(revno))
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
225
    if verbose:
226
        committers = {}
227
        for rev in history:
228
            committers[repository.get_revision(rev).committer] = True
229
        print '  %8d committer%s' % (len(committers), plural(len(committers)))
77 by mbp at sourcefrog
- split info command out into separate file
230
    if revno > 0:
1624.3.17 by Olaf Conradi
Remove indirection in branch.repository as it is available as repository
231
        firstrev = repository.get_revision(history[0])
77 by mbp at sourcefrog
- split info command out into separate file
232
        age = int((time.time() - firstrev.timestamp) / 3600 / 24)
111 by mbp at sourcefrog
Make fields wider in 'bzr info' output to accomodate big trees
233
        print '  %8d day%s old' % (age, plural(age))
1694.2.6 by Martin Pool
[merge] bzr.dev
234
        print '   first revision: %s' % osutils.format_date(firstrev.timestamp,
235
                                                            firstrev.timezone)
77 by mbp at sourcefrog
- split info command out into separate file
236
1624.3.17 by Olaf Conradi
Remove indirection in branch.repository as it is available as repository
237
        lastrev = repository.get_revision(history[-1])
1694.2.6 by Martin Pool
[merge] bzr.dev
238
        print '  latest revision: %s' % osutils.format_date(lastrev.timestamp,
239
                                                            lastrev.timezone)
80 by mbp at sourcefrog
show_info: Show number of entries in the branch stores
240
1286 by Martin Pool
- stub out display of store size in info command
241
#     print
1624.3.8 by Olaf Conradi
Adjust formatting. Start sections with a capital letter.
242
#     print 'Text store:'
1624.3.2 by Olaf Conradi
Implemented table of constructs from BzrInfo specification.
243
#     c, t = branch.text_store.total_size()
1286 by Martin Pool
- stub out display of store size in info command
244
#     print '  %8d file texts' % c
1624.3.14 by Olaf Conradi
Move to using kibi for binary prefix as per standard IEEE 1541.
245
#     print '  %8d KiB' % (t/1024)
80 by mbp at sourcefrog
show_info: Show number of entries in the branch stores
246
1286 by Martin Pool
- stub out display of store size in info command
247
#     print
1624.3.8 by Olaf Conradi
Adjust formatting. Start sections with a capital letter.
248
#     print 'Inventory store:'
1624.3.2 by Olaf Conradi
Implemented table of constructs from BzrInfo specification.
249
#     c, t = branch.inventory_store.total_size()
1286 by Martin Pool
- stub out display of store size in info command
250
#     print '  %8d inventories' % c
1624.3.14 by Olaf Conradi
Move to using kibi for binary prefix as per standard IEEE 1541.
251
#     print '  %8d KiB' % (t/1024)
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
252
253
254
def _show_repository_info(repository):
255
    """Show settings of a repository."""
256
    if repository.make_working_trees():
257
        print
258
        print 'Create working tree for new branches inside the repository.'
259
260
261
def _show_repository_stats(repository):
262
    """Show statistics about a repository."""
263
    if repository.bzrdir.root_transport.listable():
264
        print
265
        print 'Revision store:'
266
        c, t = repository._revision_store.total_size(repository.get_transaction())
267
        print '  %8d revision%s' % (c, plural(c))
268
        print '  %8d KiB' % (t/1024)
269
270
271
@deprecated_function(zero_eight)
272
def show_info(b):
273
    """Please see show_bzrdir_info."""
274
    return show_bzrdir_info(b.bzrdir)
275
276
277
def show_bzrdir_info(a_bzrdir, verbose=False):
278
    """Output to stdout the 'info' for a_bzrdir."""
279
    try:
280
        working = a_bzrdir.open_workingtree()
1624.3.35 by Olaf Conradi
Implemented locking status for formats using LockDir.
281
        working.lock_read()
282
        try:
283
            show_tree_info(working, verbose)
284
        finally:
285
            working.unlock()
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
286
        return
287
    except (NoWorkingTree, NotLocalUrl):
288
        pass
289
290
    try:
291
        branch = a_bzrdir.open_branch()
1624.3.35 by Olaf Conradi
Implemented locking status for formats using LockDir.
292
        branch.lock_read()
293
        try:
294
            show_branch_info(branch, verbose)
295
        finally:
296
            branch.unlock()
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
297
        return
298
    except NotBranchError:
299
        pass
300
301
    try:
302
        repository = a_bzrdir.open_repository()
1624.3.35 by Olaf Conradi
Implemented locking status for formats using LockDir.
303
        repository.lock_read()
304
        try:
305
            show_repository_info(repository, verbose)
306
        finally:
307
            repository.unlock()
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
308
        return
309
    except NoRepositoryPresent:
310
        pass
311
1694.2.6 by Martin Pool
[merge] bzr.dev
312
    # Return silently, cmd_info already returned NotBranchError if no bzrdir
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
313
    # could be opened.
314
315
316
def show_tree_info(working, verbose):
317
    """Output to stdout the 'info' for working."""
318
    branch = working.branch
319
    repository = branch.repository
320
    control = working.bzrdir
321
322
    _show_location_info(repository, branch, working)
1694.2.6 by Martin Pool
[merge] bzr.dev
323
    _show_related_info(branch)
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
324
    _show_format_info(control, repository, branch, working)
1694.2.6 by Martin Pool
[merge] bzr.dev
325
    _show_locking_info(repository, branch, working)
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
326
    _show_missing_revisions_branch(branch)
327
    _show_missing_revisions_working(working)
328
    _show_working_stats(working)
329
    _show_branch_stats(branch, verbose)
330
    _show_repository_stats(repository)
331
332
333
def show_branch_info(branch, verbose):
334
    """Output to stdout the 'info' for branch."""
335
    repository = branch.repository
336
    control = branch.bzrdir
337
338
    _show_location_info(repository, branch)
1694.2.6 by Martin Pool
[merge] bzr.dev
339
    _show_related_info(branch)
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
340
    _show_format_info(control, repository, branch)
1694.2.6 by Martin Pool
[merge] bzr.dev
341
    _show_locking_info(repository, branch)
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
342
    _show_missing_revisions_branch(branch)
343
    _show_branch_stats(branch, verbose)
344
    _show_repository_stats(repository)
345
346
347
def show_repository_info(repository, verbose):
1694.2.6 by Martin Pool
[merge] bzr.dev
348
    """Output to stdout the 'info' for repository."""
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
349
    control = repository.bzrdir
350
351
    _show_location_info(repository)
352
    _show_format_info(control, repository)
1694.2.6 by Martin Pool
[merge] bzr.dev
353
    _show_locking_info(repository)
1624.3.21 by Olaf Conradi
Make bzr info command work on both local and remote locations. Support
354
    _show_repository_info(repository)
355
    _show_repository_stats(repository)