Exemplo n.º 1
0
 def _as_revision_id(self, context_branch):
     path, numstring = self.spec.rsplit(':', 1)
     try:
         index = int(numstring) - 1
     except ValueError:
         self._raise_invalid(numstring, context_branch)
     tree, file_path = workingtree.WorkingTree.open_containing(path)
     tree.lock_read()
     try:
         file_id = tree.path2id(file_path)
         if file_id is None:
             raise errors.InvalidRevisionSpec(
                 self.user_spec, context_branch,
                 "File '%s' is not versioned." % file_path)
         revision_ids = [r for (r, l) in tree.annotate_iter(file_id)]
     finally:
         tree.unlock()
     try:
         revision_id = revision_ids[index]
     except IndexError:
         self._raise_invalid(numstring, context_branch)
     if revision_id == revision.CURRENT_REVISION:
         raise errors.InvalidRevisionSpec(
             self.user_spec, context_branch,
             'Line %s has not been committed.' % numstring)
     return revision_id
Exemplo n.º 2
0
    def _lookup(self, branch):
        loc = self.spec.find(':')
        if loc == -1:
            revno_spec = self.spec
            branch_spec = None
        else:
            revno_spec = self.spec[:loc]
            branch_spec = self.spec[loc + 1:]

        if revno_spec == '':
            if not branch_spec:
                raise errors.InvalidRevisionSpec(
                    self.user_spec, branch,
                    'cannot have an empty revno and no branch')
            revno = None
        else:
            try:
                revno = int(revno_spec)
                dotted = False
            except ValueError:
                # dotted decimal. This arguably should not be here
                # but the from_string method is a little primitive
                # right now - RBC 20060928
                try:
                    match_revno = tuple(
                        (int(number) for number in revno_spec.split('.')))
                except ValueError, e:
                    raise errors.InvalidRevisionSpec(self.user_spec, branch, e)

                dotted = True
Exemplo n.º 3
0
 def _match_on(self, branch, revs):
     r = RevisionSpec.from_string(self.spec)._match_on(branch, revs)
     if r.revno == 0:
         raise errors.InvalidRevisionSpec(self.user_spec, branch,
                                      'cannot go before the null: revision')
     if r.revno is None:
         # We need to use the repository history here
         rev = branch.repository.get_revision(r.rev_id)
         if not rev.parent_ids:
             revno = 0
             revision_id = revision.NULL_REVISION
         else:
             revision_id = rev.parent_ids[0]
             try:
                 revno = revs.index(revision_id) + 1
             except ValueError:
                 revno = None
     else:
         revno = r.revno - 1
         try:
             revision_id = branch.get_rev_id(revno, revs)
         except errors.NoSuchRevision:
             raise errors.InvalidRevisionSpec(self.user_spec,
                                              branch)
     return RevisionInfo(branch, revno, revision_id)
Exemplo n.º 4
0
    def _match_on(self, branch, revs):
        """Spec for date revisions:
          date:value
          value can be 'yesterday', 'today', 'tomorrow' or a YYYY-MM-DD string.
          matches the first entry after a given date (either at midnight or
          at a specified time).
        """
        #  XXX: This doesn't actually work
        #  So the proper way of saying 'give me all entries for today' is:
        #      -r date:yesterday..date:today
        today = datetime.datetime.fromordinal(datetime.date.today().toordinal())
        if self.spec.lower() == 'yesterday':
            dt = today - datetime.timedelta(days=1)
        elif self.spec.lower() == 'today':
            dt = today
        elif self.spec.lower() == 'tomorrow':
            dt = today + datetime.timedelta(days=1)
        else:
            m = self._date_re.match(self.spec)
            if not m or (not m.group('date') and not m.group('time')):
                raise errors.InvalidRevisionSpec(self.user_spec,
                                                 branch, 'invalid date')

            try:
                if m.group('date'):
                    year = int(m.group('year'))
                    month = int(m.group('month'))
                    day = int(m.group('day'))
                else:
                    year = today.year
                    month = today.month
                    day = today.day

                if m.group('time'):
                    hour = int(m.group('hour'))
                    minute = int(m.group('minute'))
                    if m.group('second'):
                        second = int(m.group('second'))
                    else:
                        second = 0
                else:
                    hour, minute, second = 0,0,0
            except ValueError:
                raise errors.InvalidRevisionSpec(self.user_spec,
                                                 branch, 'invalid date')

            dt = datetime.datetime(year=year, month=month, day=day,
                    hour=hour, minute=minute, second=second)
        branch.lock_read()
        try:
            rev = bisect.bisect(_RevListToTimestamps(revs, branch), dt)
        finally:
            branch.unlock()
        if rev == len(revs):
            raise errors.InvalidRevisionSpec(self.user_spec, branch)
        else:
            return RevisionInfo(branch, rev + 1)
