~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/info.py

  • Committer: mbp at sourcefrog
  • Date: 2005-03-09 04:08:15 UTC
  • Revision ID: mbp@sourcefrog.net-20050309040815-13242001617e4a06
import from baz patch-364

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
19
 
__all__ = ['show_bzrdir_info']
20
 
 
21
 
import time
22
 
 
23
 
 
24
 
import bzrlib.diff as diff
25
 
from bzrlib.errors import (NoWorkingTree, NotBranchError,
26
 
                           NoRepositoryPresent, NotLocalUrl)
27
 
from bzrlib.missing import find_unmerged
28
 
from bzrlib.osutils import format_date
29
 
from bzrlib.symbol_versioning import *
30
 
 
31
 
 
32
 
def _countiter(it):
33
 
    # surely there's a builtin for this?
34
 
    i = 0
35
 
    for j in it:
36
 
        i += 1
37
 
    return i        
38
 
 
39
 
 
40
 
def plural(n, base='', pl=None):
41
 
    if n == 1:
42
 
        return base
43
 
    elif pl != None:
44
 
        return pl
45
 
    else:
46
 
        return 's'
47
 
 
48
 
 
49
 
def _show_location_info(repository=None, branch=None, working=None):
50
 
    """Show known locations for working, branch and repository."""
51
 
    print 'Location:'
52
 
    if working and branch and working.bzrdir != branch.bzrdir:
53
 
        # Lightweight checkout
54
 
        print '       checkout root: %s' % (
55
 
            working.bzrdir.root_transport.base)
56
 
        print '  checkout of branch: %s' % (
57
 
            branch.bzrdir.root_transport.base)
58
 
    elif branch:
59
 
        # Standalone or bound branch (normal checkout)
60
 
        print '         branch root: %s' % (
61
 
            branch.bzrdir.root_transport.base)
62
 
        if branch.get_bound_location():
63
 
            print '     bound to branch: %s' % branch.get_bound_location()
64
 
 
65
 
    if repository and (not branch or repository.bzrdir != branch.bzrdir):
66
 
        if repository.is_shared():
67
 
            print '   shared repository: %s' % (
68
 
                repository.bzrdir.root_transport.base)
69
 
        else:
70
 
            print '          repository: %s' % (
71
 
                repository.bzrdir.root_transport.base)
72
 
 
73
 
    if branch:
74
 
        if branch.get_parent():
75
 
            print '       parent branch: %s' % branch.get_parent()
76
 
        if branch.get_push_location():
77
 
            print '      push to branch: %s' % branch.get_push_location()
78
 
 
79
 
 
80
 
def _show_format_info(control=None, repository=None, branch=None, working=None):
81
 
    """Show known formats for control, working, branch and repository."""
82
 
    print
83
 
    print 'Format:'
84
 
    if control:
85
 
        print '       control: %s' % control._format.get_format_description()
86
 
    if working:
87
 
        print '  working tree: %s' % working._format.get_format_description()
88
 
    if branch:
89
 
        print '        branch: %s' % branch._format.get_format_description()
90
 
    if repository:
91
 
        print '    repository: %s' % repository._format.get_format_description()
92
 
 
93
 
 
94
 
def _show_missing_revisions_branch(branch):
95
 
    """Show missing master revisions in branch."""
96
 
    # Try with inaccessible branch ?
97
 
    master = branch.get_master_branch()
98
 
    if master:
99
 
        local_extra, remote_extra = find_unmerged(branch, master)
100
 
        if remote_extra:
101
 
            print
102
 
            print 'Branch is out of date: missing %d revision%s.' % (
103
 
                len(remote_extra), plural(len(remote_extra)))
104
 
 
105
 
 
106
 
def _show_missing_revisions_working(working):
107
 
    """Show missing revisions in working tree."""
108
 
    branch = working.branch
109
 
    basis = working.basis_tree()
110
 
    work_inv = working.inventory
111
 
    delta = diff.compare_trees(basis, working, want_unchanged=True)
112
 
    history = branch.revision_history()
113
 
    tree_last_id = working.last_revision()
114
 
 
115
 
    if len(history) and tree_last_id != history[-1]:
116
 
        tree_last_revno = branch.revision_id_to_revno(tree_last_id)
117
 
        missing_count = len(history) - tree_last_revno
118
 
        print
119
 
        print 'Working tree is out of date: missing %d revision%s.' % (
120
 
            missing_count, plural(missing_count))
121
 
 
122
 
 
123
 
def _show_working_stats(working):
124
 
    """Show statistics about a working tree."""
125
 
    basis = working.basis_tree()
126
 
    work_inv = working.inventory
127
 
    delta = diff.compare_trees(basis, working, want_unchanged=True)
128
 
 
129
 
    print
130
 
    print 'In the working tree:'
131
 
    print '  %8s unchanged' % len(delta.unchanged)
132
 
    print '  %8d modified' % len(delta.modified)
133
 
    print '  %8d added' % len(delta.added)
134
 
    print '  %8d removed' % len(delta.removed)
135
 
    print '  %8d renamed' % len(delta.renamed)
136
 
 
137
 
    ignore_cnt = unknown_cnt = 0
138
 
    for path in working.extras():
139
 
        if working.is_ignored(path):
140
 
            ignore_cnt += 1
141
 
        else:
142
 
            unknown_cnt += 1
143
 
    print '  %8d unknown' % unknown_cnt
144
 
    print '  %8d ignored' % ignore_cnt
145
 
 
146
 
    dir_cnt = 0
147
 
    for file_id in work_inv:
