~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/revisionspec.py

  • Committer: Martin Pool
  • Date: 2005-11-28 08:03:42 UTC
  • mto: (1185.33.61 bzr.dev)
  • mto: This revision was merged to the branch mainline in revision 1518.
  • Revision ID: mbp@sourcefrog.net-20051128080342-b7db3190dca90484
[broken] start converting basic_io to more rfc822-like format

Suggestions from mailing list:
 
  no double quotes
  no cute right-alignment
  no escaping
  just indent continuation lines

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
import datetime
19
19
import re
20
 
from bzrlib.errors import BzrError, NoSuchRevision
 
20
from bzrlib.errors import BzrError, NoSuchRevision, NoCommits
21
21
 
22
22
_marker = []
23
23
 
49
49
            self.rev_id = rev_id
50
50
 
51
51
    def __nonzero__(self):
52
 
        return not (self.revno is None or self.rev_id is None)
 
52
        # first the easy ones...
 
53
        if self.rev_id is None:
 
54
            return False
 
55
        if self.revno is not None:
 
56
            return True
 
57
        # TODO: otherwise, it should depend on how I was built -
 
58
        # if it's in_history(branch), then check revision_history(),
 
59
        # if it's in_store(branch), do the check below
 
60
        return self.branch.revision_store.has_id(self.rev_id)
53
61
 
54
62
    def __len__(self):
55
63
        return 2
143
151
        revs = branch.revision_history()
144
152
        return self._match_on_and_check(branch, revs)
145
153
 
 
154
        # FIXME: in_history is somewhat broken,
 
155
        # it will return non-history revisions in many
 
156
        # circumstances. The expected facility is that
 
157
        # in_history only returns revision-history revs,
 
158
        # in_store returns any rev. RBC 20051010
 
159
    # aliases for now, when we fix the core logic, then they
 
160
    # will do what you expect.
 
161
    in_store = in_history
 
162
    in_branch = in_store
 
163
        
146
164
    def __repr__(self):
147
165
        # this is mostly for helping with testing
