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
13 global _next_repo_id, _repo_ids
14 repo_id = _repo_ids.get(key)
17 next_id = _next_repo_id = _next_repo_id + 1
18 _repo_ids[key] = next_id
22 def __init__(self, repo_dir=None):
23 self.repo_dir = realpath(repo_dir or git.repo())
24 self._cp = git.cp(self.repo_dir)
25 self.update_ref = partial(git.update_ref, repo_dir=self.repo_dir)
26 self.rev_list = partial(git.rev_list, repo_dir=self.repo_dir)
27 self._id = _repo_id(self.repo_dir)
38 def __exit__(self, type, value, traceback):
39 with pending_raise(value, rethrow=False):
43 """Return an identifier that differs from any other repository that
44 doesn't share the same repository-specific information
45 (e.g. refs, tags, etc.)."""
51 def new_packwriter(self, compression_level=1,
52 max_pack_size=None, max_pack_objects=None):
53 return git.PackWriter(repo_dir=self.repo_dir,
54 compression_level=compression_level,
55 max_pack_size=max_pack_size,
56 max_pack_objects=max_pack_objects)
59 """If ref does not exist, yield (None, None, None). Otherwise yield
60 (oidx, type, size), and then all of the data associated with
64 it = self._cp.get(ref)
65 oidx, typ, size = info = next(it)
70 assert not next(it, None)
73 return self._cp.join(ref)
75 def refs(self, patterns=None, limit_to_heads=False, limit_to_tags=False):
76 for ref in git.list_refs(patterns=patterns,
77 limit_to_heads=limit_to_heads,
78 limit_to_tags=limit_to_tags,
79 repo_dir=self.repo_dir):
82 ## Of course, the vfs better not call this...
83 def resolve(self, path, parent=None, want_meta=True, follow=True):
85 return vfs.resolve(self, path,
86 parent=parent, want_meta=want_meta, follow=follow)
90 def __init__(self, address):
91 self.address = address
92 self.client = client.Client(address)
93 self.new_packwriter = self.client.new_packwriter
94 self.update_ref = self.client.update_ref
95 self.rev_list = self.client.rev_list
96 self._id = _repo_id(self.address)
109 def __exit__(self, type, value, traceback):
110 with pending_raise(value, rethrow=False):
114 """Return an identifier that differs from any other repository that
115 doesn't share the same repository-specific information
116 (e.g. refs, tags, etc.)."""
123 """If ref does not exist, yield (None, None, None). Otherwise yield
124 (oidx, type, size), and then all of the data associated with
128 # Yield all the data here so that we don't finish the
129 # cat_batch iterator (triggering its cleanup) until all of the
130 # data has been read. Otherwise we'd be out of sync with the
132 items = self.client.cat_batch((ref,))
133 oidx, typ, size, it = info = next(items)
138 assert not next(items, None)
141 return self.client.join(ref)
143 def refs(self, patterns=None, limit_to_heads=False, limit_to_tags=False):
144 for ref in self.client.refs(patterns=patterns,
145 limit_to_heads=limit_to_heads,
146 limit_to_tags=limit_to_tags):
149 def resolve(self, path, parent=None, want_meta=True, follow=True):
150 ## FIXME: mode_only=?
151 return self.client.resolve(path, parent=parent, want_meta=want_meta,