~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/check.py

  • Committer: Martin Pool
  • Date: 2005-07-06 10:07:31 UTC
  • Revision ID: mbp@sourcefrog.net-20050706100731-ce25f8bf569ad1ae
- start adding refactored/simplified hash cache
  not used yet

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
 
 
21
 
def _update_store_entry(obj, obj_id, branch, store_name, store):
22
 
    """This is just a meta-function, which handles both revision entries
23
 
    and inventory entries.
24
 
    """
25
 
    from bzrlib.trace import mutter
26
 
    import tempfile, os, errno
27
 
    from osutils import rename
28
 
    obj_tmp = tempfile.TemporaryFile()
29
 
    obj.write_xml(obj_tmp)
30
 
    obj_tmp.seek(0)
31
 
 
32
 
    tmpfd, tmp_path = tempfile.mkstemp(prefix=obj_id, suffix='.gz',
33
 
        dir=branch.controlfilename(store_name))
34
 
    os.close(tmpfd)
35
 
    try:
36
 
        orig_obj_path = branch.controlfilename([store_name, obj_id+'.gz'])
37
 
        # Remove the old entry out of the way
38
 
        rename(orig_obj_path, tmp_path)
39
 
        try:
40
 
            # TODO: We may need to handle the case where the old
41
 
            # entry was not compressed (and thus did not end with .gz)
42
 
 
43
 
            store.add(obj_tmp, obj_id) # Add the new one
44
 
            os.remove(tmp_path) # Remove the old name
45
 
            mutter('    Updated %s entry {%s}' % (store_name, obj_id))
46
 
        except:
47
 
            # On any exception, restore the old entry
48
 
            rename(tmp_path, orig_obj_path)
49
 
            raise
50
 
    finally:
51
 
        if os.path.exists(tmp_path):
52
 
            # Unfortunately, the next command might throw
53
 
            # an exception, which will mask a previous exception.
54
 
            os.remove(tmp_path)
55
 
        obj_tmp.close()
56
 
 
57
 
def _update_revision_entry(rev, branch):
58
 
    """After updating the values in a revision, make sure to
59
 
    write out the data, but try to do it in an atomic manner.
60
 
 
61
 
    :param rev:    The Revision object to store
62
 
    :param branch: The Branch object where this Revision is to be stored.
63
 
    """
64
 
    _update_store_entry(rev, rev.revision_id, branch,
65
 
            'revision-store', branch.revision_store)
66
 
 
67
 
def _update_inventory_entry(inv, inv_id, branch):
68
 
    """When an inventory has been modified (such as by adding a unique tree root)
69
 
    this atomically re-generates the file.
70
 
 
71
 
    :param inv:     The Inventory
72
 
    :param inv_id:  The inventory id for this inventory
73
 
    :param branch:  The Branch where this entry will be stored.
74
 
    """
75
 
    raise NotImplementedError("can't update existing inventory entry")
 
18
 
76
19
 
77
20
 
78
21
def check(branch):
83
26
    TODO: Check for extra files in the control directory.
