bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 1 | # Copyright (C) 2005 Canonical Ltd
 | 
| 1887.1.1
by Adeodato Simó Do not separate paragraphs in the copyright statement with blank lines, | 2 | #
 | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 3 | # This program is free software; you can redistribute it and/or modify
 | 
| 4 | # it under the terms of the GNU General Public License as published by
 | |
| 5 | # the Free Software Foundation; either version 2 of the License, or
 | |
| 6 | # (at your option) any later version.
 | |
| 1887.1.1
by Adeodato Simó Do not separate paragraphs in the copyright statement with blank lines, | 7 | #
 | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 8 | # This program is distributed in the hope that it will be useful,
 | 
| 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| 11 | # GNU General Public License for more details.
 | |
| 1887.1.1
by Adeodato Simó Do not separate paragraphs in the copyright statement with blank lines, | 12 | #
 | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 13 | # You should have received a copy of the GNU General Public License
 | 
| 14 | # along with this program; if not, write to the Free Software
 | |
| 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
| 16 | ||
| 17 | ||
| 1948.4.1
by John Arbash Meinel Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers | 18 | import bisect | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 19 | import datetime | 
| 20 | import re | |
| 1948.4.1
by John Arbash Meinel Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers | 21 | |
| 22 | from bzrlib import ( | |
| 23 | errors, | |
| 1948.4.18
by John Arbash Meinel Update branch: spec and tests | 24 | revision, | 
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 25 | symbol_versioning, | 
| 26 | trace, | |
| 1948.4.1
by John Arbash Meinel Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers | 27 |     )
 | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 28 | |
| 1948.4.16
by John Arbash Meinel Move the tests into the associated tester, remove redundant tests, some small PEP8 changes | 29 | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 30 | _marker = [] | 
| 31 | ||
| 1948.4.16
by John Arbash Meinel Move the tests into the associated tester, remove redundant tests, some small PEP8 changes | 32 | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 33 | class RevisionInfo(object): | 
| 34 | """The results of applying a revision specification to a branch. | |
| 35 | ||
| 36 |     An instance has two useful attributes: revno, and rev_id.
 | |
| 37 | ||
| 38 |     They can also be accessed as spec[0] and spec[1] respectively,
 | |
| 39 |     so that you can write code like:
 | |
| 40 |     revno, rev_id = RevisionSpec(branch, spec)
 | |
| 41 |     although this is probably going to be deprecated later.
 | |
| 42 | ||
| 43 |     This class exists mostly to be the return value of a RevisionSpec,
 | |
| 44 |     so that you can access the member you're interested in (number or id)
 | |
| 45 |     or treat the result as a tuple.
 | |
| 46 |     """
 | |
| 47 | ||
| 48 | def __init__(self, branch, revno, rev_id=_marker): | |
| 49 | self.branch = branch | |
| 50 | self.revno = revno | |
| 51 | if rev_id is _marker: | |
| 52 |             # allow caller to be lazy
 | |
| 53 | if self.revno is None: | |
| 54 | self.rev_id = None | |
| 55 | else: | |
| 56 | self.rev_id = branch.get_rev_id(self.revno) | |
| 57 | else: | |
| 58 | self.rev_id = rev_id | |
| 59 | ||
| 60 | def __nonzero__(self): | |
| 61 |         # first the easy ones...
 | |
| 62 | if self.rev_id is None: | |
| 63 | return False | |
| 64 | if self.revno is not None: | |
| 65 | return True | |
| 66 |         # TODO: otherwise, it should depend on how I was built -
 | |
| 67 |         # if it's in_history(branch), then check revision_history(),
 | |
| 68 |         # if it's in_store(branch), do the check below
 | |
