X-Git-Url: https://git.mdrn.pl/redakcja.git/blobdiff_plain/3546a2b2d5f52224bcf95803030611ab505f29cd..bd2f4130a81e68a2bb3c8d88448540ec60fe7be5:/lib/wlrepo/mercurial_backend/document.py diff --git a/lib/wlrepo/mercurial_backend/document.py b/lib/wlrepo/mercurial_backend/document.py index 3f94097a..f7da32d2 100644 --- a/lib/wlrepo/mercurial_backend/document.py +++ b/lib/wlrepo/mercurial_backend/document.py @@ -1,11 +1,18 @@ # -*- encoding: utf-8 -*- +import logging +log = logging.getLogger('ral.mercurial') + __author__ = "Łukasz Rekucki" __date__ = "$2009-09-25 09:35:06$" __doc__ = "Module documentation." import wlrepo import mercurial.error +import re + +import logging +log = logging.getLogger('wlrepo.document') class MercurialDocument(wlrepo.Document): @@ -50,6 +57,10 @@ class MercurialDocument(wlrepo.Document): ops(self._library, entry_path) message, user = commit_info(self) + + message = self._library._sanitize_string(message) + user = self._library._sanitize_string(user) + self._library._commit(message, user) try: return self._library.document(docid=self.id, user=user) @@ -67,6 +78,9 @@ class MercurialDocument(wlrepo.Document): def ismain(self): return self._revision.user_name is None + def islatest(self): + return (self == self.latest()) + def shared(self): if self.ismain(): return self @@ -81,120 +95,113 @@ class MercurialDocument(wlrepo.Document): def take_action(library, resolve): # branch from latest - library._create_branch(fullid, parent=self._revision) + library._set_branchname(fullid) if not self._library.has_revision(fullid): + log.info("Checking out document %s" % fullid) + self.invoke_and_commit(take_action, \ lambda d: ("$AUTO$ File checkout.", user) ) return self._library.document_for_rev(fullid) - + + def up_to_date(self): + if self.ismain(): + return True + + shared = self.shared() + + if shared.parentof(self): + return True + + if shared.has_parent_from(self): + return True + + return False + def update(self, user): """Update parts of the document.""" lock = self.library.lock() try: if self.ismain(): # main revision of the document - return (True, False) - - if self._revision.has_children(): - # can't update non-latest revision - return (False, False) + return self - sv = self.shared() - - if not sv.ancestorof(self) and not self.parentof(sv): - return self._revision.merge_with(sv._revision, user=user) + # check for children in this branch + if self._revision.has_children(limit_branch=True): + raise wlrepo.UpdateException("Revision %s has children." % self.revision) + + shared = self.shared() + + # the shared version comes from our version + if self.parentof(self.shared()): + return self + + # no changes since last update + if shared.ancestorof(self): + return self - return (False, False) + # last share was from this branch + if shared.has_parent_from(self): + return self + + if self._revision.merge_with(sv._revision, user=user,\ + message="$AUTO$ Personal branch update."): + return self.latest() + else: + raise wlrepo.UpdateException("Merge failed.") finally: lock.release() def share(self, message): lock = self.library.lock() try: + + # nothing to do if self.ismain(): - return (True, False) # always shared + return self + + shared = self.shared() + + # we just did this - move on + if self.parentof(shared): + return shared - user = self._revision.user_name - main = self.shared()._revision - local = self._revision + # No changes since update + if shared.parentof(self): + return shared - # Case 1: + # The good situation + # # * local # | - # * <- can also be here! - # /| + # >* + # || # / | # main * * # | | - # The local branch has been recently updated, - # so we don't need to update yet again, but we need to - # merge down to default branch, even if there was - # no commit's since last update - - if main.ancestorof(local): - print "case 1" - success, changed = main.merge_with(local, user=user, message=message) - # Case 2: - # - # main * * local - # |\ | - # | \| - # | * - # | | - # - # Default has no changes, to update from this branch - # since the last merge of local to default. - elif local.has_common_ancestor(main): - print "case 2" - if not local.parentof(main): - success, changed = main.merge_with(local, user=user, message=message) - - # Case 3: - # main * - # | - # * <- this case overlaps with previos one - # |\ - # | \ - # | * local - # | | - # - # There was a recent merge to the defaul branch and - # no changes to local branch recently. - # - # Use the fact, that user is prepared to see changes, to - # update his branch if there are any - elif local.ancestorof(main): - print "case 3" - if not local.parentof(main): - success, changed = local.merge_with(main, user=user, \ - message='$AUTO$ Local branch update during share.') - - else: - print "case 4" - success, changed = local.merge_with(main, user=user, \ - message='$AUTO$ Local branch update during share.') + if shared.ancestorof(self): + success = shared._revision.merge_with(self._revision, user=self.owner, message=message) if not success: - return False + raise wlrepo.LibraryException("Merge failed.") + + return shared.latest() - if changed: - local = local.latest() - - success, changed = main.merge_with(local, user=user,\ - message=message) - - return success, changed + raise wlrepo.LibraryException("Unrecognized share-state.") finally: - lock.release() + lock.release() + + + def has_conflict_marks(self): + return re.search("^(?:<<<<<<< .*|=======|>>>>>>> .*)$", self.data('xml'), re.MULTILINE) def __unicode__(self): - return u"Document(%s:%s)" % (self.name, self.owner) + return u"Document(%s:%s)" % (self.id, self.owner) def __str__(self): return self.__unicode__().encode('utf-8') def __eq__(self, other): - return (self._revision == other._revision) and (self.name == other.name) + return (self._revision == other._revision)