X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fbup%2Fgit.py;h=70673a3d2f8377f1329d254cbb002b995c75ebd4;hb=c40b3dd5fd74e72024fbaad3daf5a958aefa1c54;hp=5e52ab6f1a6ae627dfee5bd375682405eaf80a25;hpb=20494763c5ab8e33ee705d839e3d0ab2f8e37cbf;p=bup.git diff --git a/lib/bup/git.py b/lib/bup/git.py index 5e52ab6..70673a3 100644 --- a/lib/bup/git.py +++ b/lib/bup/git.py @@ -3,18 +3,19 @@ bup repositories are in Git format. This library allows us to interact with the Git data structures. """ +from __future__ import absolute_import import errno, os, sys, zlib, time, subprocess, struct, stat, re, tempfile, glob from collections import namedtuple from itertools import islice from numbers import Integral -from bup import _helpers, hashsplit, path, midx, bloom, xstat +from bup import _helpers, compat, hashsplit, path, midx, bloom, xstat from bup.helpers import (Sha1, add_error, chunkyreader, debug1, debug2, fdatasync, hostname, localtime, log, merge_iter, mmap_read, mmap_readwrite, parse_num, - progress, qprogress, stat_if_exists, + progress, qprogress, shstr, stat_if_exists, unlink, username, userfullname, utc_offset_str) @@ -36,7 +37,7 @@ class GitError(Exception): def _git_wait(cmd, p): rv = p.wait() if rv != 0: - raise GitError('%s returned %d' % (cmd, rv)) + raise GitError('%s returned %d' % (shstr(cmd), rv)) def _git_capture(argv): p = subprocess.Popen(argv, stdout=subprocess.PIPE, preexec_fn = _gitenv()) @@ -552,7 +553,7 @@ class PackIdxList: if self.bloom is None and os.path.exists(bfull): self.bloom = bloom.ShaBloom(bfull) self.packs = list(set(d.values())) - self.packs.sort(lambda x,y: -cmp(len(x),len(y))) + self.packs.sort(reverse=True, key=lambda x: len(x)) if self.bloom and self.bloom.valid() and len(self.bloom) >= len(self): self.do_bloom = True else: @@ -923,34 +924,52 @@ def read_ref(refname, repo_dir = None): return None -def rev_list(ref, count=None, repo_dir=None): - """Generate a list of reachable commits in reverse chronological order. +def rev_list_invocation(ref_or_refs, count=None, format=None): + if isinstance(ref_or_refs, compat.str_type): + refs = (ref_or_refs,) + else: + refs = ref_or_refs + argv = ['git', 'rev-list'] + if isinstance(count, Integral): + argv.extend(['-n', str(count)]) + elif count: + raise ValueError('unexpected count argument %r' % count) + + if format: + argv.append('--pretty=format:' + format) + for ref in refs: + assert not ref.startswith('-') + argv.append(ref) + argv.append('--') + return argv + - This generator walks through commits, from child to parent, that are - reachable via the specified ref and yields a series of tuples of the form - (date,hash). +def rev_list(ref_or_refs, count=None, parse=None, format=None, repo_dir=None): + """Yield information about commits as per "git rev-list". If a format + is not provided, yield one hex hash at a time. If a format is + provided, pass it to rev-list and call parse(git_stdout) for each + commit with the stream positioned just after the rev-list "commit + HASH" header line. When a format is provided yield (oidx, + parse(git_stdout)) for each commit. - If count is a non-zero integer, limit the number of commits to "count" - objects. """ - assert(not ref.startswith('-')) - opts = [] - if isinstance(count, Integral): - opts += ['-n', str(count)] - else: - assert not count - argv = ['git', 'rev-list', '--pretty=format:%at'] + opts + [ref, '--'] - p = subprocess.Popen(argv, + assert bool(parse) == bool(format) + p = subprocess.Popen(rev_list_invocation(ref_or_refs, count=count, + format=format), preexec_fn = _gitenv(repo_dir), stdout = subprocess.PIPE) - commit = None - for row in p.stdout: - s = row.strip() - if s.startswith('commit '): - commit = s[7:].decode('hex') - else: - date = int(s) - yield (date, commit) + if not format: + for line in p.stdout: + yield line.strip() + else: + line = p.stdout.readline() + while line: + s = line.strip() + if not s.startswith('commit '): + raise Exception('unexpected line ' + s) + yield s[7:], parse(p.stdout) + line = p.stdout.readline() + rv = p.wait() # not fatal if rv: raise GitError, 'git rev-list returned error %d' % rv