| 1185.67.2
by Aaron Bentley Renamed Branch.storage to Branch.repository | 69 | return self.branch.repository.has_revision(self.rev_id) | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 70 | |
| 71 | def __len__(self): | |
| 72 | return 2 | |
| 73 | ||
| 74 | def __getitem__(self, index): | |
| 75 | if index == 0: return self.revno | |
| 76 | if index == 1: return self.rev_id | |
| 77 | raise IndexError(index) | |
| 78 | ||
| 79 | def get(self): | |
| 1185.67.2
by Aaron Bentley Renamed Branch.storage to Branch.repository | 80 | return self.branch.repository.get_revision(self.rev_id) | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 81 | |
| 82 | def __eq__(self, other): | |
| 83 | if type(other) not in (tuple, list, type(self)): | |
| 84 | return False | |
| 85 | if type(other) is type(self) and self.branch is not other.branch: | |
| 86 | return False | |
| 87 | return tuple(self) == tuple(other) | |
| 88 | ||
| 89 | def __repr__(self): | |
| 90 | return '<bzrlib.revisionspec.RevisionInfo object %s, %s for %r>' % ( | |
| 91 | self.revno, self.rev_id, self.branch) | |
| 92 | ||
| 1948.4.16
by John Arbash Meinel Move the tests into the associated tester, remove redundant tests, some small PEP8 changes | 93 | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 94 | # classes in this list should have a "prefix" attribute, against which
 | 
| 95 | # string specs are matched
 | |
| 96 | SPEC_TYPES = [] | |
| 1948.4.35
by John Arbash Meinel Move the _revno_regex to a more logical location | 97 | _revno_regex = None | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 98 | |
| 1948.4.16
by John Arbash Meinel Move the tests into the associated tester, remove redundant tests, some small PEP8 changes | 99 | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 100 | class RevisionSpec(object): | 
| 101 | """A parsed revision specification. | |
| 102 | ||
| 103 |     A revision specification can be an integer, in which case it is
 | |
| 104 |     assumed to be a revno (though this will translate negative values
 | |
| 105 |     into positive ones); or it can be a string, in which case it is
 | |
| 106 |     parsed for something like 'date:' or 'revid:' etc.
 | |
| 107 | ||
| 108 |     Revision specs are an UI element, and they have been moved out
 | |
| 109 |     of the branch class to leave "back-end" classes unaware of such
 | |
| 110 |     details.  Code that gets a revno or rev_id from other code should
 | |
| 111 |     not be using revision specs - revnos and revision ids are the
 | |
| 112 |     accepted ways to refer to revisions internally.
 | |
| 113 | ||
| 114 |     (Equivalent to the old Branch method get_revision_info())
 | |
| 115 |     """
 | |
| 116 | ||
| 117 | prefix = None | |
| 118 | ||
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 119 | def __new__(cls, spec, _internal=False): | 
| 120 | if _internal: | |
| 121 | return object.__new__(cls, spec, _internal=_internal) | |
| 122 | ||
| 123 | symbol_versioning.warn('Creating a RevisionSpec directly has' | |
| 124 |                                ' been deprecated in version 0.11. Use'
 | |
| 1948.4.33
by John Arbash Meinel Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin) | 125 |                                ' RevisionSpec.from_string()'
 | 
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 126 | ' instead.', | 
| 127 | DeprecationWarning, stacklevel=2) | |
| 1948.4.33
by John Arbash Meinel Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin) | 128 | return RevisionSpec.from_string(spec) | 
| 129 | ||
| 130 |     @staticmethod
 | |
| 131 | def from_string(spec): | |
| 132 | """Parse a revision spec string into a RevisionSpec object. | |
| 133 | ||
| 134 |         :param spec: A string specified by the user
 | |
| 135 |         :return: A RevisionSpec object that understands how to parse the
 | |
| 136 |             supplied notation.
 | |
| 137 |         """
 | |