148
166
        return '<%s %s%s>' % (self.__class__.__name__,
192
210
 
193
211
 
194
212
class RevisionSpec_last(RevisionSpec):
 
213
 
195
214
    prefix = 'last:'
196
215
 
197
216
    def _match_on(self, branch, revs):
207
226
SPEC_TYPES.append(RevisionSpec_last)
208
227
 
209
228
 
 
229
class RevisionSpec_before(RevisionSpec):
 
230
 
 
231
    prefix = 'before:'
 
232
    
 
233
    def _match_on(self, branch, revs):
 
234
        r = RevisionSpec(self.spec)._match_on(branch, revs)
 
235
        if (r.revno is None) or (r.revno == 0):
 
236
            return r
 
237
        return RevisionInfo(branch, r.revno - 1)
 
238
 
 
239
SPEC_TYPES.append(RevisionSpec_before)
 
240
 
 
241
 
210
242
class RevisionSpec_tag(RevisionSpec):
211
243
    prefix = 'tag:'
212
244
 
229
261
        Spec for date revisions:
230
262
          date:value
231
263
          value can be 'yesterday', 'today', 'tomorrow' or a YYYY-MM-DD string.
232
 
          it can also start with a '+/-/='. '+' says match the first
233
 
          entry after the given date. '-' is match the first entry before the date
234
 
          '=' is match the first entry after, but still on the given date.
235
 
 
236
 
          +2005-05-12 says find the first matching entry after May 12th, 2005 at 0:00
237
 
          -2005-05-12 says find the first matching entry before May 12th, 2005 at 0:00
238
 
          =2005-05-12 says find the first match after May 12th, 2005 at 0:00 but before
239
 
              May 13th, 2005 at 0:00
 
264
          matches the first entry after a given date (either at midnight or
 
265
          at a specified time).
240
266
 
241
267
          So the proper way of saying 'give me all entries for today' is:
242
 
              -r {date:+today}:{date:-tomorrow}
243
 
          The default is '=' when not supplied
 
268
              -r date:today..date:tomorrow
244
269
        """
245
 
        match_style = '='
246
 
        if self.spec[:1] in ('+', '-', '='):
247
 
            match_style = self.spec[:1]
248
 
            self.spec = self.spec[1:]
249
 
 
250
 
        # XXX: this should probably be using datetime.date instead
251
 
        today = datetime.datetime.today().replace(hour=0, minute=0, second=0,
252
 
                                                  microsecond=0)
 
270
        today = datetime.datetime.fromordinal(datetime.date.today().toordinal())
253
271
        if self.spec.lower() == 'yesterday':
254
272
            dt = today - datetime.timedelta(days=1)
255
273
        elif self.spec.lower() == 'today':
278
296
            dt = datetime.datetime(year=year, month=month, day=day,
279
297
                    hour=hour, minute=minute, second=second)
280
298
        first = dt
281
 
        last = None
282
 
        reversed = False
283
 
        if match_style == '-':
284
 
            reversed = True
285
 
        elif match_style == '=':
286
 
            last = dt + datetime.timedelta(days=1)
287
 
 
288
 
        if reversed:
289
 
            for i in range(len(revs)-1, -1, -1):
290
 
                r = branch.get_revision(revs[i])
291
 
                # TODO: Handle timezone.
292
 
                dt = datetime.datetime.fromtimestamp(r.timestamp)
293
 
                if first >= dt and (last is None or dt >= last):
294
 
                    return RevisionInfo(branch, i+1,)
295
 
        else:
296
 
            for i in range(len(revs)):
297
 
                r = branch.get_revision(revs[i])
298
 
                # TODO: Handle timezone.
299
 
                dt = datetime.datetime.fromtimestamp(r.timestamp)
300
 
                if first <= dt and (last is None or dt <= last):
301
 
                    return RevisionInfo(branch, i+1,)
 
299
        for i in range(len(revs)):
 
300
            r = branch.get_revision(revs[i])
 
301
            # TODO: Handle timezone.
 
302
            dt = datetime.datetime.fromtimestamp(r.timestamp)
 
303
            if first <= dt:
 
304
                return RevisionInfo(branch, i+1)
 
305
        return RevisionInfo(branch, None)
302
306
 
303
307
SPEC_TYPES.append(RevisionSpec_date)
 
308
 
 
309
 
 
310
class RevisionSpec_ancestor(RevisionSpec):
 
311
    prefix = 'ancestor:'
 
312
 
 
313
    def _match_on(self, branch, revs):
 
314
        from branch import Branch
 
315
        from revision import common_ancestor, MultipleRevisionSources
 
316
        other_branch = Branch.open_containing(self.spec)[0]
 
317
        revision_a = branch.last_revision()
 
318
        revision_b = other_branch.last_revision()
 
319
        for r, b in ((revision_a, branch), (revision_b, other_branch)):
 
320
            if r is None:
 
321
                raise NoCommits(b)
 
322
        revision_source = MultipleRevisionSources(branch, other_branch)
 
323
        rev_id = common_ancestor(revision_a, revision_b, revision_source)
 
324
        try:
 
325
            revno = branch.revision_id_to_revno(rev_id)
 
326
        except NoSuchRevision:
 
327
            revno = None
 
328
        return RevisionInfo(branch, revno, rev_id)
 
329
        
 
330
SPEC_TYPES.append(RevisionSpec_ancestor)
 
331
 
 
332
class RevisionSpec_branch(RevisionSpec):
 
333
    """A branch: revision specifier.
 
334
 
 
335
    This takes the path to a branch and returns its tip revision id.
 
336
    """
 
337
    prefix = 'branch:'
 
338
 
 
339
    def _match_on(self, branch, revs):
 
340
        from branch import Branch
 
341
        from fetch import greedy_fetch
 
342
        other_branch = Branch.open_containing(self.spec)[0]
 
343
        revision_b = other_branch.last_revision()
 
344
        if revision_b is None:
 
345
            raise NoCommits(other_branch)
 
346
        # pull in the remote revisions so we can diff
 
347
        greedy_fetch(branch, other_branch, revision=revision_b)
 
348
        try:
 
349
            revno = branch.revision_id_to_revno(revision_b)
 
350
        except NoSuchRevision:
 
351
            revno = None
 
352
        return RevisionInfo(branch, revno, revision_b)
 
353
        
 
354
SPEC_TYPES.append(RevisionSpec_branch)