parts.append(part)
shalists.append([])
-def _pop():
+def _pop(force_tree):
assert(len(parts) > 1)
part = parts.pop()
shalist = shalists.pop()
- tree = w.new_tree(shalist)
+ tree = force_tree or w.new_tree(shalist)
shalists[-1].append(('40000', part, tree))
return tree
r = index.Reader(git.repo('bupindex'))
+def already_saved(ent):
+ return ent.is_valid() and w.exists(ent.sha) and ent.sha
+
+def wantrecurse(ent):
+ return not already_saved(ent)
+
total = ftotal = 0
if opt.progress:
- for (transname,ent) in r.filter(extra):
+ for (transname,ent) in r.filter(extra, wantrecurse=wantrecurse):
if not (ftotal % 10024):
progress('Reading index: %d\r' % ftotal)
exists = (ent.flags & index.IX_EXISTS)
- hashvalid = (ent.flags & index.IX_HASHVALID) and w.exists(ent.sha)
+ hashvalid = already_saved(ent)
if exists and not hashvalid:
total += ent.size
ftotal += 1
tstart = time.time()
count = fcount = 0
-for (transname,ent) in r.filter(extra):
+for (transname,ent) in r.filter(extra, wantrecurse=wantrecurse):
(dir, file) = os.path.split(ent.name)
exists = (ent.flags & index.IX_EXISTS)
- hashvalid = (ent.flags & index.IX_HASHVALID) and w.exists(ent.sha)
+ hashvalid = already_saved(ent)
if opt.verbose:
if not exists:
status = 'D'
assert(dir.startswith('/'))
dirp = dir.split('/')
while parts > dirp:
- _pop()
+ _pop(force_tree = None)
if dir != '/':
for part in dirp[len(parts):]:
_push(part)
if not file:
# sub/parentdirectories already handled in the pop/push() part above.
- ent.validate(040000, _pop())
- ent.repack()
+ oldtree = already_saved(ent) # may be None
+ newtree = _pop(force_tree = oldtree)
+ if not oldtree:
+ ent.validate(040000, newtree)
+ ent.repack()
count += ent.size
continue
progress('Saving: %.2f%% (%d/%dk, %d/%d files), done. \n'
% (pct, count/1024, total/1024, fcount, ftotal))
-#log('parts out: %r\n' % parts)
-#log('stk out: %r\n' % shalists)
while len(parts) > 1:
- _pop()
-#log('parts out: %r\n' % parts)
-#log('stk out: %r\n' % shalists)
+ _pop(force_tree = None)
assert(len(shalists) == 1)
tree = w.new_tree(shalists[-1])
if opt.tree:
return (self.flags & IX_EXISTS) == 0
def set_deleted(self):
- self.flags &= ~(IX_EXISTS | IX_HASHVALID)
- self.set_dirty()
+ if self.flags & IX_EXISTS:
+ self.flags &= ~(IX_EXISTS | IX_HASHVALID)
+ self.set_dirty()
def set_dirty(self):
pass # FIXME
self.parent.invalidate()
self.parent.repack()
- def iter(self, name=None):
+ def iter(self, name=None, wantrecurse=None):
dname = name
if dname and not dname.endswith('/'):
dname += '/'
if (not dname
or child.name.startswith(dname)
or child.name.endswith('/') and dname.startswith(child.name)):
- for e in child.iter(name=name):
- yield e
+ if not wantrecurse or wantrecurse(child):
+ for e in child.iter(name=name, wantrecurse=wantrecurse):
+ yield e
if not name or child.name == name or child.name.startswith(dname):
yield child
ofs = eon + 1 + ENTLEN
yield ExistingEntry(None, basename, basename, self.m, eon+1)
ofs = eon + 1 + ENTLEN
- def iter(self, name=None):
+ def iter(self, name=None, wantrecurse=None):
if len(self.m) > len(INDEX_HDR)+ENTLEN:
dname = name
if dname and not dname.endswith('/'):
dname += '/'
root = ExistingEntry(None, '/', '/',
self.m, len(self.m)-FOOTLEN-ENTLEN)
- for sub in root.iter(name=name):
+ for sub in root.iter(name=name, wantrecurse=wantrecurse):
yield sub
if not dname or dname == root.name:
yield root
self.m = None
self.writable = False
- def filter(self, prefixes):
+ def filter(self, prefixes, wantrecurse=None):
for (rp, path) in reduce_paths(prefixes):
- for e in self.iter(rp):
+ for e in self.iter(rp, wantrecurse=wantrecurse):
assert(e.name.startswith(rp))
name = path + e.name[len(rp):]
yield (name, e)