57
57
# TODO: otherwise, it should depend on how I was built -
58
58
# if it's in_history(branch), then check revision_history(),
59
59
# if it's in_store(branch), do the check below
60
return self.branch.repository.has_revision(self.rev_id)
60
return self.rev_id in self.branch.revision_store
151
151
revs = branch.revision_history()
152
152
return self._match_on_and_check(branch, revs)
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
164
154
def __repr__(self):
165
155
# this is mostly for helping with testing
166
156
return '<%s %s%s>' % (self.__class__.__name__,
205
195
return RevisionInfo(branch, revs.index(self.spec) + 1, self.spec)
206
196
except ValueError:
207
return RevisionInfo(branch, None, self.spec)
197
return RevisionInfo(branch, None)
209
199
SPEC_TYPES.append(RevisionSpec_revid)
212
202
class RevisionSpec_last(RevisionSpec):
216
205
def _match_on(self, branch, revs):
226
215
SPEC_TYPES.append(RevisionSpec_last)
229
class RevisionSpec_before(RevisionSpec):
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):
237
return RevisionInfo(branch, r.revno - 1)
239
SPEC_TYPES.append(RevisionSpec_before)
242
218
class RevisionSpec_tag(RevisionSpec):
261
237
Spec for date revisions:
263
239
value can be 'yesterday', 'today', 'tomorrow' or a YYYY-MM-DD string.
264
matches the first entry after a given date (either at midnight or
265
at a specified time).
240
it can also start with a '+/-/='. '+' says match the first
241
entry after the given date. '-' is match the first entry before the date
242
'=' is match the first entry after, but still on the given date.
244
+2005-05-12 says find the first matching entry after May 12th, 2005 at 0:00
245
-2005-05-12 says find the first matching entry before May 12th, 2005 at 0:00
246
=2005-05-12 says find the first match after May 12th, 2005 at 0:00 but before
247
May 13th, 2005 at 0:00
267
249
So the proper way of saying 'give me all entries for today' is:
268
-r date:today..date:tomorrow
250
-r {date:+today}:{date:-tomorrow}
251
The default is '=' when not supplied
270
today = datetime.datetime.fromordinal(datetime.date.today().toordinal())
254
if self.spec[:1] in ('+', '-', '='):
255
match_style = self.spec[:1]
256
self.spec = self.spec[1:]
258
# XXX: this should probably be using datetime.date instead
259
today = datetime.datetime.today().replace(hour=0, minute=0, second=0,
271
261
if self.spec.lower() == 'yesterday':
272
262
dt = today - datetime.timedelta(days=1)
273
263
elif self.spec.lower() == 'today':
296
286
dt = datetime.datetime(year=year, month=month, day=day,
297
287
hour=hour, minute=minute, second=second)
299
for i in range(len(revs)):
300
r = branch.repository.get_revision(revs[i])
301
# TODO: Handle timezone.
302
dt = datetime.datetime.fromtimestamp(r.timestamp)
304
return RevisionInfo(branch, i+1)
305
return RevisionInfo(branch, None)
291
if match_style == '-':
293
elif match_style == '=':
294
last = dt + datetime.timedelta(days=1)
297
for i in range(len(revs)-1, -1, -1):
298
r = branch.get_revision(revs[i])
299
# TODO: Handle timezone.
300
dt = datetime.datetime.fromtimestamp(r.timestamp)
301
if first >= dt and (last is None or dt >= last):
302
return RevisionInfo(branch, i+1,)
304
for i in range(len(revs)):
305
r = branch.get_revision(revs[i])
306
# TODO: Handle timezone.
307
dt = datetime.datetime.fromtimestamp(r.timestamp)
308
if first <= dt and (last is None or dt <= last):
309
return RevisionInfo(branch, i+1,)
307
311
SPEC_TYPES.append(RevisionSpec_date)
313
317
def _match_on(self, branch, revs):
314
318
from branch import Branch
315
319
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()
320
other_branch = Branch.open_containing(self.spec)
321
revision_a = branch.last_patch()
322
revision_b = other_branch.last_patch()
319
323
for r, b in ((revision_a, branch), (revision_b, other_branch)):
321
325
raise NoCommits(b)
322
revision_source = MultipleRevisionSources(branch.repository,
323
other_branch.repository)
326
revision_source = MultipleRevisionSources(branch, other_branch)
324
327
rev_id = common_ancestor(revision_a, revision_b, revision_source)
326
329
revno = branch.revision_id_to_revno(rev_id)
329
332
return RevisionInfo(branch, revno, rev_id)
331
334
SPEC_TYPES.append(RevisionSpec_ancestor)
333
class RevisionSpec_branch(RevisionSpec):
334
"""A branch: revision specifier.
336
This takes the path to a branch and returns its tip revision id.
340
def _match_on(self, branch, revs):
341
from branch import Branch
342
from fetch import greedy_fetch
343
other_branch = Branch.open_containing(self.spec)[0]
344
revision_b = other_branch.last_revision()
345
if revision_b is None:
346
raise NoCommits(other_branch)
347
# pull in the remote revisions so we can diff
348
greedy_fetch(branch, other_branch, revision=revision_b)
350
revno = branch.revision_id_to_revno(revision_b)
351
except NoSuchRevision:
353
return RevisionInfo(branch, revno, revision_b)
355
SPEC_TYPES.append(RevisionSpec_branch)