1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2
# Some parts of the code are:
3
# Copyright (C) 2005, 2006 by Canonical Ltd
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.
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.
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
23
import bzrlib.osutils as osutils
25
from bzrlib.info import _repo_rel_url
26
from bzrlib.missing import find_unmerged
28
def get_location_info(repository, branch=None, working=None):
29
""" Get known locations for working, branch and repository.
31
:return: a dictionary containing the needed infos
34
repository_path = repository.bzrdir.root_transport.base
35
if working and branch:
36
working_path = working.bzrdir.root_transport.base
37
branch_path = branch.bzrdir.root_transport.base
38
if working_path != branch_path:
39
# lightweight checkout
40
ret['lightcoroot'] = working_path
41
if repository.is_shared():
42
# lightweight checkout of branch in shared repository
43
ret['sharedrepo'] = repository_path
44
ret['repobranch'] = _repo_rel_url(repository_path, branch_path)
46
# lightweight checkout of standalone branch
47
ret['cobranch'] = branch_path
48
elif repository.is_shared():
49
# branch with tree inside shared repository
50
ret['sharedrepo'] = repository_path
51
ret['repoco'] = _repo_rel_url(repository_path, branch_path)
52
elif branch.get_bound_location():
54
ret['coroot'] = working_path
55
ret['cobranch'] = branch.get_bound_location()
58
ret['branchroot'] = working_path
60
branch_path = branch.bzrdir.root_transport.base
61
if repository.is_shared():
62
# branch is part of shared repository
63
ret['sharedrepo'] = repository_path
64
ret['repobranch'] = _repo_rel_url(repository_path, branch_path)
67
ret['branchroot'] = branch_path
70
assert repository.is_shared()
71
ret['sharedrepo'] = repository_path
75
def get_related_info(branch):
76
""" Get parent and push location of branch.
78
:return: a dictionary containing the needed infos
81
if branch.get_parent() or branch.get_push_location():
82
if branch.get_parent():
83
ret['parentbranch'] = branch.get_parent()
84
if branch.get_push_location():
85
ret['publishbranch'] = branch.get_push_location()
90
def get_format_info(control=None, repository=None, branch=None, working=None):
91
""" Get known formats for control, working, branch and repository.
93
:return: a dictionary containing the needed infos
97
ret['control'] = control._format.get_format_description()
99
ret['workingtree'] = working._format.get_format_description()
101
ret['branch'] = branch._format.get_format_description()
103
ret['repository'] = repository._format.get_format_description()
108
def get_locking_info(repository, branch=None, working=None):
109
""" Get locking status of working, branch and repository.
111
:return: a dictionary containing the needed infos
114
if (repository.get_physical_lock_status() or
115
(branch and branch.get_physical_lock_status()) or
116
(working and working.get_physical_lock_status())):
118
if working.get_physical_lock_status():
122
ret['workingtree'] = status
124
if branch.get_physical_lock_status():
128
ret['branch'] = status
130
if repository.get_physical_lock_status():
134
ret['repository'] = status
138
def get_missing_revisions_branch(branch):
139
""" Get missing master revisions in branch.
141
:return: a dictionary containing the needed infos
144
# Try with inaccessible branch ?
145
master = branch.get_master_branch()
147
local_extra, remote_extra = find_unmerged(branch, master)
149
ret = len(remote_extra)
154
def get_missing_revisions_working(working):
155
""" Get missing revisions in working tree.
157
:return: a dictionary containing the needed infos
159
if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
160
# function deprecated after 0.9
161
from bzrlib.delta import compare_trees
164
branch = working.branch
165
basis = working.basis_tree()
167
if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
168
delta = compare_trees(basis, working, want_unchanged=True)
170
delta = working.changes_from(basis, want_unchanged=True)
172
history = branch.revision_history()
173
tree_last_id = working.last_revision()
175
if len(history) and tree_last_id != history[-1]:
176
tree_last_revno = branch.revision_id_to_revno(tree_last_id)
177
missing_count = len(history) - tree_last_revno
183
def get_working_stats(working):
184
""" Get statistics about a working tree.
186
:return: a dictionary containing the needed infos
188
if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
189
# function deprecated after 0.9
190
from bzrlib.delta import compare_trees
193
basis = working.basis_tree()
195
if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
196
delta = compare_trees(basis, working, want_unchanged=True)
198
delta = working.changes_from(basis, want_unchanged=True)
200
ret['unchanged'] = len(delta.unchanged)
201
ret['modified'] = len(delta.modified)
202
ret['added'] = len(delta.added)
203
ret['removed'] = len(delta.removed)
204
ret['renamed'] = len(delta.renamed)
206
ignore_cnt = unknown_cnt = 0
207
for path in working.extras():
208
if working.is_ignored(path):
212
ret['unknown'] = unknown_cnt
213
ret['ignored'] = ignore_cnt
216
for path, ie in working.iter_entries_by_dir():
217
if ie.kind == 'directory':
219
ret['subdirs'] = dir_cnt
223
def get_branch_stats(branch):
224
""" Get statistics about a branch.
226
:return: a dictionary containing the needed infos
229
repository = branch.repository
230
history = branch.revision_history()
236
committers[repository.get_revision(rev).committer] = True
237
ret['commiters'] = len(committers)
239
firstrev = repository.get_revision(history[0])
240
age = int((time.time() - firstrev.timestamp) / 3600 / 24)
242
ret['firstrev'] = osutils.format_date(firstrev.timestamp,
245
lastrev = repository.get_revision(history[-1])
246
ret['lastrev'] = osutils.format_date(lastrev.timestamp,
251
def get_repository_stats(repository):
252
""" Get statistics about a repository.
254
:return: a dictionary containing the needed infos
257
if repository.bzrdir.root_transport.listable():
258
c, t = repository._revision_store.total_size(repository.get_transaction())
264
def diff_helper(tree, specific_files, external_diff_options,
265
old_revision_spec=None, new_revision_spec=None,
266
old_label='a/', new_label='b/', output=None):
269
:param tree: a WorkingTree
271
:param specific_files: the specific files to compare, or None
273
:param external_diff_options: if non-None, run an external diff, and pass it these options
275
:param old_revision_spec: if None, use basis tree as old revision, otherwise use the tree for the specified revision.
277
:param new_revision_spec: if None, use working tree as new revision, otherwise use the tree for the specified revision.
281
from bzrlib.diff import show_diff_trees
287
revision_id = spec.in_store(tree.branch).rev_id
288
return tree.branch.repository.revision_tree(revision_id)
290
if old_revision_spec is None:
291
old_tree = tree.basis_tree()
293
old_tree = spec_tree(old_revision_spec)
295
if new_revision_spec is None:
298
new_tree = spec_tree(new_revision_spec)
300
return show_diff_trees(old_tree, new_tree, output, specific_files,
301
external_diff_options,
302
old_label=old_label, new_label=new_label)