84
27
    """
85
28
    from bzrlib.trace import mutter
86
 
    from bzrlib.errors import BzrCheckError, NoSuchRevision
 
29
    from bzrlib.errors import BzrCheckError
87
30
    from bzrlib.osutils import fingerprint_file
88
 
    from bzrlib.inventory import ROOT_ID
89
 
    from bzrlib.branch import gen_root_id
 
31
    from bzrlib.progress import ProgressBar
90
32
 
91
33
    branch.lock_read()
92
34
 
93
35
    try:
 
36
        pb = ProgressBar(show_spinner=True)
94
37
        last_rev_id = None
95
38
 
96
39
        missing_inventory_sha_cnt = 0
97
40
        missing_revision_sha_cnt = 0
98
 
        missing_revision_cnt = 0
99
41
 
100
42
        history = branch.revision_history()
101
43
        revno = 0
105
47
        # for all texts checked, text_id -> sha1
106
48
        checked_texts = {}
107
49
 
108
 
        progress = bzrlib.ui.ui_factory.progress_bar()
109
 
 
110
50
        for rev_id in history:
111
51
            revno += 1
112
 
            progress.update('checking revision', revno, revcount)
113
 
            # mutter('    revision {%s}' % rev_id)
 
52
            pb.update('checking revision', revno, revcount)
 
53
            mutter('    revision {%s}' % rev_id)
114
54
            rev = branch.get_revision(rev_id)
115
55
            if rev.revision_id != rev_id:
116
56
                raise BzrCheckError('wrong internal revision id in revision {%s}'
135
75
                        missing_revision_sha_cnt += 1
136
76
                        continue
137
77
                    prid = prr.revision_id
138
 
                    
139
 
                    try:
140
 
                        actual_sha = branch.get_revision_sha1(prid)
141
 
                    except NoSuchRevision:
142
 
                        missing_revision_cnt += 1
143
 
                        mutter("parent {%s} of {%s} not present in store",
144
 
                               prid, rev_id)
145
 
                        continue
146
 
                        
 
78
                    actual_sha = branch.get_revision_sha1(prid)
147
79
                    if prr.revision_sha1 != actual_sha:
148
80
                        raise BzrCheckError("mismatched revision sha1 for "
149
81
                                            "parent {%s} of {%s}: %s vs %s"
154
86
                                    "by {%s}"
155
87
                                    % (rev_id, last_rev_id))
156
88
 
157
 
            if hasattr(rev, 'inventory_id') and rev.inventory_id != rev_id:
 
89
            if rev.inventory_id != rev_id:
158
90
                mismatch_inv_id.append(rev_id)
159
91
 
160
92
            ## TODO: Check all the required fields are present on the revision.
161
93
 
162
94
            if rev.inventory_sha1:
163
 
                inv_sha1 = branch.get_inventory_sha1(rev_id)
 
95
                inv_sha1 = branch.get_inventory_sha1(rev.inventory_id)
164
96
                if inv_sha1 != rev.inventory_sha1:
165
97
                    raise BzrCheckError('Inventory sha1 hash doesn\'t match'
166
98
                        ' value in revision {%s}' % rev_id)
168
100
                missing_inventory_sha_cnt += 1
169
101
                mutter("no inventory_sha1 on revision {%s}" % rev_id)
170
102
 
171
 
            inv = branch.get_inventory(rev_id)
 
103
            inv = branch.get_inventory(rev.inventory_id)
172
104
            seen_ids = {}
173
105
            seen_names = {}
174
106
 
184
116
            for file_id in inv:
185
117
                i += 1
186
118
                if i & 31 == 0:
187
 
                    progress.tick()
 
119
                    pb.tick()
188
120
 
189
121
                ie = inv[file_id]
190
122
 
213
145
                        raise BzrCheckError('directory {%s} has text in revision {%s}'
214
146
                                % (file_id, rev_id))
215
147
 
216
 
            progress.tick()
 
148
            pb.tick()
217
149
            for path, ie in inv.iter_entries():
218
150
                if path in seen_names:
219
151
                    raise BzrCheckError('duplicated path %s '
225
157
    finally:
226
158
        branch.unlock()
227
159
 
228
 
    progress.clear()
 
160
    pb.clear()
229
161
 
230
 
    note('checked %d revisions, %d file texts' % (revcount, len(checked_texts)))
 
162
    print 'checked %d revisions, %d file texts' % (revcount, len(checked_texts))
231
163
    
232
164
    if missing_inventory_sha_cnt:
233
 
        note('%d revisions are missing inventory_sha1' % missing_inventory_sha_cnt)
 
165
        print '%d revisions are missing inventory_sha1' % missing_inventory_sha_cnt
234
166
 
235
167
    if missing_revision_sha_cnt:
236
 
        note('%d parent links are missing revision_sha1' % missing_revision_sha_cnt)
237
 
 
238
 
    if missing_revision_cnt:
239
 
        note('%d revisions are mentioned but not present' % missing_revision_cnt)
240
 
 
241
 
    if missing_revision_cnt:
242
 
        print '%d revisions are mentioned but not present' % missing_revision_cnt
243
 
 
244
 
    # stub this out for now because the main bzr branch has references
245
 
    # to revisions that aren't present in the store -- mbp 20050804
246
 
#    if (missing_inventory_sha_cnt
247
 
#        or missing_revision_sha_cnt):
248
 
#        print '  (use "bzr upgrade" to fix them)'
 
168
        print '%d parent links are missing revision_sha1' % missing_revision_sha_cnt
 
169
 
 
170
    if (missing_inventory_sha_cnt
 
171
        or missing_revision_sha_cnt):
 
172
        print '  (use "bzr upgrade" to fix them)'
249
173
 
250
174
    if mismatch_inv_id:
251
 
        warning('%d revisions have mismatched inventory ids:' % len(mismatch_inv_id))
 
175
        print '%d revisions have mismatched inventory ids:' % len(mismatch_inv_id)
252
176
        for rev_id in mismatch_inv_id:
253
 
            warning('  %s', rev_id)
 
177
            print '  ', rev_id