~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/check.py

  • Committer: Martin Pool
  • Date: 2005-09-16 09:56:24 UTC
  • Revision ID: mbp@sourcefrog.net-20050916095623-ca0dff452934f21f
- make progress bar more tolerant of out-of-range values

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
 
18
import bzrlib.ui
 
19
from bzrlib.trace import note, warning
 
20
from bzrlib.osutils import rename, sha_string
18
21
 
19
22
def _update_store_entry(obj, obj_id, branch, store_name, store):
20
23
    """This is just a meta-function, which handles both revision entries
22
25
    """
23
26
    from bzrlib.trace import mutter
24
27
    import tempfile, os, errno
25
 
    from osutils import rename
26
28
    obj_tmp = tempfile.TemporaryFile()
27
29
    obj.write_xml(obj_tmp)
28
30
    obj_tmp.seek(0)
70
72
    :param inv_id:  The inventory id for this inventory
71
73
    :param branch:  The Branch where this entry will be stored.
72
74
    """
73
 
    _update_store_entry(inv, inv_id, branch,
74
 
            'inventory-store', branch.inventory_store)
 
75
    raise NotImplementedError("can't update existing inventory entry")
 
76
 
75
77
 
76
78
def check(branch):
77
79
    """Run consistency checks on a branch.
81
83
    TODO: Check for extra files in the control directory.
