2 from __future__ import absolute_import
3 from os.path import realpath
4 from functools import partial
6 from bup import client, git, vfs
7 from bup.compat import pending_raise
14 global _next_repo_id, _repo_ids
15 repo_id = _repo_ids.get(key)
18 next_id = _next_repo_id = _next_repo_id + 1
19 _repo_ids[key] = next_id
23 def __init__(self, repo_dir=None):
25 self.repo_dir = realpath(repo_dir or git.repo())
26 self._cp = git.cp(self.repo_dir)
27 self.update_ref = partial(git.update_ref, repo_dir=self.repo_dir)
28 self.rev_list = partial(git.rev_list, repo_dir=self.repo_dir)
29 self._id = _repo_id(self.repo_dir)
40 def __exit__(self, type, value, traceback):
41 with pending_raise(value, rethrow=False):
45 """Return an identifier that differs from any other repository that
46 doesn't share the same repository-specific information
47 (e.g. refs, tags, etc.)."""
53 def new_packwriter(self, compression_level=1,
54 max_pack_size=None, max_pack_objects=None):
55 return git.PackWriter(repo_dir=self.repo_dir,
56 compression_level=compression_level,
57 max_pack_size=max_pack_size,
58 max_pack_objects=max_pack_objects)
61 """If ref does not exist, yield (None, None, None). Otherwise yield
62 (oidx, type, size), and then all of the data associated with
66 it = self._cp.get(ref)
67 oidx, typ, size = info = next(it)
72 assert not next(it, None)
75 return self._cp.join(ref)
77 def refs(self, patterns=None, limit_to_heads=False, limit_to_tags=False):
78 for ref in git.list_refs(patterns=patterns,
79 limit_to_heads=limit_to_heads,
80 limit_to_tags=limit_to_tags,
81 repo_dir=self.repo_dir):
84 ## Of course, the vfs better not call this...
85 def resolve(self, path, parent=None, want_meta=True, follow=True):
87 return vfs.resolve(self, path,
88 parent=parent, want_meta=want_meta, follow=follow)
92 def __init__(self, address):
94 self.address = address
95 self.client = client.Client(address)
96 self.new_packwriter = self.client.new_packwriter
97 self.update_ref = self.client.update_ref
98 self.rev_list = self.client.rev_list
99 self._id = _repo_id(self.address)
113 def __exit__(self, type, value, traceback):
114 with pending_raise(value, rethrow=False):
118 """Return an identifier that differs from any other repository that
119 doesn't share the same repository-specific information
120 (e.g. refs, tags, etc.)."""
127 """If ref does not exist, yield (None, None, None). Otherwise yield
128 (oidx, type, size), and then all of the data associated with
132 # Yield all the data here so that we don't finish the
133 # cat_batch iterator (triggering its cleanup) until all of the
134 # data has been read. Otherwise we'd be out of sync with the
136 items = self.client.cat_batch((ref,))
137 oidx, typ, size, it = info = next(items)
142 assert not next(items, None)
145 return self.client.join(ref)
147 def refs(self, patterns=None, limit_to_heads=False, limit_to_tags=False):
148 for ref in self.client.refs(patterns=patterns,
149 limit_to_heads=limit_to_heads,
150 limit_to_tags=limit_to_tags):
153 def resolve(self, path, parent=None, want_meta=True, follow=True):
154 ## FIXME: mode_only=?
155 return self.client.resolve(path, parent=parent, want_meta=want_meta,