| 138 | if not isinstance(spec, (type(None), basestring)): | |
| 139 | raise TypeError('error') | |
| 140 | ||
| 141 | if spec is None: | |
| 142 | return RevisionSpec(None, _internal=True) | |
| 143 | ||
| 144 | assert isinstance(spec, basestring), \ | |
| 145 | "You should only supply strings not %s" % (type(spec),) | |
| 146 | ||
| 147 | for spectype in SPEC_TYPES: | |
| 148 | if spec.startswith(spectype.prefix): | |
| 149 | trace.mutter('Returning RevisionSpec %s for %s', | |
| 150 | spectype.__name__, spec) | |
| 151 | return spectype(spec, _internal=True) | |
| 152 | else: | |
| 153 |             # RevisionSpec_revno is special cased, because it is the only
 | |
| 154 |             # one that directly handles plain integers
 | |
| 155 | global _revno_regex | |
| 156 | if _revno_regex is None: | |
| 157 | _revno_regex = re.compile(r'-?\d+(:.*)?$') | |
| 158 | if _revno_regex.match(spec) is not None: | |
| 159 | return RevisionSpec_revno(spec, _internal=True) | |
| 160 | ||
| 161 | raise errors.NoSuchRevisionSpec(spec) | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 162 | |
| 163 | def __init__(self, spec, _internal=False): | |
| 164 | """Create a RevisionSpec referring to the Null revision. | |
| 165 | ||
| 166 |         :param spec: The original spec supplied by the user
 | |
| 167 |         :param _internal: Used to ensure that RevisionSpec is not being
 | |
| 1948.4.33
by John Arbash Meinel Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin) | 168 |             called directly. Only from RevisionSpec.from_string()
 | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 169 |         """
 | 
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 170 | if not _internal: | 
| 171 |             # XXX: Update this after 0.10 is released
 | |
| 172 | symbol_versioning.warn('Creating a RevisionSpec directly has' | |
| 173 |                                    ' been deprecated in version 0.11. Use'
 | |
| 1948.4.33
by John Arbash Meinel Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin) | 174 |                                    ' RevisionSpec.from_string()'
 | 
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 175 | ' instead.', | 
| 176 | DeprecationWarning, stacklevel=2) | |
| 177 | self.user_spec = spec | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 178 | if self.prefix and spec.startswith(self.prefix): | 
| 179 | spec = spec[len(self.prefix):] | |
| 180 | self.spec = spec | |
| 181 | ||
| 182 | def _match_on(self, branch, revs): | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 183 | trace.mutter('Returning RevisionSpec._match_on: None') | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 184 | return RevisionInfo(branch, 0, None) | 
| 185 | ||
| 186 | def _match_on_and_check(self, branch, revs): | |
| 187 | info = self._match_on(branch, revs) | |
| 188 | if info: | |
| 189 | return info | |
| 190 | elif info == (0, None): | |
| 191 |             # special case - the empty tree
 | |
| 192 | return info | |
| 193 | elif self.prefix: | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 194 | raise errors.InvalidRevisionSpec(self.user_spec, branch) | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 195 | else: | 
| 1948.4.2
by John Arbash Meinel Update _match_on_and_check to raise the right error | 196 | raise errors.InvalidRevisionSpec(self.spec, branch) | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 197 | |
| 198 | def in_history(self, branch): | |
| 1732.3.1
by Matthieu Moy Implementation of -r revno:N:/path/to/branch | 199 | if branch: | 
| 200 | revs = branch.revision_history() | |
| 201 | else: | |
| 202 | revs = None | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 203 | return self._match_on_and_check(branch, revs) | 
| 204 | ||
| 1432
by Robert Collins branch: namespace | 205 |         # FIXME: in_history is somewhat broken,
 | 
| 206 |         # it will return non-history revisions in many
 | |
| 207 |         # circumstances. The expected facility is that
 | |
| 208 |         # in_history only returns revision-history revs,
 | |
| 209 |         # in_store returns any rev. RBC 20051010
 | |
| 210 |     # aliases for now, when we fix the core logic, then they
 | |
| 211 |     # will do what you expect.
 | |
| 212 | in_store = in_history | |
| 213 | in_branch = in_store | |
| 214 | ||
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 215 | def __repr__(self): | 
| 216 |         # this is mostly for helping with testing
 | |
