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):
24 self.repo_dir = realpath(repo_dir or git.repo())
25 self._cp = git.cp(self.repo_dir)
26 self.update_ref = partial(git.update_ref, repo_dir=self.repo_dir)
27 self.rev_list = partial(git.rev_list, repo_dir=self.repo_dir)
28 self._id = _repo_id(self.repo_dir)
36 def __exit__(self, type, value, traceback):
37 with pending_raise(value, rethrow=False):
41 """Return an identifier that differs from any other repository that
42 doesn't share the same repository-specific information
43 (e.g. refs, tags, etc.)."""
49 def new_packwriter(self, compression_level=1,
50 max_pack_size=None, max_pack_objects=None):
51 return git.PackWriter(repo_dir=self.repo_dir,
52 compression_level=compression_level,
53 max_pack_size=max_pack_size,
54 max_pack_objects=max_pack_objects)
57 """If ref does not exist, yield (None, None, None). Otherwise yield
58 (oidx, type, size), and then all of the data associated with
62 it = self._cp.get(ref)
63 oidx, typ, size = info = next(it)
68 assert not next(it, None)
71 return self._cp.join(ref)
73 def refs(self, patterns=None, limit_to_heads=False, limit_to_tags=False):
74 for ref in git.list_refs(patterns=patterns,
75 limit_to_heads=limit_to_heads,
76 limit_to_tags=limit_to_tags,
77 repo_dir=self.repo_dir):
80 ## Of course, the vfs better not call this...
81 def resolve(self, path, parent=None, want_meta=True, follow=True):
83 return vfs.resolve(self, path,
84 parent=parent, want_meta=want_meta, follow=follow)
88 def __init__(self, address):
89 self.address = address
90 self.client = client.Client(address)
91 self.new_packwriter = self.client.new_packwriter
92 self.update_ref = self.client.update_ref
93 self.rev_list = self.client.rev_list
94 self._id = _repo_id(self.address)
104 def __exit__(self, type, value, traceback):
105 with pending_raise(value, rethrow=False):
109 """Return an identifier that differs from any other repository that
110 doesn't share the same repository-specific information
111 (e.g. refs, tags, etc.)."""
118 """If ref does not exist, yield (None, None, None). Otherwise yield
119 (oidx, type, size), and then all of the data associated with
123 # Yield all the data here so that we don't finish the
124 # cat_batch iterator (triggering its cleanup) until all of the
125 # data has been read. Otherwise we'd be out of sync with the
127 items = self.client.cat_batch((ref,))
128 oidx, typ, size, it = info = next(items)
133 assert not next(items, None)
136 return self.client.join(ref)
138 def refs(self, patterns=None, limit_to_heads=False, limit_to_tags=False):
139 for ref in self.client.refs(patterns=patterns,
140 limit_to_heads=limit_to_heads,
141 limit_to_tags=limit_to_tags):
144 def resolve(self, path, parent=None, want_meta=True, follow=True):
145 ## FIXME: mode_only=?
146 return self.client.resolve(path, parent=parent, want_meta=want_meta,