1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
import collections
from bzrlib.commands import Command, builtin_command_registry
from bzrlib import (
bzrdir,
errors,
trace,
)
class cmd_cross_check(Command):
__doc__ = """Check that 2 or more repos agree data in common.
Currently this only checks that the contents of inventories are the same in
all repos.
Use ``--verbose`` to get details of the differences.
"""
takes_args = ['repository*']
takes_options = ['revision', 'verbose']
def run(self, revision=None, repository_list=None, verbose=False):
if not repository_list or len(repository_list) < 2:
raise errors.BzrCommandError("At least 2 repos required.")
repos = []
possible_transports = []
for repo_path in repository_list:
bd, leftover_path = bzrdir.BzrDir.open_containing(repo_path,
possible_transports=possible_transports)
possible_transports.append(bd.root_transport)
repo = bd.find_repository()
self.add_cleanup(repo.lock_read().unlock)
repos.append(repo)
inv_counts = collections.defaultdict(lambda: 0)
for repo in repos:
for inv_key in repo.inventories.keys():
inv_counts[inv_key] += 1
all_inv_keys = frozenset(inv_counts)
common_inv_keys = set()
for inv_key, count in inv_counts.iteritems():
if count >= 2:
common_inv_keys.add(inv_key)
self.outf.write('%d common inventories to check (%d seen)\n' %
(len(common_inv_keys), len(all_inv_keys)))
trace.mutter('common invs: %r', common_inv_keys)
#trace.mutter('all invs: %r', all_inv_keys)
for inv_key in common_inv_keys:
inv_id = inv_key[-1]
first_inv = expected_root_1 = expected_root_2 = None
for repo in repos:
try:
inv = repo.get_inventory(inv_id)
except errors.NoSuchRevision:
continue
else:
root_1 = inv.id_to_entry.key()
root_2 = inv.parent_id_basename_to_file_id.key()
if first_inv is None:
first_inv = inv
expected_root_1 = root_1
expected_root_2 = root_2
continue
if root_1 != expected_root_1:
self.outf.write(
'disagree id_to_entry for %s: %r %r\n'
% (inv_id, expected_root_1, root_1))
if verbose:
self.outf.write(first_inv.id_to_entry._dump_tree(True))
self.outf.write(inv.id_to_entry._dump_tree(True))
if root_2 != expected_root_2:
self.outf.write(
'disagree parent_id_basename_to_file_id for %s: %r %r\n'
% (inv_id, expected_root_2, root_2))
if verbose:
self.outf.write(first_inv.parent_id_basename_to_file_id._dump_tree(True))
self.outf.write(inv.parent_id_basename_to_file_id._dump_tree(True))
builtin_command_registry.register(cmd_cross_check)
|