| 1948.4.32
by John Arbash Meinel Clean up __repr__, as well as add tests that we can handle -r12:branch/ | 217 | return '<%s %s>' % (self.__class__.__name__, | 
| 218 | self.user_spec) | |
| 1881.1.1
by Matthieu Moy Fixed and tested "bzr diff" outside a working tree. | 219 | |
| 1881.1.4
by Matthieu Moy needs_tree -> needs_branch | 220 | def needs_branch(self): | 
| 221 | """Whether this revision spec needs a branch. | |
| 222 | ||
| 1711.2.99
by John Arbash Meinel minor typo fix | 223 |         Set this to False the branch argument of _match_on is not used.
 | 
| 224 |         """
 | |
| 1881.1.1
by Matthieu Moy Fixed and tested "bzr diff" outside a working tree. | 225 | return True | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 226 | |
| 1948.4.22
by John Arbash Meinel Refactor common code from integer revno handlers | 227 | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 228 | # private API
 | 
| 229 | ||
| 230 | class RevisionSpec_revno(RevisionSpec): | |
| 231 | prefix = 'revno:' | |
| 232 | ||
| 233 | def _match_on(self, branch, revs): | |
| 234 | """Lookup a revision by revision number""" | |
| 1948.4.1
by John Arbash Meinel Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers | 235 | loc = self.spec.find(':') | 
| 236 | if loc == -1: | |
| 237 | revno_spec = self.spec | |
| 238 | branch_spec = None | |
| 239 | else: | |
| 240 | revno_spec = self.spec[:loc] | |
| 241 | branch_spec = self.spec[loc+1:] | |
| 242 | ||
| 243 | if revno_spec == '': | |
| 1948.4.6
by John Arbash Meinel A small bugfix, and more tests for revno: | 244 | if not branch_spec: | 
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 245 | raise errors.InvalidRevisionSpec(self.user_spec, | 
| 1948.4.5
by John Arbash Meinel Fix tests for negative entries, and add tests for revno: | 246 | branch, 'cannot have an empty revno and no branch') | 
| 1948.4.1
by John Arbash Meinel Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers | 247 | revno = None | 
| 248 | else: | |
| 249 | try: | |
| 250 | revno = int(revno_spec) | |
| 251 | except ValueError, e: | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 252 | raise errors.InvalidRevisionSpec(self.user_spec, | 
| 1948.4.5
by John Arbash Meinel Fix tests for negative entries, and add tests for revno: | 253 | branch, e) | 
| 1948.4.1
by John Arbash Meinel Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers | 254 | |
| 1948.4.6
by John Arbash Meinel A small bugfix, and more tests for revno: | 255 | if branch_spec: | 
| 1948.4.1
by John Arbash Meinel Update number parsers to raise InvalidRevisionSpec. Update revno: itself so it supports negative numbers | 256 | from bzrlib.branch import Branch | 
| 257 | branch = Branch.open(branch_spec) | |
| 1948.4.22
by John Arbash Meinel Refactor common code from integer revno handlers | 258 |             # Need to use a new revision history
 | 
| 259 |             # because we are using a specific branch
 | |
| 260 | revs = branch.revision_history() | |
| 261 | ||
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 262 | if revno < 0: | 
| 263 | if (-revno) >= len(revs): | |
| 264 | revno = 1 | |
| 265 | else: | |
| 266 | revno = len(revs) + revno + 1 | |
| 267 | try: | |
| 268 | revision_id = branch.get_rev_id(revno, revs) | |
| 269 | except errors.NoSuchRevision: | |
| 270 | raise errors.InvalidRevisionSpec(self.user_spec, branch) | |
| 271 | return RevisionInfo(branch, revno, revision_id) | |
| 1881.1.1
by Matthieu Moy Fixed and tested "bzr diff" outside a working tree. | 272 | |
| 1881.1.4
by Matthieu Moy needs_tree -> needs_branch | 273 | def needs_branch(self): | 
| 1881.1.1
by Matthieu Moy Fixed and tested "bzr diff" outside a working tree. | 274 | return self.spec.find(':') == -1 | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 275 | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 276 | # Old compatibility 
 | 