148
 
        if work_inv.get_file_kind(file_id) == 'directory':
149
 
            dir_cnt += 1
150
 
    print '  %8d versioned %s' \
151
 
          % (dir_cnt,
152
 
             plural(dir_cnt, 'subdirectory', 'subdirectories'))
153
 
 
154
 
 
155
 
def _show_branch_stats(branch, verbose):
156
 
    """Show statistics about a branch."""
157
 
    repository = branch.repository
158
 
    history = branch.revision_history()
159
 
 
160
 
    print
161
 
    print 'Branch history:'
162
 
    revno = len(history)
163
 
    print '  %8d revision%s' % (revno, plural(revno))
164
 
    if verbose:
165
 
        committers = {}
166
 
        for rev in history:
167
 
            committers[repository.get_revision(rev).committer] = True
168
 
        print '  %8d committer%s' % (len(committers), plural(len(committers)))
169
 
    if revno > 0:
170
 
        firstrev = repository.get_revision(history[0])
171
 
        age = int((time.time() - firstrev.timestamp) / 3600 / 24)
172
 
        print '  %8d day%s old' % (age, plural(age))
173
 
        print '   first revision: %s' % format_date(firstrev.timestamp,
174
 
                                                    firstrev.timezone)
175
 
 
176
 
        lastrev = repository.get_revision(history[-1])
177
 
        print '  latest revision: %s' % format_date(lastrev.timestamp,
178
 
                                                    lastrev.timezone)
179
 
 
180
 
#     print
181
 
#     print 'Text store:'
182
 
#     c, t = branch.text_store.total_size()
183
 
#     print '  %8d file texts' % c
184
 
#     print '  %8d KiB' % (t/1024)
185
 
 
186
 
#     print
187
 
#     print 'Inventory store:'
188
 
#     c, t = branch.inventory_store.total_size()
189
 
#     print '  %8d inventories' % c
190
 
#     print '  %8d KiB' % (t/1024)
191
 
 
192
 
 
193
 
def _show_repository_info(repository):
194
 
    """Show settings of a repository."""
195
 
    if repository.make_working_trees():
196
 
        print
197
 
        print 'Create working tree for new branches inside the repository.'
198
 
 
199
 
 
200
 
def _show_repository_stats(repository):
201
 
    """Show statistics about a repository."""
202
 
    if repository.bzrdir.root_transport.listable():
203
 
        print
204
 
        print 'Revision store:'
205
 
        c, t = repository._revision_store.total_size(repository.get_transaction())
206
 
        print '  %8d revision%s' % (c, plural(c))
207
 
        print '  %8d KiB' % (t/1024)
208
 
 
209
 
 
210
 
@deprecated_function(zero_eight)
211
 
def show_info(b):
212
 
    """Please see show_bzrdir_info."""
213
 
    return show_bzrdir_info(b.bzrdir)
214
 
 
215
 
 
216
 
def show_bzrdir_info(a_bzrdir, verbose=False):
217
 
    """Output to stdout the 'info' for a_bzrdir."""
218
 
    try:
219
 
        working = a_bzrdir.open_workingtree()
220
 
        working.lock_read()
221
 
        try:
222
 
            show_tree_info(working, verbose)
223
 
        finally:
224
 
            working.unlock()
225
 
        return
226
 
    except (NoWorkingTree, NotLocalUrl):
227
 
        pass
228
 
 
229
 
    try:
230
 
        branch = a_bzrdir.open_branch()
231
 
        branch.lock_read()
232
 
        try:
233
 
            show_branch_info(branch, verbose)
234
 
        finally:
235
 
            branch.unlock()
236
 
        return
237
 
    except NotBranchError:
238
 
        pass
239
 
 
240
 
    try:
241
 
        repository = a_bzrdir.open_repository()
242
 
        repository.lock_read()
243
 
        try:
244
 
            show_repository_info(repository, verbose)
245
 
        finally:
246
 
            repository.unlock()
247
 
        return
248
 
    except NoRepositoryPresent:
249
 
        pass
250
 
 
251
 
    # Return silently, cmd_info returns NotBranchError if no bzrdir
252
 
    # could be opened.
253
 
 
254
 
 
255
 
def show_tree_info(working, verbose):
256
 
    """Output to stdout the 'info' for working."""
257
 
    branch = working.branch
258
 
    repository = branch.repository
259
 
    control = working.bzrdir
260
 
 
261
 
    _show_location_info(repository, branch, working)
262
 
    _show_format_info(control, repository, branch, working)
263
 
    _show_missing_revisions_branch(branch)
264
 
    _show_missing_revisions_working(working)
265
 
    _show_working_stats(working)
266
 
    _show_branch_stats(branch, verbose)
267
 
    _show_repository_stats(repository)
268
 
 
269
 
 
270
 
def show_branch_info(branch, verbose):
271
 
    """Output to stdout the 'info' for branch."""
272
 
    repository = branch.repository
273
 
    control = branch.bzrdir
274
 
 
275
 
    _show_location_info(repository, branch)
276
 
    _show_format_info(control, repository, branch)
277
 
    _show_missing_revisions_branch(branch)
278
 
    _show_branch_stats(branch, verbose)
279
 
    _show_repository_stats(repository)
280
 
 
281
 
 
282
 
def show_repository_info(repository, verbose):
283
 
    """Output to stdout the 'info' for branch."""
284
 
    control = repository.bzrdir
285
 
 
286
 
    _show_location_info(repository)
287
 
    _show_format_info(control, repository)
288
 
    _show_repository_info(repository)
289
 
    _show_repository_stats(repository)