Exemplo n.º 5
0
 def _match_on_and_check(self, branch, revs):
     info = self._match_on(branch, revs)
     if info:
         return info
     elif info == (None, None):
         # special case - nothing supplied
         return info
     elif self.prefix:
         raise errors.InvalidRevisionSpec(self.user_spec, branch)
     else:
         raise errors.InvalidRevisionSpec(self.spec, branch)
Exemplo n.º 6
0
    def _match_on(self, branch, revs):
        """Run the lookup and see what we can get."""

        # First, see if it's a revno
        if self._revno_regex.match(self.spec) is not None:
            try:
                return self._try_spectype(RevisionSpec_revno, branch)
            except RevisionSpec_revno.dwim_catchable_exceptions:
                pass

        # Next see what has been registered
        for objgetter in self._possible_revspecs:
            rs_class = objgetter.get_obj()
            try:
                return self._try_spectype(rs_class, branch)
            except rs_class.dwim_catchable_exceptions:
                pass

        # Try the old (deprecated) dwim list:
        for rs_class in dwim_revspecs:
            try:
                return self._try_spectype(rs_class, branch)
            except rs_class.dwim_catchable_exceptions:
                pass

        # Well, I dunno what it is. Note that we don't try to keep track of the
        # first of last exception raised during the DWIM tries as none seems
        # really relevant.
        raise errors.InvalidRevisionSpec(self.spec, branch)
Exemplo n.º 7
0
class RevisionSpec_last(RevisionSpec):
    """Selects the nth revision from the end."""

    help_txt = """Selects the nth revision from the end.

    Supply a positive number to get the nth revision from the end.
    This is the same as supplying negative numbers to the 'revno:' spec.
    Examples::

      last:1        -> return the last revision
      last:3        -> return the revision 2 before the end.
    """

    prefix = 'last:'

    def _match_on(self, branch, revs):
        revno, revision_id = self._revno_and_revision_id(branch)
        return RevisionInfo(branch, revno, revision_id)

    def _revno_and_revision_id(self, context_branch):
        last_revno, last_revision_id = context_branch.last_revision_info()

        if self.spec == '':
            if not last_revno:
                raise errors.NoCommits(context_branch)
            return last_revno, last_revision_id

        try:
            offset = int(self.spec)
        except ValueError, e:
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch, e)

        if offset <= 0:
            raise errors.InvalidRevisionSpec(
                self.user_spec, context_branch,
                'you must supply a positive value')

        revno = last_revno - offset + 1
        try:
            revision_id = context_branch.get_rev_id(revno)
        except errors.NoSuchRevision:
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch)
        return revno, revision_id
Exemplo n.º 8
0
    def _revno_and_revision_id(self, context_branch):
        last_revno, last_revision_id = context_branch.last_revision_info()

        if self.spec == '':
            if not last_revno:
                raise errors.NoCommits(context_branch)
            return last_revno, last_revision_id

        try:
            offset = int(self.spec)
        except ValueError, e:
            raise errors.InvalidRevisionSpec(self.user_spec, context_branch, e)
Exemplo n.º 9
0
 def _as_revision_id(self, context_branch):
     base_revspec = RevisionSpec.from_string(self.spec)
     base_revision_id = base_revspec.as_revision_id(context_branch)
     if base_revision_id == revision.NULL_REVISION:
         raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
                                      'cannot go before the null: revision')
     context_repo = context_branch.repository
     context_repo.lock_read()
     try:
         parent_map = context_repo.get_parent_map([base_revision_id])
     finally:
         context_repo.unlock()
     if base_revision_id not in parent_map:
         # Ghost, or unknown revision id
         raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
             'cannot find the matching revision')
     parents = parent_map[base_revision_id]
     if len(parents) < 1:
         raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
             'No parents for revision.')
     return parents[0]