| 277 | RevisionSpec_int = RevisionSpec_revno | |
| 278 | ||
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 279 | SPEC_TYPES.append(RevisionSpec_revno) | 
| 280 | ||
| 281 | ||
| 282 | class RevisionSpec_revid(RevisionSpec): | |
| 283 | prefix = 'revid:' | |
| 284 | ||
| 285 | def _match_on(self, branch, revs): | |
| 286 | try: | |
| 1948.4.2
by John Arbash Meinel Update _match_on_and_check to raise the right error | 287 | revno = revs.index(self.spec) + 1 | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 288 | except ValueError: | 
| 1948.4.2
by John Arbash Meinel Update _match_on_and_check to raise the right error | 289 | revno = None | 
| 290 | return RevisionInfo(branch, revno, self.spec) | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 291 | |
| 292 | SPEC_TYPES.append(RevisionSpec_revid) | |
| 293 | ||
| 294 | ||
| 295 | class RevisionSpec_last(RevisionSpec): | |
| 1185.1.39
by Robert Collins Robey Pointers before: namespace to clear up usage of dates in revision parameters | 296 | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 297 | prefix = 'last:' | 
| 298 | ||
| 299 | def _match_on(self, branch, revs): | |
| 1948.4.9
by John Arbash Meinel Cleanup and test last: | 300 | if self.spec == '': | 
| 301 | if not revs: | |
| 1948.4.26
by John Arbash Meinel Get rid of direct imports of exceptions | 302 | raise errors.NoCommits(branch) | 
| 1948.4.9
by John Arbash Meinel Cleanup and test last: | 303 | return RevisionInfo(branch, len(revs), revs[-1]) | 
| 304 | ||
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 305 | try: | 
| 306 | offset = int(self.spec) | |
| 1948.4.9
by John Arbash Meinel Cleanup and test last: | 307 | except ValueError, e: | 
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 308 | raise errors.InvalidRevisionSpec(self.user_spec, branch, e) | 
| 1948.4.9
by John Arbash Meinel Cleanup and test last: | 309 | |
| 310 | if offset <= 0: | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 311 | raise errors.InvalidRevisionSpec(self.user_spec, branch, | 
| 1948.4.9
by John Arbash Meinel Cleanup and test last: | 312 | 'you must supply a positive value') | 
| 313 | revno = len(revs) - offset + 1 | |
| 314 | try: | |
| 315 | revision_id = branch.get_rev_id(revno, revs) | |
| 316 | except errors.NoSuchRevision: | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 317 | raise errors.InvalidRevisionSpec(self.user_spec, branch) | 
| 1948.4.9
by John Arbash Meinel Cleanup and test last: | 318 | return RevisionInfo(branch, revno, revision_id) | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 319 | |
| 320 | SPEC_TYPES.append(RevisionSpec_last) | |
| 321 | ||
| 322 | ||
| 1185.1.39
by Robert Collins Robey Pointers before: namespace to clear up usage of dates in revision parameters | 323 | class RevisionSpec_before(RevisionSpec): | 
| 324 | ||
| 325 | prefix = 'before:' | |
| 326 | ||
| 327 | def _match_on(self, branch, revs): | |
| 1948.4.33
by John Arbash Meinel Switch from get_revision_spec() to RevisionSpec.from_string() (as advised by Martin) | 328 | r = RevisionSpec.from_string(self.spec)._match_on(branch, revs) | 
| 1948.4.13
by John Arbash Meinel Going before:0 is an error, and if you are on another history, use the leftmost parent | 329 | if r.revno == 0: | 
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 330 | raise errors.InvalidRevisionSpec(self.user_spec, branch, | 
| 1948.4.13
by John Arbash Meinel Going before:0 is an error, and if you are on another history, use the leftmost parent | 331 | 'cannot go before the null: revision') | 
| 332 | if r.revno is None: | |
| 333 |             # We need to use the repository history here
 | |