82
84
    """
83
85
    from bzrlib.trace import mutter
84
 
    from bzrlib.errors import BzrCheckError
 
86
    from bzrlib.errors import BzrCheckError, NoSuchRevision
85
87
    from bzrlib.osutils import fingerprint_file
86
 
    from bzrlib.progress import ProgressBar
87
88
    from bzrlib.inventory import ROOT_ID
88
89
    from bzrlib.branch import gen_root_id
89
90
 
90
91
    branch.lock_read()
91
92
 
92
93
    try:
93
 
        pb = ProgressBar(show_spinner=True)
94
94
        last_rev_id = None
95
95
 
96
96
        missing_inventory_sha_cnt = 0
97
97
        missing_revision_sha_cnt = 0
 
98
        missing_revision_cnt = 0
98
99
 
99
100
        history = branch.revision_history()
100
101
        revno = 0
101
102
        revcount = len(history)
102
 
        mismatch_inv_id = []
103
 
 
104
 
        # for all texts checked, text_id -> sha1
105
 
        checked_texts = {}
 
103
 
 
104
        checked_text_count = 0
 
105
 
 
106
        progress = bzrlib.ui.ui_factory.progress_bar()
106
107
 
107
108
        for rev_id in history:
108
109
            revno += 1
109
 
            pb.update('checking revision', revno, revcount)
110
 
            mutter('    revision {%s}' % rev_id)
 
110
            progress.update('checking revision', revno, revcount)
 
111
            # mutter('    revision {%s}' % rev_id)
111
112
            rev = branch.get_revision(rev_id)
112
113
            if rev.revision_id != rev_id:
113
114
                raise BzrCheckError('wrong internal revision id in revision {%s}'
132
133
                        missing_revision_sha_cnt += 1
133
134
                        continue
134
135
                    prid = prr.revision_id
135
 
                    actual_sha = branch.get_revision_sha1(prid)
 
136
                    
 
137
                    try:
 
138
                        actual_sha = branch.get_revision_sha1(prid)
 
139
                    except NoSuchRevision:
 
140
                        missing_revision_cnt += 1
 
141
                        mutter("parent {%s} of {%s} not present in store",
 
142
                               prid, rev_id)
 
143
                        continue
 
144
                        
136
145
                    if prr.revision_sha1 != actual_sha:
137
146
                        raise BzrCheckError("mismatched revision sha1 for "
138
147
                                            "parent {%s} of {%s}: %s vs %s"
143
152
                                    "by {%s}"
144
153
                                    % (rev_id, last_rev_id))
145
154
 
146
 
            if rev.inventory_id != rev_id:
147
 
                mismatch_inv_id.append(rev_id)
148
 
 
149
155
            ## TODO: Check all the required fields are present on the revision.
150
156
 
151
157
            if rev.inventory_sha1:
152
 
                inv_sha1 = branch.get_inventory_sha1(rev.inventory_id)
 
158
                inv_sha1 = branch.get_inventory_sha1(rev_id)
153
159
                if inv_sha1 != rev.inventory_sha1:
154
160
                    raise BzrCheckError('Inventory sha1 hash doesn\'t match'
155
161
                        ' value in revision {%s}' % rev_id)
157
163
                missing_inventory_sha_cnt += 1
158
164
                mutter("no inventory_sha1 on revision {%s}" % rev_id)
159
165
 
160
 
            inv = branch.get_inventory(rev.inventory_id)
 
166
            tree = branch.revision_tree(rev_id)
 
167
            inv = tree.inventory
161
168
            seen_ids = {}
162
169
            seen_names = {}
163
170
 
173
180
            for file_id in inv:
174
181
                i += 1
175
182
                if i & 31 == 0:
176
 
                    pb.tick()
 
183
                    progress.tick()
177
184
 
178
185
                ie = inv[file_id]
179
186
 
183
190
                                % (ie.parent_id, rev_id))
184
191
 
185
192
                if ie.kind == 'file':
186
 
                    if ie.text_id in checked_texts:
187
 
                        fp = checked_texts[ie.text_id]
188
 
                    else:
189
 
                        if not ie.text_id in branch.text_store:
190
 
                            raise BzrCheckError('text {%s} not in text_store' % ie.text_id)
191
 
 
192
 
                        tf = branch.text_store[ie.text_id]
193
 
                        fp = fingerprint_file(tf)
194
 
                        checked_texts[ie.text_id] = fp
195
 
 
196
 
                    if ie.text_size != fp['size']:
 
193
                    text = tree.get_file_text(file_id)
 
194
                    checked_text_count += 1 
 
195
                    if ie.text_size != len(text):
197
196
                        raise BzrCheckError('text {%s} wrong size' % ie.text_id)
198
 
                    if ie.text_sha1 != fp['sha1']:
 
197
                    if ie.text_sha1 != sha_string(text):
199
198
                        raise BzrCheckError('text {%s} wrong sha1' % ie.text_id)
200
199
                elif ie.kind == 'directory':
201
200
                    if ie.text_sha1 != None or ie.text_size != None or ie.text_id != None:
202
201
                        raise BzrCheckError('directory {%s} has text in revision {%s}'
203
202
                                % (file_id, rev_id))
204
203
 
205
 
            pb.tick()
 
204
            progress.tick()
206
205
            for path, ie in inv.iter_entries():
207
206
                if path in seen_names:
208
207
                    raise BzrCheckError('duplicated path %s '
209
208
                                        'in inventory for revision {%s}'
210
209
                                        % (path, rev_id))
211
 
            seen_names[path] = True
 
210
                seen_names[path] = True
212
211
            last_rev_id = rev_id
213
212
 
214
213
    finally:
215
214
        branch.unlock()
216
215
 
217
 
    pb.clear()
 
216
    progress.clear()
218
217
 
219
 
    print 'checked %d revisions, %d file texts' % (revcount, len(checked_texts))
 
218
    note('checked %d revisions, %d file texts' % (revcount, checked_text_count))
220
219
    
221
220
    if missing_inventory_sha_cnt:
222
 
        print '%d revisions are missing inventory_sha1' % missing_inventory_sha_cnt
223
 
 
224
 
    if missing_revision_sha_cnt:
225
 
        print '%d parent links are missing revision_sha1' % missing_revision_sha_cnt
226
 
 
227
 
    if (missing_inventory_sha_cnt
228
 
        or missing_revision_sha_cnt):
229
 
        print '  (use "bzr upgrade" to fix them)'
230
 
 
231
 
    if mismatch_inv_id:
232
 
        print '%d revisions have mismatched inventory ids:' % len(mismatch_inv_id)
233
 
        for rev_id in mismatch_inv_id:
234
 
            print '  ', rev_id
 
221
        note('%d revisions are missing inventory_sha1' % missing_inventory_sha_cnt)
 
222
 
 
223
    ##if missing_revision_sha_cnt:
 
224
    ##    note('%d parent links are missing revision_sha1' % missing_revision_sha_cnt)
 
225
 
 
226
    if missing_revision_cnt:
 
227
        note('%d revisions are mentioned but not present' % missing_revision_cnt)
 
228
 
 
229
    if missing_revision_cnt:
 
230
        print '%d revisions are mentioned but not present' % missing_revision_cnt
 
231
 
 
232
    # stub this out for now because the main bzr branch has references
 
233
    # to revisions that aren't present in the store -- mbp 20050804
 
234
#    if (missing_inventory_sha_cnt
 
235
#        or missing_revision_sha_cnt):
 
236
#        print '  (use "bzr upgrade" to fix them)'