From: Rob Browning Date: Sun, 12 Jun 2016 20:50:46 +0000 (-0500) Subject: gc: explicitly handle missing objects X-Git-Tag: 0.29-rc1~47 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=bup.git;a=commitdiff_plain;h=06ba7da77423400a40b9093a3aeb524ac5698dad gc: explicitly handle missing objects 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 Tested-by: Rob Browning --- diff --git a/cmd/gc-cmd.py b/cmd/gc-cmd.py index a3cf60f..a95f8f6 100755 --- a/cmd/gc-cmd.py +++ b/cmd/gc-cmd.py @@ -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? diff --git a/lib/bup/git.py b/lib/bup/git.py index 0f770a4..9c5f1f7 100644 --- a/lib/bup/git.py +++ b/lib/bup/git.py @@ -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)