| 334 | rev = branch.repository.get_revision(r.rev_id) | |
| 335 | if not rev.parent_ids: | |
| 336 | revno = 0 | |
| 337 | revision_id = None | |
| 338 | else: | |
| 339 | revision_id = rev.parent_ids[0] | |
| 340 | try: | |
| 341 | revno = revs.index(revision_id) + 1 | |
| 342 | except ValueError: | |
| 343 | revno = None | |
| 344 | else: | |
| 345 | revno = r.revno - 1 | |
| 346 | try: | |
| 347 | revision_id = branch.get_rev_id(revno, revs) | |
| 1948.4.26
by John Arbash Meinel Get rid of direct imports of exceptions | 348 | except errors.NoSuchRevision: | 
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 349 | raise errors.InvalidRevisionSpec(self.user_spec, | 
| 1948.4.13
by John Arbash Meinel Going before:0 is an error, and if you are on another history, use the leftmost parent | 350 | branch) | 
| 351 | return RevisionInfo(branch, revno, revision_id) | |
| 1185.1.39
by Robert Collins Robey Pointers before: namespace to clear up usage of dates in revision parameters | 352 | |
| 353 | SPEC_TYPES.append(RevisionSpec_before) | |
| 354 | ||
| 355 | ||
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 356 | class RevisionSpec_tag(RevisionSpec): | 
| 357 | prefix = 'tag:' | |
| 358 | ||
| 359 | def _match_on(self, branch, revs): | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 360 | raise errors.InvalidRevisionSpec(self.user_spec, branch, | 
| 1948.4.11
by John Arbash Meinel Update and test the tag: spec | 361 |                                          'tag: namespace registered,'
 | 
| 362 | ' but not implemented') | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 363 | |
| 364 | SPEC_TYPES.append(RevisionSpec_tag) | |
| 365 | ||
| 366 | ||
| 1948.4.12
by John Arbash Meinel Some tests for the date: spec | 367 | class _RevListToTimestamps(object): | 
| 368 | """This takes a list of revisions, and allows you to bisect by date""" | |
| 369 | ||
| 370 | __slots__ = ['revs', 'branch'] | |
| 371 | ||
| 1688.2.2
by Guillaume Pinot Binary search for 'date:' revision. | 372 | def __init__(self, revs, branch): | 
| 373 | self.revs = revs | |
| 374 | self.branch = branch | |
| 1948.4.12
by John Arbash Meinel Some tests for the date: spec | 375 | |
| 1688.2.2
by Guillaume Pinot Binary search for 'date:' revision. | 376 | def __getitem__(self, index): | 
| 1948.4.12
by John Arbash Meinel Some tests for the date: spec | 377 | """Get the date of the index'd item""" | 
| 1688.2.2
by Guillaume Pinot Binary search for 'date:' revision. | 378 | r = self.branch.repository.get_revision(self.revs[index]) | 
| 379 |         # TODO: Handle timezone.
 | |
| 380 | return datetime.datetime.fromtimestamp(r.timestamp) | |
| 1948.4.12
by John Arbash Meinel Some tests for the date: spec | 381 | |
| 1688.2.2
by Guillaume Pinot Binary search for 'date:' revision. | 382 | def __len__(self): | 
| 383 | return len(self.revs) | |
| 384 | ||
| 385 | ||
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 386 | class RevisionSpec_date(RevisionSpec): | 
| 387 | prefix = 'date:' | |
| 388 | _date_re = re.compile( | |
| 389 | r'(?P<date>(?P<year>\d\d\d\d)-(?P<month>\d\d)-(?P<day>\d\d))?' | |
| 390 | r'(,|T)?\s*' | |
| 391 | r'(?P<time>(?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d))?)?' | |
| 392 |         )
 | |
