1 # -*- encoding: utf-8 -*-
4 log = logging.getLogger('ral.mercurial')
6 __author__ = "Ćukasz Rekucki"
7 __date__ = "$2009-09-25 09:35:06$"
8 __doc__ = "Module documentation."
11 import mercurial.error
15 log = logging.getLogger('wlrepo.document')
17 class MercurialDocument(wlrepo.Document):
19 def data(self, entry):
20 path = self._library._sanitize_string(self.id + u'.' + entry)
22 return self._library._filectx(path, \
23 self._revision.hgrev()).data().decode('utf-8')
24 except mercurial.error.LookupError, e:
25 fl = [x.decode('utf-8') for x in self._revision._changectx]
26 raise wlrepo.EntryNotFound(self._revision, path.decode('utf-8'), fl)
28 def quickwrite(self, entry, data, msg, user=None):
29 user = user or self.owner
31 if isinstance(data, unicode):
32 data = data.encode('utf-8')
34 user = self._library._sanitize_string(user)
35 msg = self._library._sanitize_string(msg)
36 entry = self._library._sanitize_string(entry)
39 raise ValueError("Can't determine user.")
42 f = l._fileopen(r(entry), "w+")
47 return self.invoke_and_commit(write, lambda d: (msg, \
48 self._library._sanitize_string(self.owner)) )
50 def invoke_and_commit(self, ops, commit_info):
51 lock = self._library.lock()
53 self._library._checkout(self._revision.hgrev())
55 def entry_path(entry):
56 return self._library._sanitize_string(self.id + u'.' + entry)
58 ops(self._library, entry_path)
59 message, user = commit_info(self)
61 message = self._library._sanitize_string(message)
62 user = self._library._sanitize_string(user)
64 self._library._commit(message, user)
66 return self._library.document(docid=self.id, user=user)
68 # rollback the last commit
69 self._library._rollback()
74 # def commit(self, message, user):
75 # """Make a new commit."""
76 # self.invoke_and_commit(message, user, lambda *a: True)
79 return self._revision.user_name is None
82 return (self == self.latest())
88 return self._library.document(docid=self.id)
91 return self._library.document(docid=self.id, user=self.owner)
94 fullid = self._library.fulldocid(self.id, user)
96 def take_action(library, resolve):
98 library._set_branchname(fullid)
100 if not self._library.has_revision(fullid):
101 log.info("Checking out document %s" % fullid)
103 self.invoke_and_commit(take_action, \
104 lambda d: ("$AUTO$ File checkout.", user) )
106 return self._library.document_for_rev(fullid)
108 def up_to_date(self):
112 shared = self.shared()
114 if shared.ancestorof(self):
117 if shared.has_parent_from(self):
122 def update(self, user):
123 """Update parts of the document."""
124 lock = self.library.lock()
127 # main revision of the document
130 # check for children in this branch
131 if self._revision.has_children(limit_branch=True):
132 raise wlrepo.UpdateException("Revision %s has children." % self.revision)
134 shared = self.shared()
140 # we carry the latest version
141 if shared.ancestorof(self):
150 if self.parentof(shared):
158 # This is ok (s - shared, S - self)
160 if self._revision.merge_with(shared._revision, user=user,\
161 message="$AUTO$ Personal branch update."):
164 raise wlrepo.UpdateException("Merge failed.")
169 def would_share(self):
173 shared = self.shared()
175 # we just did this - move on
176 if self.parentof(shared):
185 # Situation above is ok - what we don't want, is:
192 # We want to prevent stuff like this.
193 if self.parent().parentof(shared):
196 def share(self, message):
197 lock = self.library.lock()
200 if not self.would_share():
212 if shared.ancestorof(self):
213 success = shared._revision.merge_with(self._revision, user=self.owner, message=message)
216 raise wlrepo.LibraryException("Merge failed.")
218 return shared.latest()
220 raise wlrepo.LibraryException("Unrecognized share-state.")
225 def has_conflict_marks(self):
226 return re.search("^(?:<<<<<<< .*|=======|>>>>>>> .*)$", self.data('xml'), re.MULTILINE)
228 def __unicode__(self):
229 return u"Document(%s:%s)" % (self.id, self.owner)
232 return self.__unicode__().encode('utf-8')
234 def __eq__(self, other):
235 return (self._revision == other._revision)