Exemplo n.º 10
0
 def _as_revision_id(self, context_branch):
     revspec = RevisionSpec.from_string(self.spec)
     if revspec.get_branch() is None:
         spec_branch = context_branch
     else:
         spec_branch = _mod_branch.Branch.open(revspec.get_branch())
     revision_id = revspec.as_revision_id(spec_branch)
     graph = context_branch.repository.get_graph()
     result = graph.find_lefthand_merger(revision_id,
                                         context_branch.last_revision())
     if result is None:
         raise errors.InvalidRevisionSpec(self.user_spec, context_branch)
     return result
Exemplo n.º 11
0
 def _raise_invalid(self, numstring, context_branch):
     raise errors.InvalidRevisionSpec(self.user_spec, context_branch,
                                      'No such line: %s' % numstring)
Exemplo n.º 12
0
class RevisionSpec_revno(RevisionSpec):
    """Selects a revision using a number."""

    help_txt = """Selects a revision using a number.

    Use an integer to specify a revision in the history of the branch.
    Optionally a branch can be specified.  A negative number will count
    from the end of the branch (-1 is the last revision, -2 the previous
    one). If the negative number is larger than the branch's history, the
    first revision is returned.
    Examples::

      revno:1                   -> return the first revision of this branch
      revno:3:/path/to/branch   -> return the 3rd revision of
                                   the branch '/path/to/branch'
      revno:-1                  -> The last revision in a branch.
      -2:http://other/branch    -> The second to last revision in the
                                   remote branch.
      -1000000                  -> Most likely the first revision, unless
                                   your history is very long.
    """
    prefix = 'revno:'

    def _match_on(self, branch, revs):
        """Lookup a revision by revision number"""
        branch, revno, revision_id = self._lookup(branch)
        return RevisionInfo(branch, revno, revision_id)

    def _lookup(self, branch):
        loc = self.spec.find(':')
        if loc == -1:
            revno_spec = self.spec
            branch_spec = None
        else:
            revno_spec = self.spec[:loc]
            branch_spec = self.spec[loc + 1:]

        if revno_spec == '':
            if not branch_spec:
                raise errors.InvalidRevisionSpec(
                    self.user_spec, branch,
                    'cannot have an empty revno and no branch')
            revno = None
        else:
            try:
                revno = int(revno_spec)
                dotted = False
            except ValueError:
                # dotted decimal. This arguably should not be here
                # but the from_string method is a little primitive
                # right now - RBC 20060928
                try:
                    match_revno = tuple(
                        (int(number) for number in revno_spec.split('.')))
                except ValueError, e:
                    raise errors.InvalidRevisionSpec(self.user_spec, branch, e)

                dotted = True

        if branch_spec:
            # the user has overriden the branch to look in.
            branch = _mod_branch.Branch.open(branch_spec)

        if dotted:
            try:
                revision_id = branch.dotted_revno_to_revision_id(
                    match_revno, _cache_reverse=True)
            except errors.NoSuchRevision:
                raise errors.InvalidRevisionSpec(self.user_spec, branch)
            else:
                # there is no traditional 'revno' for dotted-decimal revnos.
                # so for API compatibility we return None.
                return branch, None, revision_id
        else:
            last_revno, last_revision_id = branch.last_revision_info()
            if revno < 0:
                # if get_rev_id supported negative revnos, there would not be a
                # need for this special case.
                if (-revno) >= last_revno:
                    revno = 1
                else:
                    revno = last_revno + revno + 1
            try:
                revision_id = branch.get_rev_id(revno)
            except errors.NoSuchRevision:
                raise errors.InvalidRevisionSpec(self.user_spec, branch)
        return branch, revno, revision_id
 def _match_on(self, branch, revs):
     if self.spec == "bork":
         return RevisionInfo.from_revision_id(branch, "r1")
     else:
         raise errors.InvalidRevisionSpec(self.spec, branch)