| 393 | ||
| 394 | def _match_on(self, branch, revs): | |
| 395 | """ | |
| 396 |         Spec for date revisions:
 | |
| 397 |           date:value
 | |
| 398 |           value can be 'yesterday', 'today', 'tomorrow' or a YYYY-MM-DD string.
 | |
| 1185.1.39
by Robert Collins Robey Pointers before: namespace to clear up usage of dates in revision parameters | 399 |           matches the first entry after a given date (either at midnight or
 | 
| 400 |           at a specified time).
 | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 401 | |
| 402 |           So the proper way of saying 'give me all entries for today' is:
 | |
| 1711.2.90
by John Arbash Meinel Fix the docstring of RevisionSpec_date (bug #31276) | 403 |               -r date:yesterday..date:today
 | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 404 |         """
 | 
| 1185.1.39
by Robert Collins Robey Pointers before: namespace to clear up usage of dates in revision parameters | 405 | today = datetime.datetime.fromordinal(datetime.date.today().toordinal()) | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 406 | if self.spec.lower() == 'yesterday': | 
| 407 | dt = today - datetime.timedelta(days=1) | |
| 408 | elif self.spec.lower() == 'today': | |
| 409 | dt = today | |
| 410 | elif self.spec.lower() == 'tomorrow': | |
| 411 | dt = today + datetime.timedelta(days=1) | |
| 412 | else: | |
| 413 | m = self._date_re.match(self.spec) | |
| 414 | if not m or (not m.group('date') and not m.group('time')): | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 415 | raise errors.InvalidRevisionSpec(self.user_spec, | 
| 1948.4.12
by John Arbash Meinel Some tests for the date: spec | 416 | branch, 'invalid date') | 
| 417 | ||
| 418 | try: | |
| 419 | if m.group('date'): | |
| 420 | year = int(m.group('year')) | |
| 421 | month = int(m.group('month')) | |
| 422 | day = int(m.group('day')) | |
| 423 | else: | |
| 424 | year = today.year | |
| 425 | month = today.month | |
| 426 | day = today.day | |
| 427 | ||
| 428 | if m.group('time'): | |
| 429 | hour = int(m.group('hour')) | |
| 430 | minute = int(m.group('minute')) | |
| 431 | if m.group('second'): | |
| 432 | second = int(m.group('second')) | |
| 433 | else: | |
| 434 | second = 0 | |
| 435 | else: | |
| 436 | hour, minute, second = 0,0,0 | |
| 437 | except ValueError: | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 438 | raise errors.InvalidRevisionSpec(self.user_spec, | 
| 1948.4.12
by John Arbash Meinel Some tests for the date: spec | 439 | branch, 'invalid date') | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 440 | |
| 441 | dt = datetime.datetime(year=year, month=month, day=day, | |
| 442 | hour=hour, minute=minute, second=second) | |
| 1704.2.27
by Martin Pool Run bisection search for revision date with lock held. (Robert Widhopf-Frenk) | 443 | branch.lock_read() | 
| 444 | try: | |
| 1948.4.12
by John Arbash Meinel Some tests for the date: spec | 445 | rev = bisect.bisect(_RevListToTimestamps(revs, branch), dt) | 
| 1704.2.27
by Martin Pool Run bisection search for revision date with lock held. (Robert Widhopf-Frenk) | 446 | finally: | 
| 447 | branch.unlock() | |
| 1688.2.2
by Guillaume Pinot Binary search for 'date:' revision. | 448 | if rev == len(revs): | 
| 449 | return RevisionInfo(branch, None) | |
| 450 | else: | |
| 451 | return RevisionInfo(branch, rev + 1) | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 452 | |
| 453 | SPEC_TYPES.append(RevisionSpec_date) | |
| 454 | ||
| 455 | ||
| 456 | class RevisionSpec_ancestor(RevisionSpec): | |
| 457 | prefix = 'ancestor:' | |
| 458 | ||
| 459 | def _match_on(self, branch, revs): | |
| 1948.4.16
by John Arbash Meinel Move the tests into the associated tester, remove redundant tests, some small PEP8 changes | 460 | from bzrlib.branch import Branch | 
| 1948.4.18
by John Arbash Meinel Update branch: spec and tests | 461 | |
| 1948.4.27
by John Arbash Meinel Deprecate calling RevisionSpec directly, and instead use a helper function. Also merge the old RevisionSpec_int class into RevisionSpec_revno | 462 | trace.mutter('matching ancestor: on: %s, %s', self.spec, branch) | 
| 1948.4.17
by John Arbash Meinel Update tests for ancestor: spec | 463 | other_branch = Branch.open(self.spec) | 
| 1390
by Robert Collins pair programming worx... merge integration and weave | 464 | revision_a = branch.last_revision() | 
| 465 | revision_b = other_branch.last_revision() | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 466 | for r, b in ((revision_a, branch), (revision_b, other_branch)): | 
| 1948.4.18
by John Arbash Meinel Update branch: spec and tests | 467 | if r in (None, revision.NULL_REVISION): | 
| 1948.4.26
by John Arbash Meinel Get rid of direct imports of exceptions | 468 | raise errors.NoCommits(b) | 
| 1948.4.18
by John Arbash Meinel Update branch: spec and tests | 469 | revision_source = revision.MultipleRevisionSources( | 
| 470 | branch.repository, other_branch.repository) | |
| 471 | rev_id = revision.common_ancestor(revision_a, revision_b, | |
| 472 | revision_source) | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 473 | try: | 
| 474 | revno = branch.revision_id_to_revno(rev_id) | |
| 1948.4.26
by John Arbash Meinel Get rid of direct imports of exceptions | 475 | except errors.NoSuchRevision: | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 476 | revno = None | 
| 477 | return RevisionInfo(branch, revno, rev_id) | |
| 478 | ||
| 479 | SPEC_TYPES.append(RevisionSpec_ancestor) | |
| 1432
by Robert Collins branch: namespace | 480 | |
| 1948.4.16
by John Arbash Meinel Move the tests into the associated tester, remove redundant tests, some small PEP8 changes | 481 | |
| 1432
by Robert Collins branch: namespace | 482 | class RevisionSpec_branch(RevisionSpec): | 
| 483 | """A branch: revision specifier. | |
| 484 | ||
| 485 |     This takes the path to a branch and returns its tip revision id.
 | |
| 486 |     """
 | |
