1 # -*- coding: utf-8 -*-
4 from mercurial import localrepo, ui, match, node, encoding, util
5 import mercurial.merge, mercurial.error
7 encoding.encoding = 'utf-8'
10 class RepositoryDoesNotExist(Exception):
13 class Repository(object):
14 """Abstrakcja repozytorium Mercurial. DziaĆa z Mercurial w wersji 1.3.1."""
16 def __init__(self, path, create=False):
18 self.ui.config('ui', 'quiet', 'true')
19 self.ui.config('ui', 'interactive', 'false')
21 self.real_path = os.path.realpath(path)
22 self.repo = self.open_repository(self.real_path, create)
23 self._pending_files = []
25 def open_repository(self, path, create=False):
26 if os.path.isdir(path):
28 return localrepo.localrepository(self.ui, path)
29 except mercurial.error.RepoError:
30 # dir is not an hg repo, we must init it
32 return localrepo.localrepository(self.ui, path, create=1)
35 return localrepo.localrepository(self.ui, path, create=1)
36 raise RepositoryDoesNotExist("Repository %s does not exist." % path)
38 def all_files(self, branch='default'):
39 return self.in_branch(lambda: self._all_files(), branch)
42 return list(self.repo[None])
44 def get_file(self, path, branch='default'):
45 return self.in_branch(lambda: self._get_file(path), branch)
47 def _get_file(self, path):
48 return self.repo.wread(path)
50 def add_file(self, path, value, branch='default'):
51 return self.in_branch(lambda: self._add_file(path, value), branch)
53 def _add_file(self, path, value):
54 return self.repo.wwrite(path, value.encode('utf-8'), [])
55 # f = codecs.open(os.path.join(self.real_path, path), 'w', encoding='utf-8')
58 # if path not in self._pending_files:
59 # self._pending_files.append(path)
61 def _commit(self, message, user=None, key=None):
62 return self.repo.commit(text=message, user=user)
64 def _commit2(self, message, key=None, user=None):
66 Commit unsynchronized data to disk.
69 - message: mercurial's changeset message
70 - key: supply to sync only one key
72 if isinstance(message, unicode):
73 message = message.encode('utf-8')
74 if isinstance(user, unicode):
75 user = user.encode('utf-8')
83 # first of all, add absent data and clean removed
85 # will commit all keys
86 pending_files = self._pending_files
88 if keys not in self._pending_files:
93 for path in pending_files:
94 files_to_commit.append(path)
95 if path in self.all_files():
96 if not os.path.exists(os.path.join(self.real_path, path)):
98 files_to_remove.append(path)
101 files_to_add.append(path)
104 self.repo.add(files_to_add)
107 self.repo.forget(files_to_remove)
110 for i, f in enumerate(files_to_commit):
111 if isinstance(f, unicode):
112 files_to_commit[i] = f.encode('utf-8')
113 matcher = match.match(self.repo.root, self.repo.root, files_to_commit, default='path')
114 rev = self.repo.commit(message, user=user, match=matcher)
117 for key in pending_files:
118 self._pending_files.remove(key)
121 # self._keys = self.get_persisted_objects_keys()
122 # return node.hex(rev)
124 def commit(self, message, key=None, user=None, branch='default'):
125 return self.in_branch(lambda: self._commit(message, key=key, user=user), branch)
127 def in_branch(self, action, bname='default'):
128 wlock = self.repo.wlock()
130 old = self._switch_to_branch(bname)
135 self._switch_to_branch(old)
139 def _switch_to_branch(self, bname):
140 wlock = self.repo.wlock()
142 current = self.repo[None].branch()
146 tip = self.repo.branchtags()[bname]
147 upstats = mercurial.merge.update(self.repo, tip, False, True, None)
150 raise RepositoryException("Can't switch to branch '%s': no such branch." % bname , ke)
151 except util.Abort, ae:
152 raise repositoryException("Can't switch to branch '%s': %s" % (bname, ae.message), ae)
156 def write_lock(self):
157 """Returns w write lock to the repository."""
158 return self.repo.wlock()
161 class RepositoryException(Exception):
163 def __init__(self, msg, cause=None):
164 Exception.__init__(self, msg)