/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1 by mbp at sourcefrog
import from baz patch-364
1
# Copyright (C) 2004, 2005 by Martin Pool
2
# Copyright (C) 2005 by Canonical Ltd
3
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
1335 by Martin Pool
doc
18
# TODO: Check ancestries are correct for every revision: includes
19
# every committed so far, and in a reasonable order.
20
1347 by Martin Pool
- refactor check code into method object
21
# TODO: Also check non-mainline revisions mentioned as parents.
22
23
# TODO: Check for extra files in the control directory.
24
1348 by Martin Pool
- more refactoring of check code
25
# TODO: Check revision, inventory and entry objects have all 
26
# required fields.
27
1347 by Martin Pool
- refactor check code into method object
28
1104 by Martin Pool
- Add a simple UIFactory
29
import bzrlib.ui
1130 by Martin Pool
- check command writes output through logging not direct
30
from bzrlib.trace import note, warning
1346 by Martin Pool
- remove dead code from bzrlib.check
31
from bzrlib.osutils import rename, sha_string, fingerprint_file
32
from bzrlib.trace import mutter
33
from bzrlib.errors import BzrCheckError, NoSuchRevision
34
from bzrlib.inventory import ROOT_ID
35
from bzrlib.branch import gen_root_id
1 by mbp at sourcefrog
import from baz patch-364
36
1104 by Martin Pool
- Add a simple UIFactory
37
1347 by Martin Pool
- refactor check code into method object
38
class Check(object):
39
    """Check a branch"""
40
    def __init__(self, branch):
41
        self.branch = branch
42
        self.run()
43
44
45
    def run(self):
46
        branch = self.branch
47
1348 by Martin Pool
- more refactoring of check code
48
	self.checked_text_cnt = 0
49
	self.checked_rev_cnt = 0
50
        self.missing_inventory_sha_cnt = 0
51
        self.missing_revision_cnt = 0
676 by Martin Pool
- lock branch while checking
52
53
        history = branch.revision_history()
54
        revno = 0
55
        revcount = len(history)
56
1348 by Martin Pool
- more refactoring of check code
57
        last_rev_id = None
58
        self.progress = bzrlib.ui.ui_factory.progress_bar()
703 by Martin Pool
- split out a new 'bzr upgrade' command separate from
59
        for rev_id in history:
1348 by Martin Pool
- more refactoring of check code
60
            self.progress.update('checking revision', revno, revcount)
676 by Martin Pool
- lock branch while checking
61
            revno += 1
1348 by Martin Pool
- more refactoring of check code
62
	    self.check_one_rev(rev_id, last_rev_id)
63
	    last_rev_id = rev_id
64
        self.progress.clear()
65
	self.report_results()
66
67
68
    def report_results(self):
69
	note('checked branch %s format %d',
70
	     self.branch.base, 
71
	     self.branch._branch_format)
72
73
        note('checked %d revisions, %d file texts',
74
	     self.checked_rev_cnt,
75
	     self.checked_text_cnt)
76
77
        if self.missing_inventory_sha_cnt:
78
            note('%d revisions are missing inventory_sha1',
79
		 self.missing_inventory_sha_cnt)
80
81
        if self.missing_revision_cnt:
82
            note('%d revisions are mentioned but not present',
83
		 self.missing_revision_cnt)
84
85
86
    def check_one_rev(self, rev_id, last_rev_id):
1349 by Martin Pool
- more refactoring of check code
87
	"""Check one revision.
88
89
	rev_id - the one to check
90
91
	last_rev_id - the previous one on the mainline, if any.
92
	"""
93
1348 by Martin Pool
- more refactoring of check code
94
	# mutter('    revision {%s}' % rev_id)
95
	branch = self.branch
96
	rev = branch.get_revision(rev_id)
97
	if rev.revision_id != rev_id:
98
	    raise BzrCheckError('wrong internal revision id in revision {%s}'
99
				% rev_id)
100
101
	# check the previous history entry is a parent of this entry
102
	if rev.parent_ids:
103
	    if last_rev_id is None:
104
		raise BzrCheckError("revision {%s} has %d parents, but is the "
105
				    "start of the branch"
106
				    % (rev_id, len(rev.parent_ids)))
107
	    for parent_id in rev.parent_ids:
108
		if parent_id == last_rev_id:
109
		    break
110
	    else:
111
		raise BzrCheckError("previous revision {%s} not listed among "
112
				    "parents of {%s}"
113
				    % (last_rev_id, rev_id))
114
	elif last_rev_id:
115
	    raise BzrCheckError("revision {%s} has no parents listed "
116
				"but preceded by {%s}"
117
				% (rev_id, last_rev_id))
118
119
	if rev.inventory_sha1:
120
	    inv_sha1 = branch.get_inventory_sha1(rev_id)
121
	    if inv_sha1 != rev.inventory_sha1:
122
		raise BzrCheckError('Inventory sha1 hash doesn\'t match'
123
		    ' value in revision {%s}' % rev_id)
124
	else:
125
	    missing_inventory_sha_cnt += 1
126
	    mutter("no inventory_sha1 on revision {%s}" % rev_id)
127
1349 by Martin Pool
- more refactoring of check code
128
	self._check_revision_tree(rev_id)
129
130
    def _check_revision_tree(self, rev_id):
131
	tree = self.branch.revision_tree(rev_id)
1348 by Martin Pool
- more refactoring of check code
132
	inv = tree.inventory
133
	seen_ids = {}
134
	for file_id in inv:
135
	    if file_id in seen_ids:
136
		raise BzrCheckError('duplicated file_id {%s} '
137
				    'in inventory for revision {%s}'
138
				    % (file_id, rev_id))
139
	    seen_ids[file_id] = True
140
	for file_id in inv:
1349 by Martin Pool
- more refactoring of check code
141
	    self._check_one_entry(rev_id, inv, tree, file_id)
142
	seen_names = {}
1348 by Martin Pool
- more refactoring of check code
143
	for path, ie in inv.iter_entries():
144
	    if path in seen_names:
145
		raise BzrCheckError('duplicated path %s '
146
				    'in inventory for revision {%s}'
147
				    % (path, rev_id))
148
	    seen_names[path] = True
1349 by Martin Pool
- more refactoring of check code
149
150
	
151
    def _check_one_entry(self, rev_id, inv, tree, file_id):
152
	ie = inv[file_id]
153
	if ie.parent_id != None:
154
	    if not inv.has_id(ie.parent_id):
155
		raise BzrCheckError('missing parent {%s} in inventory for revision {%s}'
156
			% (ie.parent_id, rev_id))
157
	if ie.kind == 'file':
158
	    text = tree.get_file_text(file_id)
159
	    self.checked_text_cnt += 1 
160
	    if ie.text_size != len(text):
161
		raise BzrCheckError('text {%s} wrong size' % ie.text_id)
162
	    if ie.text_sha1 != sha_string(text):
163
		raise BzrCheckError('text {%s} wrong sha1' % ie.text_id)
164
	elif ie.kind == 'directory':
165
	    if ie.text_sha1 != None or ie.text_size != None or ie.text_id != None:
166
		raise BzrCheckError('directory {%s} has text in revision {%s}'
167
			% (file_id, rev_id))
168
	elif ie.kind == 'root_directory':
169
	    pass
170
	else:
171
	    raise BzrCheckError('unknown entry kind %r in revision {%s}' % 
172
				(ie.kind, rev_id))
1347 by Martin Pool
- refactor check code into method object
173
174
175
def check(branch):
176
    """Run consistency checks on a branch."""
177
    Check(branch)