| 487 | prefix = 'branch:' | |
| 488 | ||
| 489 | def _match_on(self, branch, revs): | |
| 1948.4.18
by John Arbash Meinel Update branch: spec and tests | 490 | from bzrlib.branch import Branch | 
| 491 | other_branch = Branch.open(self.spec) | |
| 1432
by Robert Collins branch: namespace | 492 | revision_b = other_branch.last_revision() | 
| 1948.4.18
by John Arbash Meinel Update branch: spec and tests | 493 | if revision_b in (None, revision.NULL_REVISION): | 
| 1948.4.26
by John Arbash Meinel Get rid of direct imports of exceptions | 494 | raise errors.NoCommits(other_branch) | 
| 1432
by Robert Collins branch: namespace | 495 |         # pull in the remote revisions so we can diff
 | 
| 1534.1.31
by Robert Collins Deprecated fetch.fetch and fetch.greedy_fetch for branch.fetch, and move the Repository.fetch internals to InterRepo and InterWeaveRepo. | 496 | branch.fetch(other_branch, revision_b) | 
| 1432
by Robert Collins branch: namespace | 497 | try: | 
| 498 | revno = branch.revision_id_to_revno(revision_b) | |
| 1948.4.26
by John Arbash Meinel Get rid of direct imports of exceptions | 499 | except errors.NoSuchRevision: | 
| 1432
by Robert Collins branch: namespace | 500 | revno = None | 
| 501 | return RevisionInfo(branch, revno, revision_b) | |
| 502 | ||
| 503 | SPEC_TYPES.append(RevisionSpec_branch) |