From: Avery Pennarun Date: Thu, 2 Sep 2010 21:26:25 +0000 (-0700) Subject: git.py: recover more elegantly if a MIDX file has the wrong version. X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=d6b576b029da7519b8f4c9e9b024576d4e74e66d;p=packages%2Fb%2Fbup.git git.py: recover more elegantly if a MIDX file has the wrong version. Previously we'd throw an assertion for any too-new-format MIDX file, which isn't so good. Let's recover more politely (and just ignore the file in question) if that happens. Noticed by Zoran Zaric who was testing my midx3 branch. Signed-off-by: Avery Pennarun --- diff --git a/lib/bup/git.py b/lib/bup/git.py index f27e760..391ba94 100644 --- a/lib/bup/git.py +++ b/lib/bup/git.py @@ -6,6 +6,8 @@ import os, zlib, time, subprocess, struct, stat, re, tempfile import heapq from bup.helpers import * +MIDX_VERSION = 2 + verbose = 0 ignore_midx = 0 home_repodir = os.path.expanduser('~/.bup') @@ -207,24 +209,39 @@ class PackMidx: """ def __init__(self, filename): self.name = filename + self.force_keep = False assert(filename.endswith('.midx')) self.map = mmap_read(open(filename)) - if str(self.map[0:8]) == 'MIDX\0\0\0\1': - log('Warning: ignoring old-style midx %r\n' % filename) - self.bits = 0 - self.entries = 1 - self.fanout = buffer('\0\0\0\0') - self.shalist = buffer('\0'*20) - self.idxnames = [] - else: - assert(str(self.map[0:8]) == 'MIDX\0\0\0\2') - self.bits = struct.unpack('!I', self.map[8:12])[0] - self.entries = 2**self.bits - self.fanout = buffer(self.map, 12, self.entries*4) - shaofs = 12 + self.entries*4 - nsha = self._fanget(self.entries-1) - self.shalist = buffer(self.map, shaofs, nsha*20) - self.idxnames = str(self.map[shaofs + 20*nsha:]).split('\0') + if str(self.map[0:4]) != 'MIDX': + log('Warning: skipping: invalid MIDX header in %r\n' % filename) + self.force_keep = True + return self._init_failed() + ver = struct.unpack('!I', self.map[4:8])[0] + if ver < MIDX_VERSION: + log('Warning: ignoring old-style (v%d) midx %r\n' + % (ver, filename)) + self.force_keep = False # old stuff is boring + return self._init_failed() + if ver > MIDX_VERSION: + log('Warning: ignoring too-new (v%d) midx %r\n' + % (ver, filename)) + self.force_keep = True # new stuff is exciting + return self._init_failed() + + self.bits = struct.unpack('!I', self.map[8:12])[0] + self.entries = 2**self.bits + self.fanout = buffer(self.map, 12, self.entries*4) + shaofs = 12 + self.entries*4 + nsha = self._fanget(self.entries-1) + self.shalist = buffer(self.map, shaofs, nsha*20) + self.idxnames = str(self.map[shaofs + 20*nsha:]).split('\0') + + def _init_failed(self): + self.bits = 0 + self.entries = 1 + self.fanout = buffer('\0\0\0\0') + self.shalist = buffer('\0'*20) + self.idxnames = [] def _fanget(self, i): start = i*4 @@ -347,7 +364,7 @@ class PackIdxList: d[os.path.join(self.dir, name)] = ix any += 1 break - if not any: + if not any and not ix.force_keep: log('midx: removing redundant: %s\n' % os.path.basename(ix.name)) unlink(ix.name)