[Pkg-bazaar-commits] ./bzr/unstable r674: - check command now also checks new inventory_sha1 and

Martin Pool mbp at sourcefrog.net
Fri Apr 10 08:20:38 UTC 2009


------------------------------------------------------------
revno: 674
committer: Martin Pool <mbp at sourcefrog.net>
timestamp: Sat 2005-06-11 11:52:47 +1000
message:
  - check command now also checks new inventory_sha1 and 
   precursor_sha1 
  - check has --update option to fix these if they're missing
    patch from John A Meinel
modified:
  bzrlib/check.py
  bzrlib/commands.py
-------------- next part --------------
=== modified file 'bzrlib/check.py'
--- a/bzrlib/check.py	2005-06-10 09:07:57 +0000
+++ b/bzrlib/check.py	2005-06-11 01:52:47 +0000
@@ -18,8 +18,12 @@
 
 
 
-def check(branch):
+def check(branch, update=False):
     """Run consistency checks on a branch.
+
+    If update is True, for revisions missing certain information
+    (right now this is inventory_sha1 and revision_sha1),
+    update them to include the appropriate values.
     """
     import sys
 
@@ -33,12 +37,20 @@
     pb = ProgressBar(show_spinner=True)
     last_ptr = None
     checked_revs = {}
+
+    missing_inventory_sha_cnt = 0
     
     history = branch.revision_history()
     revno = 0
     revcount = len(history)
 
     checked_texts = {}
+
+    updated_revisions = []
+
+    # Set to True in the case that the previous revision entry
+    # was updated, since this will affect future revision entries
+    updated_previous_revision = False
     
     for rid in history:
         revno += 1
@@ -56,6 +68,83 @@
 
         ## TODO: Check all the required fields are present on the revision.
 
+        updated = False
+        if rev.inventory_sha1:
+            #mutter('    checking inventory hash {%s}' % rev.inventory_sha1)
+            inv_sha1 = branch.get_inventory_sha1(rev.inventory_id)
+            if inv_sha1 != rev.inventory_sha1:
+                raise BzrCheckError('Inventory sha1 hash doesn\'t match'
+                    ' value in revision {%s}' % rid)
+        elif update:
+            inv_sha1 = branch.get_inventory_sha1(rev.inventory_id)
+            rev.inventory_sha1 = inv_sha1
+            updated = True
+        else:
+            missing_inventory_sha_cnt += 1
+            mutter("no inventory_sha1 on revision {%s}" % rid)
+
+        if rev.precursor:
+            if rev.precursor_sha1:
+                precursor_sha1 = branch.get_revision_sha1(rev.precursor)
+                if updated_previous_revision: 
+                    # we don't expect the hashes to match, because
+                    # we had to modify the previous revision_history entry.
+                    rev.precursor_sha1 = precursor_sha1
+                    updated = True
+                else:
+                    #mutter('    checking precursor hash {%s}' % rev.precursor_sha1)
+                    if rev.precursor_sha1 != precursor_sha1:
+                        raise BzrCheckError('Precursor sha1 hash doesn\'t match'
+                            ' value in revision {%s}' % rid)
+            elif update:
+                precursor_sha1 = branch.get_revision_sha1(rev.precursor)
+                rev.precursor_sha1 = precursor_sha1
+                updated = True
+
+        if updated:
+            updated_previous_revision = True
+            # We had to update this revision entries hashes
+            # Now we need to write out a new value
+            # This is a little bit invasive, since we are *rewriting* a
+            # revision entry. I'm not supremely happy about it, but
+            # there should be *some* way of making old entries have
+            # the full meta information.
+            import tempfile, os, errno
+            rev_tmp = tempfile.TemporaryFile()
+            rev.write_xml(rev_tmp)
+            rev_tmp.seek(0)
+
+            tmpfd, tmp_path = tempfile.mkstemp(prefix=rid, suffix='.gz',
+                dir=branch.controlfilename('revision-store'))
+            os.close(tmpfd)
+            def special_rename(p1, p2):
+                if sys.platform == 'win32':
+                    try:
+                        os.remove(p2)
+                    except OSError, e:
+                        if e.errno != e.ENOENT:
+                            raise
+                os.rename(p1, p2)
+
+            try:
+                # TODO: We may need to handle the case where the old revision
+                # entry was not compressed (and thus did not end with .gz)
+
+                # Remove the old revision entry out of the way
+                rev_path = branch.controlfilename(['revision-store', rid+'.gz'])
+                special_rename(rev_path, tmp_path)
+                branch.revision_store.add(rev_tmp, rid) # Add the new one
+                os.remove(tmp_path) # Remove the old name
+                mutter('    Updated revision entry {%s}' % rid)
+            except:
+                # On any exception, restore the old entry
+                special_rename(tmp_path, rev_path)
+                raise
+            rev_tmp.close()
+            updated_revisions.append(rid)
+        else:
+            updated_previous_revision = False
+            
         inv = branch.get_inventory(rev.inventory_id)
         seen_ids = {}
         seen_names = {}
@@ -112,5 +201,10 @@
 
 
     pb.clear()
+
     print 'checked %d revisions, %d file texts' % (revcount, len(checked_texts))
-
+    if updated_revisions:
+        print '%d revisions updated to current format' % len(updated_revisions)
+    if missing_inventory_sha_cnt:
+        print '%d revisions are missing inventory_sha1' % missing_inventory_sha_cnt
+        print '  (use bzr check --update to fix them)'

=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py	2005-06-11 01:36:09 +0000
+++ b/bzrlib/commands.py	2005-06-11 01:52:47 +0000
@@ -1097,11 +1097,16 @@
 
     This command checks various invariants about the branch storage to
     detect data corruption or bzr bugs.
+
+    If given the --update flag, it will update some optional fields
+    to help ensure data consistency.
     """
     takes_args = ['dir?']
-    def run(self, dir='.'):
+    takes_options = ['update']
+
+    def run(self, dir='.', update=False):
         import bzrlib.check
-        bzrlib.check.check(Branch(dir))
+        bzrlib.check.check(Branch(dir), update=update)
 
 
 
@@ -1278,6 +1283,7 @@
     'verbose':                None,
     'version':                None,
     'email':                  None,
+    'update':                 None,
     }
 
 SHORT_OPTIONS = {



More information about the Pkg-bazaar-commits mailing list