]> arthur.barton.de Git - bup.git/commitdiff
gc: explicitly handle missing objects
authorRob Browning <rlb@defaultvalue.org>
Sun, 12 Jun 2016 20:50:46 +0000 (15:50 -0500)
committerRob Browning <rlb@defaultvalue.org>
Sat, 2 Jul 2016 16:20:31 +0000 (11:20 -0500)
Instead of just dying with a KeyError backtrace, detect missing objects
and print a friendlier message about the problem.  Having the new
MissingObject exception derive from KeyError should avoid affecting
existing code.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
cmd/gc-cmd.py
lib/bup/git.py

index a3cf60f8cb0264240f936585299b466776d50ee9..a95f8f63416d1ccec84f37eb303a9e7fcc92ae02 100755 (executable)
@@ -6,7 +6,7 @@ exec "$bup_python" "$0" ${1+"$@"}
 # end of bup preamble
 import glob, os, stat, subprocess, sys, tempfile
 from bup import bloom, git, midx, options, vfs
-from bup.git import walk_object
+from bup.git import MissingObject, walk_object
 from bup.helpers import handle_ctrl_c, log, progress, qprogress, saved_errors
 from os.path import basename
 
@@ -260,7 +260,11 @@ if not existing_count:
     if opt.verbose:
         log('nothing to collect\n')
 else:
-    live_objects = find_live_objects(existing_count, cat_pipe, opt)
+    try:
+        live_objects = find_live_objects(existing_count, cat_pipe, opt)
+    except MissingObject as ex:
+        log('bup: missing object %r \n' % ex.id.encode('hex'))
+        sys.exit(1)
     try:
         # FIXME: just rename midxes and bloom, and restore them at the end if
         # we didn't change any packs?
index 0f770a45261ecef7255b7ed329d37ca638695ec8..9c5f1f7dbc419d40680e1972f83505e082d96a74 100644 (file)
@@ -1102,6 +1102,12 @@ class _AbortableIter:
         self.abort()
 
 
+class MissingObject(KeyError):
+    def __init__(self, id):
+        self.id = id
+        KeyError.__init__(self, 'object %r is missing' % id.encode('hex'))
+
+
 _ver_warned = 0
 class CatPipe:
     """Link to 'git cat-file' that is used to retrieve blob data."""
@@ -1154,7 +1160,7 @@ class CatPipe:
         hdr = self.p.stdout.readline()
         if hdr.endswith(' missing\n'):
             self.inprogress = None
-            raise KeyError('blob %r is missing' % id)
+            raise MissingObject(id.decode('hex'))
         spl = hdr.split(' ')
         if len(spl) != 3 or len(spl[0]) != 40:
             raise GitError('expected blob, got %r' % spl)
@@ -1329,7 +1335,10 @@ def walk_object(cat_pipe, id,
                 stop_at=None,
                 include_data=None):
     """Yield everything reachable from id via cat_pipe as a WalkItem,
-    stopping whenever stop_at(id) returns true."""
+    stopping whenever stop_at(id) returns true.  Throw MissingObject
+    if a hash encountered is missing from the repository.
+
+    """
     return _walk_object(cat_pipe, id, [], [],
                         stop_at=stop_at,
                         include_data=include_data)