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_relpath
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_relpath(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_relpath(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_relpath(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()
166
work_inv = working.inventory
168
if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
169
delta = compare_trees(basis, working, want_unchanged=True)
171
delta = working.changes_from(basis, want_unchanged=True)
173
history = branch.revision_history()
174
tree_last_id = working.last_revision()
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
184
def get_working_stats(working):
185
""" Get statistics about a working tree.
187
:return: a dictionary containing the needed infos
189
if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
190
# function deprecated after 0.9
191
from bzrlib.delta import compare_trees
194
basis = working.basis_tree()
195
work_inv = working.inventory
197
if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
198
delta = compare_trees(basis, working, want_unchanged=True)
200
delta = working.changes_from(basis, want_unchanged=True)
202
ret['unchanged'] = len(delta.unchanged)
203
ret['modified'] = len(delta.modified)
204
ret['added'] = len(delta.added)
205
ret['removed'] = len(delta.removed)
206
ret['renamed'] = len(delta.renamed)
208
ignore_cnt = unknown_cnt = 0
209
for path in working.extras():
210
if working.is_ignored(path):
214
ret['unknown'] = unknown_cnt
215
ret['ignored'] = ignore_cnt
218
for file_id in work_inv:
219
if work_inv.get_file_kind(file_id) == 'directory':
221
ret['subdirs'] = dir_cnt
225
def get_branch_stats(branch):
226
""" Get statistics about a branch.
228
:return: a dictionary containing the needed infos
231
repository = branch.repository
232
history = branch.revision_history()
238
committers[repository.get_revision(rev).committer] = True
239
ret['commiters'] = len(committers)
241
firstrev = repository.get_revision(history[0])
242
age = int((time.time() - firstrev.timestamp) / 3600 / 24)
244
ret['firstrev'] = osutils.format_date(firstrev.timestamp,
247
lastrev = repository.get_revision(history[-1])
248
ret['lastrev'] = osutils.format_date(lastrev.timestamp,
253
def get_repository_stats(repository):
254
""" Get statistics about a repository.
256
:return: a dictionary containing the needed infos
259
if repository.bzrdir.root_transport.listable():
260
c, t = repository._revision_store.total_size(repository.get_transaction())
266
def diff_helper(tree, specific_files, external_diff_options,
267
old_revision_spec=None, new_revision_spec=None,
268
old_label='a/', new_label='b/', output=None):
271
:param tree: a WorkingTree
273
:param specific_files: the specific files to compare, or None
275
:param external_diff_options: if non-None, run an external diff, and pass it these options
277
:param old_revision_spec: if None, use basis tree as old revision, otherwise use the tree for the specified revision.
279
:param new_revision_spec: if None, use working tree as new revision, otherwise use the tree for the specified revision.
283
from bzrlib.diff import show_diff_trees
289
revision_id = spec.in_store(tree.branch).rev_id
290
return tree.branch.repository.revision_tree(revision_id)
292
if old_revision_spec is None:
293
old_tree = tree.basis_tree()
295
old_tree = spec_tree(old_revision_spec)
297
if new_revision_spec is None:
300
new_tree = spec_tree(new_revision_spec)
302
return show_diff_trees(old_tree, new_tree, output, specific_files,
303
external_diff_options,
304
old_label=old_label, new_label=new_label)