# # # patch "setup.py" # from [e7a29a586a2957f991598466701a6dd698593c27] # to [ef7120cb5380665df5f61b47f1c1878b1c21252d] # # patch "tracmtn/backend.py" # from [7f2e7ecbe83151dd5bfa660f09311d0a361102ae] # to [64899332a0a2b585784c36c0c24787b1bec1705f] # ============================================================ --- setup.py e7a29a586a2957f991598466701a6dd698593c27 +++ setup.py ef7120cb5380665df5f61b47f1c1878b1c21252d @@ -29,7 +29,7 @@ setup( setup( name = 'TracMonotone', keywords = 'trac monotone scm plugin mtn', - version = '0.0.12', + version = '0.0.13', author = 'Thomas Moschny', author_email = 'address@hidden', packages = ['tracmtn'], ============================================================ --- tracmtn/backend.py 7f2e7ecbe83151dd5bfa660f09311d0a361102ae +++ tracmtn/backend.py 64899332a0a2b585784c36c0c24787b1bec1705f @@ -60,6 +60,14 @@ INTERFACE_VERSIONS = { '6.0': '0.37-0.38', } + +class MultipleChangesets(TracError): + def __init__(self, rev): + TracError.__init__( + self, "Multiple revisions found for '%s'" % rev, + title="Ambiguous changeset Number") + + class MonotoneConnector(Component): """ Provides this plugin's functionality. @@ -289,6 +297,12 @@ class MonotoneRepository(Repository): revision 'rev'. """ rev = self.normalize_rev(rev) + return self._get_changeset(rev) + + def _get_changeset(self, rev): + """ + Like get_changeset, but skips the revision normalization. + """ try: return MonotoneChangeset(self.mtn, rev, self.revpropspec) except AutomateException: @@ -300,7 +314,7 @@ class MonotoneRepository(Repository): """ for rev in self.mtn.select('l:%s/e:%s' % (format_datetime(start), format_datetime(stop))): - yield self.get_changeset(rev) + yield self._get_changeset(rev) def get_node(self, path, rev=None): """ @@ -314,7 +328,7 @@ class MonotoneRepository(Repository): # version of a path. # FIXME: normalize_rev can be skipped when called by ourselves - rev = self.normalize_rev(rev) or self.get_youngest_rev() + rev = self.normalize_rev(rev) path = self.normalize_path(path) try: return MonotoneNode(self.mtn, rev, path) @@ -402,23 +416,30 @@ class MonotoneRepository(Repository): return '/' + (path and path.strip('/') or '') def normalize_rev(self, rev): + """Return a canonical representation of a revision. + + It's up to the backend to decide which string values of `rev` + (usually provided by the user) should be accepted, and how + they should be normalized. Some backends may for instance want + to match against known tags or branch names. + + In addition, if `rev` is `None` or '', the youngest revision + should be returned. """ - Return a canonical representation of a revision in the repos. - 'None' is a valid revision value and represents the youngest - revision. It should simply be passed through. - """ - if rev != None: - if REVID_RULE.match(rev): - # already a single revision id, not passed to select - pass - else: - revs = self.mtn.select(rev) - if len(revs) != 1: - raise NoSuchChangeset(rev) - rev = revs[0] - rev = rev.encode('ascii') - return rev + if rev is None or isinstance(rev, basestring) and \ + rev.lower() in ('', 'none', 'latest', 'youngest'): + return self.youngest_rev + if not REVID_RULE.match(rev): + # doesn't look like a hash, pass to mtn's select + revs = self.mtn.select(rev) + if len(revs) < 1: + raise NoSuchChangeset(rev) + elif len(revs) > 1: + raise MultipleChangesets(rev) + rev = revs[0] + return rev.encode('ascii') + def short_rev(self, rev): """ Return a compact representation of a revision in the repos.