##// END OF EJS Templates
smartset: change repr of spanset to show revisions as half-open range...
Yuya Nishihara -
r32817:e962c70c default
parent child Browse files
Show More
@@ -1,1066 +1,1066 b''
1 # smartset.py - data structure for revision set
1 # smartset.py - data structure for revision set
2 #
2 #
3 # Copyright 2010 Matt Mackall <mpm@selenic.com>
3 # Copyright 2010 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 from . import (
10 from . import (
11 util,
11 util,
12 )
12 )
13
13
14 def _formatsetrepr(r):
14 def _formatsetrepr(r):
15 """Format an optional printable representation of a set
15 """Format an optional printable representation of a set
16
16
17 ======== =================================
17 ======== =================================
18 type(r) example
18 type(r) example
19 ======== =================================
19 ======== =================================
20 tuple ('<not %r>', other)
20 tuple ('<not %r>', other)
21 str '<branch closed>'
21 str '<branch closed>'
22 callable lambda: '<branch %r>' % sorted(b)
22 callable lambda: '<branch %r>' % sorted(b)
23 object other
23 object other
24 ======== =================================
24 ======== =================================
25 """
25 """
26 if r is None:
26 if r is None:
27 return ''
27 return ''
28 elif isinstance(r, tuple):
28 elif isinstance(r, tuple):
29 return r[0] % r[1:]
29 return r[0] % r[1:]
30 elif isinstance(r, str):
30 elif isinstance(r, str):
31 return r
31 return r
32 elif callable(r):
32 elif callable(r):
33 return r()
33 return r()
34 else:
34 else:
35 return repr(r)
35 return repr(r)
36
36
37 class abstractsmartset(object):
37 class abstractsmartset(object):
38
38
39 def __nonzero__(self):
39 def __nonzero__(self):
40 """True if the smartset is not empty"""
40 """True if the smartset is not empty"""
41 raise NotImplementedError()
41 raise NotImplementedError()
42
42
43 __bool__ = __nonzero__
43 __bool__ = __nonzero__
44
44
45 def __contains__(self, rev):
45 def __contains__(self, rev):
46 """provide fast membership testing"""
46 """provide fast membership testing"""
47 raise NotImplementedError()
47 raise NotImplementedError()
48
48
49 def __iter__(self):
49 def __iter__(self):
50 """iterate the set in the order it is supposed to be iterated"""
50 """iterate the set in the order it is supposed to be iterated"""
51 raise NotImplementedError()
51 raise NotImplementedError()
52
52
53 # Attributes containing a function to perform a fast iteration in a given
53 # Attributes containing a function to perform a fast iteration in a given
54 # direction. A smartset can have none, one, or both defined.
54 # direction. A smartset can have none, one, or both defined.
55 #
55 #
56 # Default value is None instead of a function returning None to avoid
56 # Default value is None instead of a function returning None to avoid
57 # initializing an iterator just for testing if a fast method exists.
57 # initializing an iterator just for testing if a fast method exists.
58 fastasc = None
58 fastasc = None
59 fastdesc = None
59 fastdesc = None
60
60
61 def isascending(self):
61 def isascending(self):
62 """True if the set will iterate in ascending order"""
62 """True if the set will iterate in ascending order"""
63 raise NotImplementedError()
63 raise NotImplementedError()
64
64
65 def isdescending(self):
65 def isdescending(self):
66 """True if the set will iterate in descending order"""
66 """True if the set will iterate in descending order"""
67 raise NotImplementedError()
67 raise NotImplementedError()
68
68
69 def istopo(self):
69 def istopo(self):
70 """True if the set will iterate in topographical order"""
70 """True if the set will iterate in topographical order"""
71 raise NotImplementedError()
71 raise NotImplementedError()
72
72
73 def min(self):
73 def min(self):
74 """return the minimum element in the set"""
74 """return the minimum element in the set"""
75 if self.fastasc is None:
75 if self.fastasc is None:
76 v = min(self)
76 v = min(self)
77 else:
77 else:
78 for v in self.fastasc():
78 for v in self.fastasc():
79 break
79 break
80 else:
80 else:
81 raise ValueError('arg is an empty sequence')
81 raise ValueError('arg is an empty sequence')
82 self.min = lambda: v
82 self.min = lambda: v
83 return v
83 return v
84
84
85 def max(self):
85 def max(self):
86 """return the maximum element in the set"""
86 """return the maximum element in the set"""
87 if self.fastdesc is None:
87 if self.fastdesc is None:
88 return max(self)
88 return max(self)
89 else:
89 else:
90 for v in self.fastdesc():
90 for v in self.fastdesc():
91 break
91 break
92 else:
92 else:
93 raise ValueError('arg is an empty sequence')
93 raise ValueError('arg is an empty sequence')
94 self.max = lambda: v
94 self.max = lambda: v
95 return v
95 return v
96
96
97 def first(self):
97 def first(self):
98 """return the first element in the set (user iteration perspective)
98 """return the first element in the set (user iteration perspective)
99
99
100 Return None if the set is empty"""
100 Return None if the set is empty"""
101 raise NotImplementedError()
101 raise NotImplementedError()
102
102
103 def last(self):
103 def last(self):
104 """return the last element in the set (user iteration perspective)
104 """return the last element in the set (user iteration perspective)
105
105
106 Return None if the set is empty"""
106 Return None if the set is empty"""
107 raise NotImplementedError()
107 raise NotImplementedError()
108
108
109 def __len__(self):
109 def __len__(self):
110 """return the length of the smartsets
110 """return the length of the smartsets
111
111
112 This can be expensive on smartset that could be lazy otherwise."""
112 This can be expensive on smartset that could be lazy otherwise."""
113 raise NotImplementedError()
113 raise NotImplementedError()
114
114
115 def reverse(self):
115 def reverse(self):
116 """reverse the expected iteration order"""
116 """reverse the expected iteration order"""
117 raise NotImplementedError()
117 raise NotImplementedError()
118
118
119 def sort(self, reverse=True):
119 def sort(self, reverse=True):
120 """get the set to iterate in an ascending or descending order"""
120 """get the set to iterate in an ascending or descending order"""
121 raise NotImplementedError()
121 raise NotImplementedError()
122
122
123 def __and__(self, other):
123 def __and__(self, other):
124 """Returns a new object with the intersection of the two collections.
124 """Returns a new object with the intersection of the two collections.
125
125
126 This is part of the mandatory API for smartset."""
126 This is part of the mandatory API for smartset."""
127 if isinstance(other, fullreposet):
127 if isinstance(other, fullreposet):
128 return self
128 return self
129 return self.filter(other.__contains__, condrepr=other, cache=False)
129 return self.filter(other.__contains__, condrepr=other, cache=False)
130
130
131 def __add__(self, other):
131 def __add__(self, other):
132 """Returns a new object with the union of the two collections.
132 """Returns a new object with the union of the two collections.
133
133
134 This is part of the mandatory API for smartset."""
134 This is part of the mandatory API for smartset."""
135 return addset(self, other)
135 return addset(self, other)
136
136
137 def __sub__(self, other):
137 def __sub__(self, other):
138 """Returns a new object with the substraction of the two collections.
138 """Returns a new object with the substraction of the two collections.
139
139
140 This is part of the mandatory API for smartset."""
140 This is part of the mandatory API for smartset."""
141 c = other.__contains__
141 c = other.__contains__
142 return self.filter(lambda r: not c(r), condrepr=('<not %r>', other),
142 return self.filter(lambda r: not c(r), condrepr=('<not %r>', other),
143 cache=False)
143 cache=False)
144
144
145 def filter(self, condition, condrepr=None, cache=True):
145 def filter(self, condition, condrepr=None, cache=True):
146 """Returns this smartset filtered by condition as a new smartset.
146 """Returns this smartset filtered by condition as a new smartset.
147
147
148 `condition` is a callable which takes a revision number and returns a
148 `condition` is a callable which takes a revision number and returns a
149 boolean. Optional `condrepr` provides a printable representation of
149 boolean. Optional `condrepr` provides a printable representation of
150 the given `condition`.
150 the given `condition`.
151
151
152 This is part of the mandatory API for smartset."""
152 This is part of the mandatory API for smartset."""
153 # builtin cannot be cached. but do not needs to
153 # builtin cannot be cached. but do not needs to
154 if cache and util.safehasattr(condition, 'func_code'):
154 if cache and util.safehasattr(condition, 'func_code'):
155 condition = util.cachefunc(condition)
155 condition = util.cachefunc(condition)
156 return filteredset(self, condition, condrepr)
156 return filteredset(self, condition, condrepr)
157
157
158 class baseset(abstractsmartset):
158 class baseset(abstractsmartset):
159 """Basic data structure that represents a revset and contains the basic
159 """Basic data structure that represents a revset and contains the basic
160 operation that it should be able to perform.
160 operation that it should be able to perform.
161
161
162 Every method in this class should be implemented by any smartset class.
162 Every method in this class should be implemented by any smartset class.
163
163
164 This class could be constructed by an (unordered) set, or an (ordered)
164 This class could be constructed by an (unordered) set, or an (ordered)
165 list-like object. If a set is provided, it'll be sorted lazily.
165 list-like object. If a set is provided, it'll be sorted lazily.
166
166
167 >>> x = [4, 0, 7, 6]
167 >>> x = [4, 0, 7, 6]
168 >>> y = [5, 6, 7, 3]
168 >>> y = [5, 6, 7, 3]
169
169
170 Construct by a set:
170 Construct by a set:
171 >>> xs = baseset(set(x))
171 >>> xs = baseset(set(x))
172 >>> ys = baseset(set(y))
172 >>> ys = baseset(set(y))
173 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
173 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
174 [[0, 4, 6, 7, 3, 5], [6, 7], [0, 4]]
174 [[0, 4, 6, 7, 3, 5], [6, 7], [0, 4]]
175 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
175 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
176 ['addset', 'baseset', 'baseset']
176 ['addset', 'baseset', 'baseset']
177
177
178 Construct by a list-like:
178 Construct by a list-like:
179 >>> xs = baseset(x)
179 >>> xs = baseset(x)
180 >>> ys = baseset(i for i in y)
180 >>> ys = baseset(i for i in y)
181 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
181 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
182 [[4, 0, 7, 6, 5, 3], [7, 6], [4, 0]]
182 [[4, 0, 7, 6, 5, 3], [7, 6], [4, 0]]
183 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
183 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
184 ['addset', 'filteredset', 'filteredset']
184 ['addset', 'filteredset', 'filteredset']
185
185
186 Populate "_set" fields in the lists so set optimization may be used:
186 Populate "_set" fields in the lists so set optimization may be used:
187 >>> [1 in xs, 3 in ys]
187 >>> [1 in xs, 3 in ys]
188 [False, True]
188 [False, True]
189
189
190 Without sort(), results won't be changed:
190 Without sort(), results won't be changed:
191 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
191 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
192 [[4, 0, 7, 6, 5, 3], [7, 6], [4, 0]]
192 [[4, 0, 7, 6, 5, 3], [7, 6], [4, 0]]
193 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
193 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
194 ['addset', 'filteredset', 'filteredset']
194 ['addset', 'filteredset', 'filteredset']
195
195
196 With sort(), set optimization could be used:
196 With sort(), set optimization could be used:
197 >>> xs.sort(reverse=True)
197 >>> xs.sort(reverse=True)
198 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
198 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
199 [[7, 6, 4, 0, 5, 3], [7, 6], [4, 0]]
199 [[7, 6, 4, 0, 5, 3], [7, 6], [4, 0]]
200 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
200 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
201 ['addset', 'baseset', 'baseset']
201 ['addset', 'baseset', 'baseset']
202
202
203 >>> ys.sort()
203 >>> ys.sort()
204 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
204 >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]]
205 [[7, 6, 4, 0, 3, 5], [7, 6], [4, 0]]
205 [[7, 6, 4, 0, 3, 5], [7, 6], [4, 0]]
206 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
206 >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]]
207 ['addset', 'baseset', 'baseset']
207 ['addset', 'baseset', 'baseset']
208
208
209 istopo is preserved across set operations
209 istopo is preserved across set operations
210 >>> xs = baseset(set(x), istopo=True)
210 >>> xs = baseset(set(x), istopo=True)
211 >>> rs = xs & ys
211 >>> rs = xs & ys
212 >>> type(rs).__name__
212 >>> type(rs).__name__
213 'baseset'
213 'baseset'
214 >>> rs._istopo
214 >>> rs._istopo
215 True
215 True
216 """
216 """
217 def __init__(self, data=(), datarepr=None, istopo=False):
217 def __init__(self, data=(), datarepr=None, istopo=False):
218 """
218 """
219 datarepr: a tuple of (format, obj, ...), a function or an object that
219 datarepr: a tuple of (format, obj, ...), a function or an object that
220 provides a printable representation of the given data.
220 provides a printable representation of the given data.
221 """
221 """
222 self._ascending = None
222 self._ascending = None
223 self._istopo = istopo
223 self._istopo = istopo
224 if isinstance(data, set):
224 if isinstance(data, set):
225 # converting set to list has a cost, do it lazily
225 # converting set to list has a cost, do it lazily
226 self._set = data
226 self._set = data
227 # set has no order we pick one for stability purpose
227 # set has no order we pick one for stability purpose
228 self._ascending = True
228 self._ascending = True
229 else:
229 else:
230 if not isinstance(data, list):
230 if not isinstance(data, list):
231 data = list(data)
231 data = list(data)
232 self._list = data
232 self._list = data
233 self._datarepr = datarepr
233 self._datarepr = datarepr
234
234
235 @util.propertycache
235 @util.propertycache
236 def _set(self):
236 def _set(self):
237 return set(self._list)
237 return set(self._list)
238
238
239 @util.propertycache
239 @util.propertycache
240 def _asclist(self):
240 def _asclist(self):
241 asclist = self._list[:]
241 asclist = self._list[:]
242 asclist.sort()
242 asclist.sort()
243 return asclist
243 return asclist
244
244
245 @util.propertycache
245 @util.propertycache
246 def _list(self):
246 def _list(self):
247 # _list is only lazily constructed if we have _set
247 # _list is only lazily constructed if we have _set
248 assert r'_set' in self.__dict__
248 assert r'_set' in self.__dict__
249 return list(self._set)
249 return list(self._set)
250
250
251 def __iter__(self):
251 def __iter__(self):
252 if self._ascending is None:
252 if self._ascending is None:
253 return iter(self._list)
253 return iter(self._list)
254 elif self._ascending:
254 elif self._ascending:
255 return iter(self._asclist)
255 return iter(self._asclist)
256 else:
256 else:
257 return reversed(self._asclist)
257 return reversed(self._asclist)
258
258
259 def fastasc(self):
259 def fastasc(self):
260 return iter(self._asclist)
260 return iter(self._asclist)
261
261
262 def fastdesc(self):
262 def fastdesc(self):
263 return reversed(self._asclist)
263 return reversed(self._asclist)
264
264
265 @util.propertycache
265 @util.propertycache
266 def __contains__(self):
266 def __contains__(self):
267 return self._set.__contains__
267 return self._set.__contains__
268
268
269 def __nonzero__(self):
269 def __nonzero__(self):
270 return bool(len(self))
270 return bool(len(self))
271
271
272 __bool__ = __nonzero__
272 __bool__ = __nonzero__
273
273
274 def sort(self, reverse=False):
274 def sort(self, reverse=False):
275 self._ascending = not bool(reverse)
275 self._ascending = not bool(reverse)
276 self._istopo = False
276 self._istopo = False
277
277
278 def reverse(self):
278 def reverse(self):
279 if self._ascending is None:
279 if self._ascending is None:
280 self._list.reverse()
280 self._list.reverse()
281 else:
281 else:
282 self._ascending = not self._ascending
282 self._ascending = not self._ascending
283 self._istopo = False
283 self._istopo = False
284
284
285 def __len__(self):
285 def __len__(self):
286 if '_list' in self.__dict__:
286 if '_list' in self.__dict__:
287 return len(self._list)
287 return len(self._list)
288 else:
288 else:
289 return len(self._set)
289 return len(self._set)
290
290
291 def isascending(self):
291 def isascending(self):
292 """Returns True if the collection is ascending order, False if not.
292 """Returns True if the collection is ascending order, False if not.
293
293
294 This is part of the mandatory API for smartset."""
294 This is part of the mandatory API for smartset."""
295 if len(self) <= 1:
295 if len(self) <= 1:
296 return True
296 return True
297 return self._ascending is not None and self._ascending
297 return self._ascending is not None and self._ascending
298
298
299 def isdescending(self):
299 def isdescending(self):
300 """Returns True if the collection is descending order, False if not.
300 """Returns True if the collection is descending order, False if not.
301
301
302 This is part of the mandatory API for smartset."""
302 This is part of the mandatory API for smartset."""
303 if len(self) <= 1:
303 if len(self) <= 1:
304 return True
304 return True
305 return self._ascending is not None and not self._ascending
305 return self._ascending is not None and not self._ascending
306
306
307 def istopo(self):
307 def istopo(self):
308 """Is the collection is in topographical order or not.
308 """Is the collection is in topographical order or not.
309
309
310 This is part of the mandatory API for smartset."""
310 This is part of the mandatory API for smartset."""
311 if len(self) <= 1:
311 if len(self) <= 1:
312 return True
312 return True
313 return self._istopo
313 return self._istopo
314
314
315 def first(self):
315 def first(self):
316 if self:
316 if self:
317 if self._ascending is None:
317 if self._ascending is None:
318 return self._list[0]
318 return self._list[0]
319 elif self._ascending:
319 elif self._ascending:
320 return self._asclist[0]
320 return self._asclist[0]
321 else:
321 else:
322 return self._asclist[-1]
322 return self._asclist[-1]
323 return None
323 return None
324
324
325 def last(self):
325 def last(self):
326 if self:
326 if self:
327 if self._ascending is None:
327 if self._ascending is None:
328 return self._list[-1]
328 return self._list[-1]
329 elif self._ascending:
329 elif self._ascending:
330 return self._asclist[-1]
330 return self._asclist[-1]
331 else:
331 else:
332 return self._asclist[0]
332 return self._asclist[0]
333 return None
333 return None
334
334
335 def _fastsetop(self, other, op):
335 def _fastsetop(self, other, op):
336 # try to use native set operations as fast paths
336 # try to use native set operations as fast paths
337 if (type(other) is baseset and '_set' in other.__dict__ and '_set' in
337 if (type(other) is baseset and '_set' in other.__dict__ and '_set' in
338 self.__dict__ and self._ascending is not None):
338 self.__dict__ and self._ascending is not None):
339 s = baseset(data=getattr(self._set, op)(other._set),
339 s = baseset(data=getattr(self._set, op)(other._set),
340 istopo=self._istopo)
340 istopo=self._istopo)
341 s._ascending = self._ascending
341 s._ascending = self._ascending
342 else:
342 else:
343 s = getattr(super(baseset, self), op)(other)
343 s = getattr(super(baseset, self), op)(other)
344 return s
344 return s
345
345
346 def __and__(self, other):
346 def __and__(self, other):
347 return self._fastsetop(other, '__and__')
347 return self._fastsetop(other, '__and__')
348
348
349 def __sub__(self, other):
349 def __sub__(self, other):
350 return self._fastsetop(other, '__sub__')
350 return self._fastsetop(other, '__sub__')
351
351
352 def __repr__(self):
352 def __repr__(self):
353 d = {None: '', False: '-', True: '+'}[self._ascending]
353 d = {None: '', False: '-', True: '+'}[self._ascending]
354 s = _formatsetrepr(self._datarepr)
354 s = _formatsetrepr(self._datarepr)
355 if not s:
355 if not s:
356 l = self._list
356 l = self._list
357 # if _list has been built from a set, it might have a different
357 # if _list has been built from a set, it might have a different
358 # order from one python implementation to another.
358 # order from one python implementation to another.
359 # We fallback to the sorted version for a stable output.
359 # We fallback to the sorted version for a stable output.
360 if self._ascending is not None:
360 if self._ascending is not None:
361 l = self._asclist
361 l = self._asclist
362 s = repr(l)
362 s = repr(l)
363 return '<%s%s %s>' % (type(self).__name__, d, s)
363 return '<%s%s %s>' % (type(self).__name__, d, s)
364
364
365 class filteredset(abstractsmartset):
365 class filteredset(abstractsmartset):
366 """Duck type for baseset class which iterates lazily over the revisions in
366 """Duck type for baseset class which iterates lazily over the revisions in
367 the subset and contains a function which tests for membership in the
367 the subset and contains a function which tests for membership in the
368 revset
368 revset
369 """
369 """
370 def __init__(self, subset, condition=lambda x: True, condrepr=None):
370 def __init__(self, subset, condition=lambda x: True, condrepr=None):
371 """
371 """
372 condition: a function that decide whether a revision in the subset
372 condition: a function that decide whether a revision in the subset
373 belongs to the revset or not.
373 belongs to the revset or not.
374 condrepr: a tuple of (format, obj, ...), a function or an object that
374 condrepr: a tuple of (format, obj, ...), a function or an object that
375 provides a printable representation of the given condition.
375 provides a printable representation of the given condition.
376 """
376 """
377 self._subset = subset
377 self._subset = subset
378 self._condition = condition
378 self._condition = condition
379 self._condrepr = condrepr
379 self._condrepr = condrepr
380
380
381 def __contains__(self, x):
381 def __contains__(self, x):
382 return x in self._subset and self._condition(x)
382 return x in self._subset and self._condition(x)
383
383
384 def __iter__(self):
384 def __iter__(self):
385 return self._iterfilter(self._subset)
385 return self._iterfilter(self._subset)
386
386
387 def _iterfilter(self, it):
387 def _iterfilter(self, it):
388 cond = self._condition
388 cond = self._condition
389 for x in it:
389 for x in it:
390 if cond(x):
390 if cond(x):
391 yield x
391 yield x
392
392
393 @property
393 @property
394 def fastasc(self):
394 def fastasc(self):
395 it = self._subset.fastasc
395 it = self._subset.fastasc
396 if it is None:
396 if it is None:
397 return None
397 return None
398 return lambda: self._iterfilter(it())
398 return lambda: self._iterfilter(it())
399
399
400 @property
400 @property
401 def fastdesc(self):
401 def fastdesc(self):
402 it = self._subset.fastdesc
402 it = self._subset.fastdesc
403 if it is None:
403 if it is None:
404 return None
404 return None
405 return lambda: self._iterfilter(it())
405 return lambda: self._iterfilter(it())
406
406
407 def __nonzero__(self):
407 def __nonzero__(self):
408 fast = None
408 fast = None
409 candidates = [self.fastasc if self.isascending() else None,
409 candidates = [self.fastasc if self.isascending() else None,
410 self.fastdesc if self.isdescending() else None,
410 self.fastdesc if self.isdescending() else None,
411 self.fastasc,
411 self.fastasc,
412 self.fastdesc]
412 self.fastdesc]
413 for candidate in candidates:
413 for candidate in candidates:
414 if candidate is not None:
414 if candidate is not None:
415 fast = candidate
415 fast = candidate
416 break
416 break
417
417
418 if fast is not None:
418 if fast is not None:
419 it = fast()
419 it = fast()
420 else:
420 else:
421 it = self
421 it = self
422
422
423 for r in it:
423 for r in it:
424 return True
424 return True
425 return False
425 return False
426
426
427 __bool__ = __nonzero__
427 __bool__ = __nonzero__
428
428
429 def __len__(self):
429 def __len__(self):
430 # Basic implementation to be changed in future patches.
430 # Basic implementation to be changed in future patches.
431 # until this gets improved, we use generator expression
431 # until this gets improved, we use generator expression
432 # here, since list comprehensions are free to call __len__ again
432 # here, since list comprehensions are free to call __len__ again
433 # causing infinite recursion
433 # causing infinite recursion
434 l = baseset(r for r in self)
434 l = baseset(r for r in self)
435 return len(l)
435 return len(l)
436
436
437 def sort(self, reverse=False):
437 def sort(self, reverse=False):
438 self._subset.sort(reverse=reverse)
438 self._subset.sort(reverse=reverse)
439
439
440 def reverse(self):
440 def reverse(self):
441 self._subset.reverse()
441 self._subset.reverse()
442
442
443 def isascending(self):
443 def isascending(self):
444 return self._subset.isascending()
444 return self._subset.isascending()
445
445
446 def isdescending(self):
446 def isdescending(self):
447 return self._subset.isdescending()
447 return self._subset.isdescending()
448
448
449 def istopo(self):
449 def istopo(self):
450 return self._subset.istopo()
450 return self._subset.istopo()
451
451
452 def first(self):
452 def first(self):
453 for x in self:
453 for x in self:
454 return x
454 return x
455 return None
455 return None
456
456
457 def last(self):
457 def last(self):
458 it = None
458 it = None
459 if self.isascending():
459 if self.isascending():
460 it = self.fastdesc
460 it = self.fastdesc
461 elif self.isdescending():
461 elif self.isdescending():
462 it = self.fastasc
462 it = self.fastasc
463 if it is not None:
463 if it is not None:
464 for x in it():
464 for x in it():
465 return x
465 return x
466 return None #empty case
466 return None #empty case
467 else:
467 else:
468 x = None
468 x = None
469 for x in self:
469 for x in self:
470 pass
470 pass
471 return x
471 return x
472
472
473 def __repr__(self):
473 def __repr__(self):
474 xs = [repr(self._subset)]
474 xs = [repr(self._subset)]
475 s = _formatsetrepr(self._condrepr)
475 s = _formatsetrepr(self._condrepr)
476 if s:
476 if s:
477 xs.append(s)
477 xs.append(s)
478 return '<%s %s>' % (type(self).__name__, ', '.join(xs))
478 return '<%s %s>' % (type(self).__name__, ', '.join(xs))
479
479
480 def _iterordered(ascending, iter1, iter2):
480 def _iterordered(ascending, iter1, iter2):
481 """produce an ordered iteration from two iterators with the same order
481 """produce an ordered iteration from two iterators with the same order
482
482
483 The ascending is used to indicated the iteration direction.
483 The ascending is used to indicated the iteration direction.
484 """
484 """
485 choice = max
485 choice = max
486 if ascending:
486 if ascending:
487 choice = min
487 choice = min
488
488
489 val1 = None
489 val1 = None
490 val2 = None
490 val2 = None
491 try:
491 try:
492 # Consume both iterators in an ordered way until one is empty
492 # Consume both iterators in an ordered way until one is empty
493 while True:
493 while True:
494 if val1 is None:
494 if val1 is None:
495 val1 = next(iter1)
495 val1 = next(iter1)
496 if val2 is None:
496 if val2 is None:
497 val2 = next(iter2)
497 val2 = next(iter2)
498 n = choice(val1, val2)
498 n = choice(val1, val2)
499 yield n
499 yield n
500 if val1 == n:
500 if val1 == n:
501 val1 = None
501 val1 = None
502 if val2 == n:
502 if val2 == n:
503 val2 = None
503 val2 = None
504 except StopIteration:
504 except StopIteration:
505 # Flush any remaining values and consume the other one
505 # Flush any remaining values and consume the other one
506 it = iter2
506 it = iter2
507 if val1 is not None:
507 if val1 is not None:
508 yield val1
508 yield val1
509 it = iter1
509 it = iter1
510 elif val2 is not None:
510 elif val2 is not None:
511 # might have been equality and both are empty
511 # might have been equality and both are empty
512 yield val2
512 yield val2
513 for val in it:
513 for val in it:
514 yield val
514 yield val
515
515
516 class addset(abstractsmartset):
516 class addset(abstractsmartset):
517 """Represent the addition of two sets
517 """Represent the addition of two sets
518
518
519 Wrapper structure for lazily adding two structures without losing much
519 Wrapper structure for lazily adding two structures without losing much
520 performance on the __contains__ method
520 performance on the __contains__ method
521
521
522 If the ascending attribute is set, that means the two structures are
522 If the ascending attribute is set, that means the two structures are
523 ordered in either an ascending or descending way. Therefore, we can add
523 ordered in either an ascending or descending way. Therefore, we can add
524 them maintaining the order by iterating over both at the same time
524 them maintaining the order by iterating over both at the same time
525
525
526 >>> xs = baseset([0, 3, 2])
526 >>> xs = baseset([0, 3, 2])
527 >>> ys = baseset([5, 2, 4])
527 >>> ys = baseset([5, 2, 4])
528
528
529 >>> rs = addset(xs, ys)
529 >>> rs = addset(xs, ys)
530 >>> bool(rs), 0 in rs, 1 in rs, 5 in rs, rs.first(), rs.last()
530 >>> bool(rs), 0 in rs, 1 in rs, 5 in rs, rs.first(), rs.last()
531 (True, True, False, True, 0, 4)
531 (True, True, False, True, 0, 4)
532 >>> rs = addset(xs, baseset([]))
532 >>> rs = addset(xs, baseset([]))
533 >>> bool(rs), 0 in rs, 1 in rs, rs.first(), rs.last()
533 >>> bool(rs), 0 in rs, 1 in rs, rs.first(), rs.last()
534 (True, True, False, 0, 2)
534 (True, True, False, 0, 2)
535 >>> rs = addset(baseset([]), baseset([]))
535 >>> rs = addset(baseset([]), baseset([]))
536 >>> bool(rs), 0 in rs, rs.first(), rs.last()
536 >>> bool(rs), 0 in rs, rs.first(), rs.last()
537 (False, False, None, None)
537 (False, False, None, None)
538
538
539 iterate unsorted:
539 iterate unsorted:
540 >>> rs = addset(xs, ys)
540 >>> rs = addset(xs, ys)
541 >>> # (use generator because pypy could call len())
541 >>> # (use generator because pypy could call len())
542 >>> list(x for x in rs) # without _genlist
542 >>> list(x for x in rs) # without _genlist
543 [0, 3, 2, 5, 4]
543 [0, 3, 2, 5, 4]
544 >>> assert not rs._genlist
544 >>> assert not rs._genlist
545 >>> len(rs)
545 >>> len(rs)
546 5
546 5
547 >>> [x for x in rs] # with _genlist
547 >>> [x for x in rs] # with _genlist
548 [0, 3, 2, 5, 4]
548 [0, 3, 2, 5, 4]
549 >>> assert rs._genlist
549 >>> assert rs._genlist
550
550
551 iterate ascending:
551 iterate ascending:
552 >>> rs = addset(xs, ys, ascending=True)
552 >>> rs = addset(xs, ys, ascending=True)
553 >>> # (use generator because pypy could call len())
553 >>> # (use generator because pypy could call len())
554 >>> list(x for x in rs), list(x for x in rs.fastasc()) # without _asclist
554 >>> list(x for x in rs), list(x for x in rs.fastasc()) # without _asclist
555 ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
555 ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
556 >>> assert not rs._asclist
556 >>> assert not rs._asclist
557 >>> len(rs)
557 >>> len(rs)
558 5
558 5
559 >>> [x for x in rs], [x for x in rs.fastasc()]
559 >>> [x for x in rs], [x for x in rs.fastasc()]
560 ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
560 ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5])
561 >>> assert rs._asclist
561 >>> assert rs._asclist
562
562
563 iterate descending:
563 iterate descending:
564 >>> rs = addset(xs, ys, ascending=False)
564 >>> rs = addset(xs, ys, ascending=False)
565 >>> # (use generator because pypy could call len())
565 >>> # (use generator because pypy could call len())
566 >>> list(x for x in rs), list(x for x in rs.fastdesc()) # without _asclist
566 >>> list(x for x in rs), list(x for x in rs.fastdesc()) # without _asclist
567 ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
567 ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
568 >>> assert not rs._asclist
568 >>> assert not rs._asclist
569 >>> len(rs)
569 >>> len(rs)
570 5
570 5
571 >>> [x for x in rs], [x for x in rs.fastdesc()]
571 >>> [x for x in rs], [x for x in rs.fastdesc()]
572 ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
572 ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0])
573 >>> assert rs._asclist
573 >>> assert rs._asclist
574
574
575 iterate ascending without fastasc:
575 iterate ascending without fastasc:
576 >>> rs = addset(xs, generatorset(ys), ascending=True)
576 >>> rs = addset(xs, generatorset(ys), ascending=True)
577 >>> assert rs.fastasc is None
577 >>> assert rs.fastasc is None
578 >>> [x for x in rs]
578 >>> [x for x in rs]
579 [0, 2, 3, 4, 5]
579 [0, 2, 3, 4, 5]
580
580
581 iterate descending without fastdesc:
581 iterate descending without fastdesc:
582 >>> rs = addset(generatorset(xs), ys, ascending=False)
582 >>> rs = addset(generatorset(xs), ys, ascending=False)
583 >>> assert rs.fastdesc is None
583 >>> assert rs.fastdesc is None
584 >>> [x for x in rs]
584 >>> [x for x in rs]
585 [5, 4, 3, 2, 0]
585 [5, 4, 3, 2, 0]
586 """
586 """
587 def __init__(self, revs1, revs2, ascending=None):
587 def __init__(self, revs1, revs2, ascending=None):
588 self._r1 = revs1
588 self._r1 = revs1
589 self._r2 = revs2
589 self._r2 = revs2
590 self._iter = None
590 self._iter = None
591 self._ascending = ascending
591 self._ascending = ascending
592 self._genlist = None
592 self._genlist = None
593 self._asclist = None
593 self._asclist = None
594
594
595 def __len__(self):
595 def __len__(self):
596 return len(self._list)
596 return len(self._list)
597
597
598 def __nonzero__(self):
598 def __nonzero__(self):
599 return bool(self._r1) or bool(self._r2)
599 return bool(self._r1) or bool(self._r2)
600
600
601 __bool__ = __nonzero__
601 __bool__ = __nonzero__
602
602
603 @util.propertycache
603 @util.propertycache
604 def _list(self):
604 def _list(self):
605 if not self._genlist:
605 if not self._genlist:
606 self._genlist = baseset(iter(self))
606 self._genlist = baseset(iter(self))
607 return self._genlist
607 return self._genlist
608
608
609 def __iter__(self):
609 def __iter__(self):
610 """Iterate over both collections without repeating elements
610 """Iterate over both collections without repeating elements
611
611
612 If the ascending attribute is not set, iterate over the first one and
612 If the ascending attribute is not set, iterate over the first one and
613 then over the second one checking for membership on the first one so we
613 then over the second one checking for membership on the first one so we
614 dont yield any duplicates.
614 dont yield any duplicates.
615
615
616 If the ascending attribute is set, iterate over both collections at the
616 If the ascending attribute is set, iterate over both collections at the
617 same time, yielding only one value at a time in the given order.
617 same time, yielding only one value at a time in the given order.
618 """
618 """
619 if self._ascending is None:
619 if self._ascending is None:
620 if self._genlist:
620 if self._genlist:
621 return iter(self._genlist)
621 return iter(self._genlist)
622 def arbitraryordergen():
622 def arbitraryordergen():
623 for r in self._r1:
623 for r in self._r1:
624 yield r
624 yield r
625 inr1 = self._r1.__contains__
625 inr1 = self._r1.__contains__
626 for r in self._r2:
626 for r in self._r2:
627 if not inr1(r):
627 if not inr1(r):
628 yield r
628 yield r
629 return arbitraryordergen()
629 return arbitraryordergen()
630 # try to use our own fast iterator if it exists
630 # try to use our own fast iterator if it exists
631 self._trysetasclist()
631 self._trysetasclist()
632 if self._ascending:
632 if self._ascending:
633 attr = 'fastasc'
633 attr = 'fastasc'
634 else:
634 else:
635 attr = 'fastdesc'
635 attr = 'fastdesc'
636 it = getattr(self, attr)
636 it = getattr(self, attr)
637 if it is not None:
637 if it is not None:
638 return it()
638 return it()
639 # maybe half of the component supports fast
639 # maybe half of the component supports fast
640 # get iterator for _r1
640 # get iterator for _r1
641 iter1 = getattr(self._r1, attr)
641 iter1 = getattr(self._r1, attr)
642 if iter1 is None:
642 if iter1 is None:
643 # let's avoid side effect (not sure it matters)
643 # let's avoid side effect (not sure it matters)
644 iter1 = iter(sorted(self._r1, reverse=not self._ascending))
644 iter1 = iter(sorted(self._r1, reverse=not self._ascending))
645 else:
645 else:
646 iter1 = iter1()
646 iter1 = iter1()
647 # get iterator for _r2
647 # get iterator for _r2
648 iter2 = getattr(self._r2, attr)
648 iter2 = getattr(self._r2, attr)
649 if iter2 is None:
649 if iter2 is None:
650 # let's avoid side effect (not sure it matters)
650 # let's avoid side effect (not sure it matters)
651 iter2 = iter(sorted(self._r2, reverse=not self._ascending))
651 iter2 = iter(sorted(self._r2, reverse=not self._ascending))
652 else:
652 else:
653 iter2 = iter2()
653 iter2 = iter2()
654 return _iterordered(self._ascending, iter1, iter2)
654 return _iterordered(self._ascending, iter1, iter2)
655
655
656 def _trysetasclist(self):
656 def _trysetasclist(self):
657 """populate the _asclist attribute if possible and necessary"""
657 """populate the _asclist attribute if possible and necessary"""
658 if self._genlist is not None and self._asclist is None:
658 if self._genlist is not None and self._asclist is None:
659 self._asclist = sorted(self._genlist)
659 self._asclist = sorted(self._genlist)
660
660
661 @property
661 @property
662 def fastasc(self):
662 def fastasc(self):
663 self._trysetasclist()
663 self._trysetasclist()
664 if self._asclist is not None:
664 if self._asclist is not None:
665 return self._asclist.__iter__
665 return self._asclist.__iter__
666 iter1 = self._r1.fastasc
666 iter1 = self._r1.fastasc
667 iter2 = self._r2.fastasc
667 iter2 = self._r2.fastasc
668 if None in (iter1, iter2):
668 if None in (iter1, iter2):
669 return None
669 return None
670 return lambda: _iterordered(True, iter1(), iter2())
670 return lambda: _iterordered(True, iter1(), iter2())
671
671
672 @property
672 @property
673 def fastdesc(self):
673 def fastdesc(self):
674 self._trysetasclist()
674 self._trysetasclist()
675 if self._asclist is not None:
675 if self._asclist is not None:
676 return self._asclist.__reversed__
676 return self._asclist.__reversed__
677 iter1 = self._r1.fastdesc
677 iter1 = self._r1.fastdesc
678 iter2 = self._r2.fastdesc
678 iter2 = self._r2.fastdesc
679 if None in (iter1, iter2):
679 if None in (iter1, iter2):
680 return None
680 return None
681 return lambda: _iterordered(False, iter1(), iter2())
681 return lambda: _iterordered(False, iter1(), iter2())
682
682
683 def __contains__(self, x):
683 def __contains__(self, x):
684 return x in self._r1 or x in self._r2
684 return x in self._r1 or x in self._r2
685
685
686 def sort(self, reverse=False):
686 def sort(self, reverse=False):
687 """Sort the added set
687 """Sort the added set
688
688
689 For this we use the cached list with all the generated values and if we
689 For this we use the cached list with all the generated values and if we
690 know they are ascending or descending we can sort them in a smart way.
690 know they are ascending or descending we can sort them in a smart way.
691 """
691 """
692 self._ascending = not reverse
692 self._ascending = not reverse
693
693
694 def isascending(self):
694 def isascending(self):
695 return self._ascending is not None and self._ascending
695 return self._ascending is not None and self._ascending
696
696
697 def isdescending(self):
697 def isdescending(self):
698 return self._ascending is not None and not self._ascending
698 return self._ascending is not None and not self._ascending
699
699
700 def istopo(self):
700 def istopo(self):
701 # not worth the trouble asserting if the two sets combined are still
701 # not worth the trouble asserting if the two sets combined are still
702 # in topographical order. Use the sort() predicate to explicitly sort
702 # in topographical order. Use the sort() predicate to explicitly sort
703 # again instead.
703 # again instead.
704 return False
704 return False
705
705
706 def reverse(self):
706 def reverse(self):
707 if self._ascending is None:
707 if self._ascending is None:
708 self._list.reverse()
708 self._list.reverse()
709 else:
709 else:
710 self._ascending = not self._ascending
710 self._ascending = not self._ascending
711
711
712 def first(self):
712 def first(self):
713 for x in self:
713 for x in self:
714 return x
714 return x
715 return None
715 return None
716
716
717 def last(self):
717 def last(self):
718 self.reverse()
718 self.reverse()
719 val = self.first()
719 val = self.first()
720 self.reverse()
720 self.reverse()
721 return val
721 return val
722
722
723 def __repr__(self):
723 def __repr__(self):
724 d = {None: '', False: '-', True: '+'}[self._ascending]
724 d = {None: '', False: '-', True: '+'}[self._ascending]
725 return '<%s%s %r, %r>' % (type(self).__name__, d, self._r1, self._r2)
725 return '<%s%s %r, %r>' % (type(self).__name__, d, self._r1, self._r2)
726
726
727 class generatorset(abstractsmartset):
727 class generatorset(abstractsmartset):
728 """Wrap a generator for lazy iteration
728 """Wrap a generator for lazy iteration
729
729
730 Wrapper structure for generators that provides lazy membership and can
730 Wrapper structure for generators that provides lazy membership and can
731 be iterated more than once.
731 be iterated more than once.
732 When asked for membership it generates values until either it finds the
732 When asked for membership it generates values until either it finds the
733 requested one or has gone through all the elements in the generator
733 requested one or has gone through all the elements in the generator
734 """
734 """
735 def __init__(self, gen, iterasc=None):
735 def __init__(self, gen, iterasc=None):
736 """
736 """
737 gen: a generator producing the values for the generatorset.
737 gen: a generator producing the values for the generatorset.
738 """
738 """
739 self._gen = gen
739 self._gen = gen
740 self._asclist = None
740 self._asclist = None
741 self._cache = {}
741 self._cache = {}
742 self._genlist = []
742 self._genlist = []
743 self._finished = False
743 self._finished = False
744 self._ascending = True
744 self._ascending = True
745 if iterasc is not None:
745 if iterasc is not None:
746 if iterasc:
746 if iterasc:
747 self.fastasc = self._iterator
747 self.fastasc = self._iterator
748 self.__contains__ = self._asccontains
748 self.__contains__ = self._asccontains
749 else:
749 else:
750 self.fastdesc = self._iterator
750 self.fastdesc = self._iterator
751 self.__contains__ = self._desccontains
751 self.__contains__ = self._desccontains
752
752
753 def __nonzero__(self):
753 def __nonzero__(self):
754 # Do not use 'for r in self' because it will enforce the iteration
754 # Do not use 'for r in self' because it will enforce the iteration
755 # order (default ascending), possibly unrolling a whole descending
755 # order (default ascending), possibly unrolling a whole descending
756 # iterator.
756 # iterator.
757 if self._genlist:
757 if self._genlist:
758 return True
758 return True
759 for r in self._consumegen():
759 for r in self._consumegen():
760 return True
760 return True
761 return False
761 return False
762
762
763 __bool__ = __nonzero__
763 __bool__ = __nonzero__
764
764
765 def __contains__(self, x):
765 def __contains__(self, x):
766 if x in self._cache:
766 if x in self._cache:
767 return self._cache[x]
767 return self._cache[x]
768
768
769 # Use new values only, as existing values would be cached.
769 # Use new values only, as existing values would be cached.
770 for l in self._consumegen():
770 for l in self._consumegen():
771 if l == x:
771 if l == x:
772 return True
772 return True
773
773
774 self._cache[x] = False
774 self._cache[x] = False
775 return False
775 return False
776
776
777 def _asccontains(self, x):
777 def _asccontains(self, x):
778 """version of contains optimised for ascending generator"""
778 """version of contains optimised for ascending generator"""
779 if x in self._cache:
779 if x in self._cache:
780 return self._cache[x]
780 return self._cache[x]
781
781
782 # Use new values only, as existing values would be cached.
782 # Use new values only, as existing values would be cached.
783 for l in self._consumegen():
783 for l in self._consumegen():
784 if l == x:
784 if l == x:
785 return True
785 return True
786 if l > x:
786 if l > x:
787 break
787 break
788
788
789 self._cache[x] = False
789 self._cache[x] = False
790 return False
790 return False
791
791
792 def _desccontains(self, x):
792 def _desccontains(self, x):
793 """version of contains optimised for descending generator"""
793 """version of contains optimised for descending generator"""
794 if x in self._cache:
794 if x in self._cache:
795 return self._cache[x]
795 return self._cache[x]
796
796
797 # Use new values only, as existing values would be cached.
797 # Use new values only, as existing values would be cached.
798 for l in self._consumegen():
798 for l in self._consumegen():
799 if l == x:
799 if l == x:
800 return True
800 return True
801 if l < x:
801 if l < x:
802 break
802 break
803
803
804 self._cache[x] = False
804 self._cache[x] = False
805 return False
805 return False
806
806
807 def __iter__(self):
807 def __iter__(self):
808 if self._ascending:
808 if self._ascending:
809 it = self.fastasc
809 it = self.fastasc
810 else:
810 else:
811 it = self.fastdesc
811 it = self.fastdesc
812 if it is not None:
812 if it is not None:
813 return it()
813 return it()
814 # we need to consume the iterator
814 # we need to consume the iterator
815 for x in self._consumegen():
815 for x in self._consumegen():
816 pass
816 pass
817 # recall the same code
817 # recall the same code
818 return iter(self)
818 return iter(self)
819
819
820 def _iterator(self):
820 def _iterator(self):
821 if self._finished:
821 if self._finished:
822 return iter(self._genlist)
822 return iter(self._genlist)
823
823
824 # We have to use this complex iteration strategy to allow multiple
824 # We have to use this complex iteration strategy to allow multiple
825 # iterations at the same time. We need to be able to catch revision
825 # iterations at the same time. We need to be able to catch revision
826 # removed from _consumegen and added to genlist in another instance.
826 # removed from _consumegen and added to genlist in another instance.
827 #
827 #
828 # Getting rid of it would provide an about 15% speed up on this
828 # Getting rid of it would provide an about 15% speed up on this
829 # iteration.
829 # iteration.
830 genlist = self._genlist
830 genlist = self._genlist
831 nextgen = self._consumegen()
831 nextgen = self._consumegen()
832 _len, _next = len, next # cache global lookup
832 _len, _next = len, next # cache global lookup
833 def gen():
833 def gen():
834 i = 0
834 i = 0
835 while True:
835 while True:
836 if i < _len(genlist):
836 if i < _len(genlist):
837 yield genlist[i]
837 yield genlist[i]
838 else:
838 else:
839 yield _next(nextgen)
839 yield _next(nextgen)
840 i += 1
840 i += 1
841 return gen()
841 return gen()
842
842
843 def _consumegen(self):
843 def _consumegen(self):
844 cache = self._cache
844 cache = self._cache
845 genlist = self._genlist.append
845 genlist = self._genlist.append
846 for item in self._gen:
846 for item in self._gen:
847 cache[item] = True
847 cache[item] = True
848 genlist(item)
848 genlist(item)
849 yield item
849 yield item
850 if not self._finished:
850 if not self._finished:
851 self._finished = True
851 self._finished = True
852 asc = self._genlist[:]
852 asc = self._genlist[:]
853 asc.sort()
853 asc.sort()
854 self._asclist = asc
854 self._asclist = asc
855 self.fastasc = asc.__iter__
855 self.fastasc = asc.__iter__
856 self.fastdesc = asc.__reversed__
856 self.fastdesc = asc.__reversed__
857
857
858 def __len__(self):
858 def __len__(self):
859 for x in self._consumegen():
859 for x in self._consumegen():
860 pass
860 pass
861 return len(self._genlist)
861 return len(self._genlist)
862
862
863 def sort(self, reverse=False):
863 def sort(self, reverse=False):
864 self._ascending = not reverse
864 self._ascending = not reverse
865
865
866 def reverse(self):
866 def reverse(self):
867 self._ascending = not self._ascending
867 self._ascending = not self._ascending
868
868
869 def isascending(self):
869 def isascending(self):
870 return self._ascending
870 return self._ascending
871
871
872 def isdescending(self):
872 def isdescending(self):
873 return not self._ascending
873 return not self._ascending
874
874
875 def istopo(self):
875 def istopo(self):
876 # not worth the trouble asserting if the two sets combined are still
876 # not worth the trouble asserting if the two sets combined are still
877 # in topographical order. Use the sort() predicate to explicitly sort
877 # in topographical order. Use the sort() predicate to explicitly sort
878 # again instead.
878 # again instead.
879 return False
879 return False
880
880
881 def first(self):
881 def first(self):
882 if self._ascending:
882 if self._ascending:
883 it = self.fastasc
883 it = self.fastasc
884 else:
884 else:
885 it = self.fastdesc
885 it = self.fastdesc
886 if it is None:
886 if it is None:
887 # we need to consume all and try again
887 # we need to consume all and try again
888 for x in self._consumegen():
888 for x in self._consumegen():
889 pass
889 pass
890 return self.first()
890 return self.first()
891 return next(it(), None)
891 return next(it(), None)
892
892
893 def last(self):
893 def last(self):
894 if self._ascending:
894 if self._ascending:
895 it = self.fastdesc
895 it = self.fastdesc
896 else:
896 else:
897 it = self.fastasc
897 it = self.fastasc
898 if it is None:
898 if it is None:
899 # we need to consume all and try again
899 # we need to consume all and try again
900 for x in self._consumegen():
900 for x in self._consumegen():
901 pass
901 pass
902 return self.first()
902 return self.first()
903 return next(it(), None)
903 return next(it(), None)
904
904
905 def __repr__(self):
905 def __repr__(self):
906 d = {False: '-', True: '+'}[self._ascending]
906 d = {False: '-', True: '+'}[self._ascending]
907 return '<%s%s>' % (type(self).__name__, d)
907 return '<%s%s>' % (type(self).__name__, d)
908
908
909 class spanset(abstractsmartset):
909 class spanset(abstractsmartset):
910 """Duck type for baseset class which represents a range of revisions and
910 """Duck type for baseset class which represents a range of revisions and
911 can work lazily and without having all the range in memory
911 can work lazily and without having all the range in memory
912
912
913 Note that spanset(x, y) behave almost like xrange(x, y) except for two
913 Note that spanset(x, y) behave almost like xrange(x, y) except for two
914 notable points:
914 notable points:
915 - when x < y it will be automatically descending,
915 - when x < y it will be automatically descending,
916 - revision filtered with this repoview will be skipped.
916 - revision filtered with this repoview will be skipped.
917
917
918 """
918 """
919 def __init__(self, repo, start=0, end=None):
919 def __init__(self, repo, start=0, end=None):
920 """
920 """
921 start: first revision included the set
921 start: first revision included the set
922 (default to 0)
922 (default to 0)
923 end: first revision excluded (last+1)
923 end: first revision excluded (last+1)
924 (default to len(repo)
924 (default to len(repo)
925
925
926 Spanset will be descending if `end` < `start`.
926 Spanset will be descending if `end` < `start`.
927 """
927 """
928 if end is None:
928 if end is None:
929 end = len(repo)
929 end = len(repo)
930 self._ascending = start <= end
930 self._ascending = start <= end
931 if not self._ascending:
931 if not self._ascending:
932 start, end = end + 1, start +1
932 start, end = end + 1, start +1
933 self._start = start
933 self._start = start
934 self._end = end
934 self._end = end
935 self._hiddenrevs = repo.changelog.filteredrevs
935 self._hiddenrevs = repo.changelog.filteredrevs
936
936
937 def sort(self, reverse=False):
937 def sort(self, reverse=False):
938 self._ascending = not reverse
938 self._ascending = not reverse
939
939
940 def reverse(self):
940 def reverse(self):
941 self._ascending = not self._ascending
941 self._ascending = not self._ascending
942
942
943 def istopo(self):
943 def istopo(self):
944 # not worth the trouble asserting if the two sets combined are still
944 # not worth the trouble asserting if the two sets combined are still
945 # in topographical order. Use the sort() predicate to explicitly sort
945 # in topographical order. Use the sort() predicate to explicitly sort
946 # again instead.
946 # again instead.
947 return False
947 return False
948
948
949 def _iterfilter(self, iterrange):
949 def _iterfilter(self, iterrange):
950 s = self._hiddenrevs
950 s = self._hiddenrevs
951 for r in iterrange:
951 for r in iterrange:
952 if r not in s:
952 if r not in s:
953 yield r
953 yield r
954
954
955 def __iter__(self):
955 def __iter__(self):
956 if self._ascending:
956 if self._ascending:
957 return self.fastasc()
957 return self.fastasc()
958 else:
958 else:
959 return self.fastdesc()
959 return self.fastdesc()
960
960
961 def fastasc(self):
961 def fastasc(self):
962 iterrange = xrange(self._start, self._end)
962 iterrange = xrange(self._start, self._end)
963 if self._hiddenrevs:
963 if self._hiddenrevs:
964 return self._iterfilter(iterrange)
964 return self._iterfilter(iterrange)
965 return iter(iterrange)
965 return iter(iterrange)
966
966
967 def fastdesc(self):
967 def fastdesc(self):
968 iterrange = xrange(self._end - 1, self._start - 1, -1)
968 iterrange = xrange(self._end - 1, self._start - 1, -1)
969 if self._hiddenrevs:
969 if self._hiddenrevs:
970 return self._iterfilter(iterrange)
970 return self._iterfilter(iterrange)
971 return iter(iterrange)
971 return iter(iterrange)
972
972
973 def __contains__(self, rev):
973 def __contains__(self, rev):
974 hidden = self._hiddenrevs
974 hidden = self._hiddenrevs
975 return ((self._start <= rev < self._end)
975 return ((self._start <= rev < self._end)
976 and not (hidden and rev in hidden))
976 and not (hidden and rev in hidden))
977
977
978 def __nonzero__(self):
978 def __nonzero__(self):
979 for r in self:
979 for r in self:
980 return True
980 return True
981 return False
981 return False
982
982
983 __bool__ = __nonzero__
983 __bool__ = __nonzero__
984
984
985 def __len__(self):
985 def __len__(self):
986 if not self._hiddenrevs:
986 if not self._hiddenrevs:
987 return abs(self._end - self._start)
987 return abs(self._end - self._start)
988 else:
988 else:
989 count = 0
989 count = 0
990 start = self._start
990 start = self._start
991 end = self._end
991 end = self._end
992 for rev in self._hiddenrevs:
992 for rev in self._hiddenrevs:
993 if (end < rev <= start) or (start <= rev < end):
993 if (end < rev <= start) or (start <= rev < end):
994 count += 1
994 count += 1
995 return abs(self._end - self._start) - count
995 return abs(self._end - self._start) - count
996
996
997 def isascending(self):
997 def isascending(self):
998 return self._ascending
998 return self._ascending
999
999
1000 def isdescending(self):
1000 def isdescending(self):
1001 return not self._ascending
1001 return not self._ascending
1002
1002
1003 def first(self):
1003 def first(self):
1004 if self._ascending:
1004 if self._ascending:
1005 it = self.fastasc
1005 it = self.fastasc
1006 else:
1006 else:
1007 it = self.fastdesc
1007 it = self.fastdesc
1008 for x in it():
1008 for x in it():
1009 return x
1009 return x
1010 return None
1010 return None
1011
1011
1012 def last(self):
1012 def last(self):
1013 if self._ascending:
1013 if self._ascending:
1014 it = self.fastdesc
1014 it = self.fastdesc
1015 else:
1015 else:
1016 it = self.fastasc
1016 it = self.fastasc
1017 for x in it():
1017 for x in it():
1018 return x
1018 return x
1019 return None
1019 return None
1020
1020
1021 def __repr__(self):
1021 def __repr__(self):
1022 d = {False: '-', True: '+'}[self._ascending]
1022 d = {False: '-', True: '+'}[self._ascending]
1023 return '<%s%s %d:%d>' % (type(self).__name__, d,
1023 return '<%s%s %d:%d>' % (type(self).__name__, d,
1024 self._start, self._end - 1)
1024 self._start, self._end)
1025
1025
1026 class fullreposet(spanset):
1026 class fullreposet(spanset):
1027 """a set containing all revisions in the repo
1027 """a set containing all revisions in the repo
1028
1028
1029 This class exists to host special optimization and magic to handle virtual
1029 This class exists to host special optimization and magic to handle virtual
1030 revisions such as "null".
1030 revisions such as "null".
1031 """
1031 """
1032
1032
1033 def __init__(self, repo):
1033 def __init__(self, repo):
1034 super(fullreposet, self).__init__(repo)
1034 super(fullreposet, self).__init__(repo)
1035
1035
1036 def __and__(self, other):
1036 def __and__(self, other):
1037 """As self contains the whole repo, all of the other set should also be
1037 """As self contains the whole repo, all of the other set should also be
1038 in self. Therefore `self & other = other`.
1038 in self. Therefore `self & other = other`.
1039
1039
1040 This boldly assumes the other contains valid revs only.
1040 This boldly assumes the other contains valid revs only.
1041 """
1041 """
1042 # other not a smartset, make is so
1042 # other not a smartset, make is so
1043 if not util.safehasattr(other, 'isascending'):
1043 if not util.safehasattr(other, 'isascending'):
1044 # filter out hidden revision
1044 # filter out hidden revision
1045 # (this boldly assumes all smartset are pure)
1045 # (this boldly assumes all smartset are pure)
1046 #
1046 #
1047 # `other` was used with "&", let's assume this is a set like
1047 # `other` was used with "&", let's assume this is a set like
1048 # object.
1048 # object.
1049 other = baseset(other - self._hiddenrevs)
1049 other = baseset(other - self._hiddenrevs)
1050
1050
1051 other.sort(reverse=self.isdescending())
1051 other.sort(reverse=self.isdescending())
1052 return other
1052 return other
1053
1053
1054 def prettyformat(revs):
1054 def prettyformat(revs):
1055 lines = []
1055 lines = []
1056 rs = repr(revs)
1056 rs = repr(revs)
1057 p = 0
1057 p = 0
1058 while p < len(rs):
1058 while p < len(rs):
1059 q = rs.find('<', p + 1)
1059 q = rs.find('<', p + 1)
1060 if q < 0:
1060 if q < 0:
1061 q = len(rs)
1061 q = len(rs)
1062 l = rs.count('<', 0, p) - rs.count('>', 0, p)
1062 l = rs.count('<', 0, p) - rs.count('>', 0, p)
1063 assert l >= 0
1063 assert l >= 0
1064 lines.append((l, rs[p:q].rstrip()))
1064 lines.append((l, rs[p:q].rstrip()))
1065 p = q
1065 p = q
1066 return '\n'.join(' ' * l + s for l, s in lines)
1066 return '\n'.join(' ' * l + s for l, s in lines)
@@ -1,3922 +1,3922 b''
1 $ HGENCODING=utf-8
1 $ HGENCODING=utf-8
2 $ export HGENCODING
2 $ export HGENCODING
3 $ cat > testrevset.py << EOF
3 $ cat > testrevset.py << EOF
4 > import mercurial.revset
4 > import mercurial.revset
5 >
5 >
6 > baseset = mercurial.revset.baseset
6 > baseset = mercurial.revset.baseset
7 >
7 >
8 > def r3232(repo, subset, x):
8 > def r3232(repo, subset, x):
9 > """"simple revset that return [3,2,3,2]
9 > """"simple revset that return [3,2,3,2]
10 >
10 >
11 > revisions duplicated on purpose.
11 > revisions duplicated on purpose.
12 > """
12 > """
13 > if 3 not in subset:
13 > if 3 not in subset:
14 > if 2 in subset:
14 > if 2 in subset:
15 > return baseset([2,2])
15 > return baseset([2,2])
16 > return baseset()
16 > return baseset()
17 > return baseset([3,3,2,2])
17 > return baseset([3,3,2,2])
18 >
18 >
19 > mercurial.revset.symbols['r3232'] = r3232
19 > mercurial.revset.symbols['r3232'] = r3232
20 > EOF
20 > EOF
21 $ cat >> $HGRCPATH << EOF
21 $ cat >> $HGRCPATH << EOF
22 > [extensions]
22 > [extensions]
23 > testrevset=$TESTTMP/testrevset.py
23 > testrevset=$TESTTMP/testrevset.py
24 > EOF
24 > EOF
25
25
26 $ try() {
26 $ try() {
27 > hg debugrevspec --debug "$@"
27 > hg debugrevspec --debug "$@"
28 > }
28 > }
29
29
30 $ log() {
30 $ log() {
31 > hg log --template '{rev}\n' -r "$1"
31 > hg log --template '{rev}\n' -r "$1"
32 > }
32 > }
33
33
34 extension to build '_intlist()' and '_hexlist()', which is necessary because
34 extension to build '_intlist()' and '_hexlist()', which is necessary because
35 these predicates use '\0' as a separator:
35 these predicates use '\0' as a separator:
36
36
37 $ cat <<EOF > debugrevlistspec.py
37 $ cat <<EOF > debugrevlistspec.py
38 > from __future__ import absolute_import
38 > from __future__ import absolute_import
39 > from mercurial import (
39 > from mercurial import (
40 > node as nodemod,
40 > node as nodemod,
41 > registrar,
41 > registrar,
42 > revset,
42 > revset,
43 > revsetlang,
43 > revsetlang,
44 > smartset,
44 > smartset,
45 > )
45 > )
46 > cmdtable = {}
46 > cmdtable = {}
47 > command = registrar.command(cmdtable)
47 > command = registrar.command(cmdtable)
48 > @command('debugrevlistspec',
48 > @command('debugrevlistspec',
49 > [('', 'optimize', None, 'print parsed tree after optimizing'),
49 > [('', 'optimize', None, 'print parsed tree after optimizing'),
50 > ('', 'bin', None, 'unhexlify arguments')])
50 > ('', 'bin', None, 'unhexlify arguments')])
51 > def debugrevlistspec(ui, repo, fmt, *args, **opts):
51 > def debugrevlistspec(ui, repo, fmt, *args, **opts):
52 > if opts['bin']:
52 > if opts['bin']:
53 > args = map(nodemod.bin, args)
53 > args = map(nodemod.bin, args)
54 > expr = revsetlang.formatspec(fmt, list(args))
54 > expr = revsetlang.formatspec(fmt, list(args))
55 > if ui.verbose:
55 > if ui.verbose:
56 > tree = revsetlang.parse(expr, lookup=repo.__contains__)
56 > tree = revsetlang.parse(expr, lookup=repo.__contains__)
57 > ui.note(revsetlang.prettyformat(tree), "\n")
57 > ui.note(revsetlang.prettyformat(tree), "\n")
58 > if opts["optimize"]:
58 > if opts["optimize"]:
59 > opttree = revsetlang.optimize(revsetlang.analyze(tree))
59 > opttree = revsetlang.optimize(revsetlang.analyze(tree))
60 > ui.note("* optimized:\n", revsetlang.prettyformat(opttree),
60 > ui.note("* optimized:\n", revsetlang.prettyformat(opttree),
61 > "\n")
61 > "\n")
62 > func = revset.match(ui, expr, repo)
62 > func = revset.match(ui, expr, repo)
63 > revs = func(repo)
63 > revs = func(repo)
64 > if ui.verbose:
64 > if ui.verbose:
65 > ui.note("* set:\n", smartset.prettyformat(revs), "\n")
65 > ui.note("* set:\n", smartset.prettyformat(revs), "\n")
66 > for c in revs:
66 > for c in revs:
67 > ui.write("%s\n" % c)
67 > ui.write("%s\n" % c)
68 > EOF
68 > EOF
69 $ cat <<EOF >> $HGRCPATH
69 $ cat <<EOF >> $HGRCPATH
70 > [extensions]
70 > [extensions]
71 > debugrevlistspec = $TESTTMP/debugrevlistspec.py
71 > debugrevlistspec = $TESTTMP/debugrevlistspec.py
72 > EOF
72 > EOF
73 $ trylist() {
73 $ trylist() {
74 > hg debugrevlistspec --debug "$@"
74 > hg debugrevlistspec --debug "$@"
75 > }
75 > }
76
76
77 $ hg init repo
77 $ hg init repo
78 $ cd repo
78 $ cd repo
79
79
80 $ echo a > a
80 $ echo a > a
81 $ hg branch a
81 $ hg branch a
82 marked working directory as branch a
82 marked working directory as branch a
83 (branches are permanent and global, did you want a bookmark?)
83 (branches are permanent and global, did you want a bookmark?)
84 $ hg ci -Aqm0
84 $ hg ci -Aqm0
85
85
86 $ echo b > b
86 $ echo b > b
87 $ hg branch b
87 $ hg branch b
88 marked working directory as branch b
88 marked working directory as branch b
89 $ hg ci -Aqm1
89 $ hg ci -Aqm1
90
90
91 $ rm a
91 $ rm a
92 $ hg branch a-b-c-
92 $ hg branch a-b-c-
93 marked working directory as branch a-b-c-
93 marked working directory as branch a-b-c-
94 $ hg ci -Aqm2 -u Bob
94 $ hg ci -Aqm2 -u Bob
95
95
96 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
96 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
97 2
97 2
98 $ hg log -r "extra('branch')" --template '{rev}\n'
98 $ hg log -r "extra('branch')" --template '{rev}\n'
99 0
99 0
100 1
100 1
101 2
101 2
102 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
102 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
103 0 a
103 0 a
104 2 a-b-c-
104 2 a-b-c-
105
105
106 $ hg co 1
106 $ hg co 1
107 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
107 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 $ hg branch +a+b+c+
108 $ hg branch +a+b+c+
109 marked working directory as branch +a+b+c+
109 marked working directory as branch +a+b+c+
110 $ hg ci -Aqm3
110 $ hg ci -Aqm3
111
111
112 $ hg co 2 # interleave
112 $ hg co 2 # interleave
113 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
113 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
114 $ echo bb > b
114 $ echo bb > b
115 $ hg branch -- -a-b-c-
115 $ hg branch -- -a-b-c-
116 marked working directory as branch -a-b-c-
116 marked working directory as branch -a-b-c-
117 $ hg ci -Aqm4 -d "May 12 2005"
117 $ hg ci -Aqm4 -d "May 12 2005"
118
118
119 $ hg co 3
119 $ hg co 3
120 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
120 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 $ hg branch !a/b/c/
121 $ hg branch !a/b/c/
122 marked working directory as branch !a/b/c/
122 marked working directory as branch !a/b/c/
123 $ hg ci -Aqm"5 bug"
123 $ hg ci -Aqm"5 bug"
124
124
125 $ hg merge 4
125 $ hg merge 4
126 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
126 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
127 (branch merge, don't forget to commit)
127 (branch merge, don't forget to commit)
128 $ hg branch _a_b_c_
128 $ hg branch _a_b_c_
129 marked working directory as branch _a_b_c_
129 marked working directory as branch _a_b_c_
130 $ hg ci -Aqm"6 issue619"
130 $ hg ci -Aqm"6 issue619"
131
131
132 $ hg branch .a.b.c.
132 $ hg branch .a.b.c.
133 marked working directory as branch .a.b.c.
133 marked working directory as branch .a.b.c.
134 $ hg ci -Aqm7
134 $ hg ci -Aqm7
135
135
136 $ hg branch all
136 $ hg branch all
137 marked working directory as branch all
137 marked working directory as branch all
138
138
139 $ hg co 4
139 $ hg co 4
140 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
140 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 $ hg branch Γ©
141 $ hg branch Γ©
142 marked working directory as branch \xc3\xa9 (esc)
142 marked working directory as branch \xc3\xa9 (esc)
143 $ hg ci -Aqm9
143 $ hg ci -Aqm9
144
144
145 $ hg tag -r6 1.0
145 $ hg tag -r6 1.0
146 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
146 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
147
147
148 $ hg clone --quiet -U -r 7 . ../remote1
148 $ hg clone --quiet -U -r 7 . ../remote1
149 $ hg clone --quiet -U -r 8 . ../remote2
149 $ hg clone --quiet -U -r 8 . ../remote2
150 $ echo "[paths]" >> .hg/hgrc
150 $ echo "[paths]" >> .hg/hgrc
151 $ echo "default = ../remote1" >> .hg/hgrc
151 $ echo "default = ../remote1" >> .hg/hgrc
152
152
153 trivial
153 trivial
154
154
155 $ try 0:1
155 $ try 0:1
156 (range
156 (range
157 ('symbol', '0')
157 ('symbol', '0')
158 ('symbol', '1'))
158 ('symbol', '1'))
159 * set:
159 * set:
160 <spanset+ 0:1>
160 <spanset+ 0:2>
161 0
161 0
162 1
162 1
163 $ try --optimize :
163 $ try --optimize :
164 (rangeall
164 (rangeall
165 None)
165 None)
166 * optimized:
166 * optimized:
167 (rangeall
167 (rangeall
168 None
168 None
169 define)
169 define)
170 * set:
170 * set:
171 <spanset+ 0:9>
171 <spanset+ 0:10>
172 0
172 0
173 1
173 1
174 2
174 2
175 3
175 3
176 4
176 4
177 5
177 5
178 6
178 6
179 7
179 7
180 8
180 8
181 9
181 9
182 $ try 3::6
182 $ try 3::6
183 (dagrange
183 (dagrange
184 ('symbol', '3')
184 ('symbol', '3')
185 ('symbol', '6'))
185 ('symbol', '6'))
186 * set:
186 * set:
187 <baseset+ [3, 5, 6]>
187 <baseset+ [3, 5, 6]>
188 3
188 3
189 5
189 5
190 6
190 6
191 $ try '0|1|2'
191 $ try '0|1|2'
192 (or
192 (or
193 (list
193 (list
194 ('symbol', '0')
194 ('symbol', '0')
195 ('symbol', '1')
195 ('symbol', '1')
196 ('symbol', '2')))
196 ('symbol', '2')))
197 * set:
197 * set:
198 <baseset [0, 1, 2]>
198 <baseset [0, 1, 2]>
199 0
199 0
200 1
200 1
201 2
201 2
202
202
203 names that should work without quoting
203 names that should work without quoting
204
204
205 $ try a
205 $ try a
206 ('symbol', 'a')
206 ('symbol', 'a')
207 * set:
207 * set:
208 <baseset [0]>
208 <baseset [0]>
209 0
209 0
210 $ try b-a
210 $ try b-a
211 (minus
211 (minus
212 ('symbol', 'b')
212 ('symbol', 'b')
213 ('symbol', 'a'))
213 ('symbol', 'a'))
214 * set:
214 * set:
215 <filteredset
215 <filteredset
216 <baseset [1]>,
216 <baseset [1]>,
217 <not
217 <not
218 <baseset [0]>>>
218 <baseset [0]>>>
219 1
219 1
220 $ try _a_b_c_
220 $ try _a_b_c_
221 ('symbol', '_a_b_c_')
221 ('symbol', '_a_b_c_')
222 * set:
222 * set:
223 <baseset [6]>
223 <baseset [6]>
224 6
224 6
225 $ try _a_b_c_-a
225 $ try _a_b_c_-a
226 (minus
226 (minus
227 ('symbol', '_a_b_c_')
227 ('symbol', '_a_b_c_')
228 ('symbol', 'a'))
228 ('symbol', 'a'))
229 * set:
229 * set:
230 <filteredset
230 <filteredset
231 <baseset [6]>,
231 <baseset [6]>,
232 <not
232 <not
233 <baseset [0]>>>
233 <baseset [0]>>>
234 6
234 6
235 $ try .a.b.c.
235 $ try .a.b.c.
236 ('symbol', '.a.b.c.')
236 ('symbol', '.a.b.c.')
237 * set:
237 * set:
238 <baseset [7]>
238 <baseset [7]>
239 7
239 7
240 $ try .a.b.c.-a
240 $ try .a.b.c.-a
241 (minus
241 (minus
242 ('symbol', '.a.b.c.')
242 ('symbol', '.a.b.c.')
243 ('symbol', 'a'))
243 ('symbol', 'a'))
244 * set:
244 * set:
245 <filteredset
245 <filteredset
246 <baseset [7]>,
246 <baseset [7]>,
247 <not
247 <not
248 <baseset [0]>>>
248 <baseset [0]>>>
249 7
249 7
250
250
251 names that should be caught by fallback mechanism
251 names that should be caught by fallback mechanism
252
252
253 $ try -- '-a-b-c-'
253 $ try -- '-a-b-c-'
254 ('symbol', '-a-b-c-')
254 ('symbol', '-a-b-c-')
255 * set:
255 * set:
256 <baseset [4]>
256 <baseset [4]>
257 4
257 4
258 $ log -a-b-c-
258 $ log -a-b-c-
259 4
259 4
260 $ try '+a+b+c+'
260 $ try '+a+b+c+'
261 ('symbol', '+a+b+c+')
261 ('symbol', '+a+b+c+')
262 * set:
262 * set:
263 <baseset [3]>
263 <baseset [3]>
264 3
264 3
265 $ try '+a+b+c+:'
265 $ try '+a+b+c+:'
266 (rangepost
266 (rangepost
267 ('symbol', '+a+b+c+'))
267 ('symbol', '+a+b+c+'))
268 * set:
268 * set:
269 <spanset+ 3:9>
269 <spanset+ 3:10>
270 3
270 3
271 4
271 4
272 5
272 5
273 6
273 6
274 7
274 7
275 8
275 8
276 9
276 9
277 $ try ':+a+b+c+'
277 $ try ':+a+b+c+'
278 (rangepre
278 (rangepre
279 ('symbol', '+a+b+c+'))
279 ('symbol', '+a+b+c+'))
280 * set:
280 * set:
281 <spanset+ 0:3>
281 <spanset+ 0:4>
282 0
282 0
283 1
283 1
284 2
284 2
285 3
285 3
286 $ try -- '-a-b-c-:+a+b+c+'
286 $ try -- '-a-b-c-:+a+b+c+'
287 (range
287 (range
288 ('symbol', '-a-b-c-')
288 ('symbol', '-a-b-c-')
289 ('symbol', '+a+b+c+'))
289 ('symbol', '+a+b+c+'))
290 * set:
290 * set:
291 <spanset- 3:4>
291 <spanset- 3:5>
292 4
292 4
293 3
293 3
294 $ log '-a-b-c-:+a+b+c+'
294 $ log '-a-b-c-:+a+b+c+'
295 4
295 4
296 3
296 3
297
297
298 $ try -- -a-b-c--a # complains
298 $ try -- -a-b-c--a # complains
299 (minus
299 (minus
300 (minus
300 (minus
301 (minus
301 (minus
302 (negate
302 (negate
303 ('symbol', 'a'))
303 ('symbol', 'a'))
304 ('symbol', 'b'))
304 ('symbol', 'b'))
305 ('symbol', 'c'))
305 ('symbol', 'c'))
306 (negate
306 (negate
307 ('symbol', 'a')))
307 ('symbol', 'a')))
308 abort: unknown revision '-a'!
308 abort: unknown revision '-a'!
309 [255]
309 [255]
310 $ try Γ©
310 $ try Γ©
311 ('symbol', '\xc3\xa9')
311 ('symbol', '\xc3\xa9')
312 * set:
312 * set:
313 <baseset [9]>
313 <baseset [9]>
314 9
314 9
315
315
316 no quoting needed
316 no quoting needed
317
317
318 $ log ::a-b-c-
318 $ log ::a-b-c-
319 0
319 0
320 1
320 1
321 2
321 2
322
322
323 quoting needed
323 quoting needed
324
324
325 $ try '"-a-b-c-"-a'
325 $ try '"-a-b-c-"-a'
326 (minus
326 (minus
327 ('string', '-a-b-c-')
327 ('string', '-a-b-c-')
328 ('symbol', 'a'))
328 ('symbol', 'a'))
329 * set:
329 * set:
330 <filteredset
330 <filteredset
331 <baseset [4]>,
331 <baseset [4]>,
332 <not
332 <not
333 <baseset [0]>>>
333 <baseset [0]>>>
334 4
334 4
335
335
336 $ log '1 or 2'
336 $ log '1 or 2'
337 1
337 1
338 2
338 2
339 $ log '1|2'
339 $ log '1|2'
340 1
340 1
341 2
341 2
342 $ log '1 and 2'
342 $ log '1 and 2'
343 $ log '1&2'
343 $ log '1&2'
344 $ try '1&2|3' # precedence - and is higher
344 $ try '1&2|3' # precedence - and is higher
345 (or
345 (or
346 (list
346 (list
347 (and
347 (and
348 ('symbol', '1')
348 ('symbol', '1')
349 ('symbol', '2'))
349 ('symbol', '2'))
350 ('symbol', '3')))
350 ('symbol', '3')))
351 * set:
351 * set:
352 <addset
352 <addset
353 <baseset []>,
353 <baseset []>,
354 <baseset [3]>>
354 <baseset [3]>>
355 3
355 3
356 $ try '1|2&3'
356 $ try '1|2&3'
357 (or
357 (or
358 (list
358 (list
359 ('symbol', '1')
359 ('symbol', '1')
360 (and
360 (and
361 ('symbol', '2')
361 ('symbol', '2')
362 ('symbol', '3'))))
362 ('symbol', '3'))))
363 * set:
363 * set:
364 <addset
364 <addset
365 <baseset [1]>,
365 <baseset [1]>,
366 <baseset []>>
366 <baseset []>>
367 1
367 1
368 $ try '1&2&3' # associativity
368 $ try '1&2&3' # associativity
369 (and
369 (and
370 (and
370 (and
371 ('symbol', '1')
371 ('symbol', '1')
372 ('symbol', '2'))
372 ('symbol', '2'))
373 ('symbol', '3'))
373 ('symbol', '3'))
374 * set:
374 * set:
375 <baseset []>
375 <baseset []>
376 $ try '1|(2|3)'
376 $ try '1|(2|3)'
377 (or
377 (or
378 (list
378 (list
379 ('symbol', '1')
379 ('symbol', '1')
380 (group
380 (group
381 (or
381 (or
382 (list
382 (list
383 ('symbol', '2')
383 ('symbol', '2')
384 ('symbol', '3'))))))
384 ('symbol', '3'))))))
385 * set:
385 * set:
386 <addset
386 <addset
387 <baseset [1]>,
387 <baseset [1]>,
388 <baseset [2, 3]>>
388 <baseset [2, 3]>>
389 1
389 1
390 2
390 2
391 3
391 3
392 $ log '1.0' # tag
392 $ log '1.0' # tag
393 6
393 6
394 $ log 'a' # branch
394 $ log 'a' # branch
395 0
395 0
396 $ log '2785f51ee'
396 $ log '2785f51ee'
397 0
397 0
398 $ log 'date(2005)'
398 $ log 'date(2005)'
399 4
399 4
400 $ log 'date(this is a test)'
400 $ log 'date(this is a test)'
401 hg: parse error at 10: unexpected token: symbol
401 hg: parse error at 10: unexpected token: symbol
402 [255]
402 [255]
403 $ log 'date()'
403 $ log 'date()'
404 hg: parse error: date requires a string
404 hg: parse error: date requires a string
405 [255]
405 [255]
406 $ log 'date'
406 $ log 'date'
407 abort: unknown revision 'date'!
407 abort: unknown revision 'date'!
408 [255]
408 [255]
409 $ log 'date('
409 $ log 'date('
410 hg: parse error at 5: not a prefix: end
410 hg: parse error at 5: not a prefix: end
411 [255]
411 [255]
412 $ log 'date("\xy")'
412 $ log 'date("\xy")'
413 hg: parse error: invalid \x escape
413 hg: parse error: invalid \x escape
414 [255]
414 [255]
415 $ log 'date(tip)'
415 $ log 'date(tip)'
416 hg: parse error: invalid date: 'tip'
416 hg: parse error: invalid date: 'tip'
417 [255]
417 [255]
418 $ log '0:date'
418 $ log '0:date'
419 abort: unknown revision 'date'!
419 abort: unknown revision 'date'!
420 [255]
420 [255]
421 $ log '::"date"'
421 $ log '::"date"'
422 abort: unknown revision 'date'!
422 abort: unknown revision 'date'!
423 [255]
423 [255]
424 $ hg book date -r 4
424 $ hg book date -r 4
425 $ log '0:date'
425 $ log '0:date'
426 0
426 0
427 1
427 1
428 2
428 2
429 3
429 3
430 4
430 4
431 $ log '::date'
431 $ log '::date'
432 0
432 0
433 1
433 1
434 2
434 2
435 4
435 4
436 $ log '::"date"'
436 $ log '::"date"'
437 0
437 0
438 1
438 1
439 2
439 2
440 4
440 4
441 $ log 'date(2005) and 1::'
441 $ log 'date(2005) and 1::'
442 4
442 4
443 $ hg book -d date
443 $ hg book -d date
444
444
445 function name should be a symbol
445 function name should be a symbol
446
446
447 $ log '"date"(2005)'
447 $ log '"date"(2005)'
448 hg: parse error: not a symbol
448 hg: parse error: not a symbol
449 [255]
449 [255]
450
450
451 keyword arguments
451 keyword arguments
452
452
453 $ log 'extra(branch, value=a)'
453 $ log 'extra(branch, value=a)'
454 0
454 0
455
455
456 $ log 'extra(branch, a, b)'
456 $ log 'extra(branch, a, b)'
457 hg: parse error: extra takes at most 2 positional arguments
457 hg: parse error: extra takes at most 2 positional arguments
458 [255]
458 [255]
459 $ log 'extra(a, label=b)'
459 $ log 'extra(a, label=b)'
460 hg: parse error: extra got multiple values for keyword argument 'label'
460 hg: parse error: extra got multiple values for keyword argument 'label'
461 [255]
461 [255]
462 $ log 'extra(label=branch, default)'
462 $ log 'extra(label=branch, default)'
463 hg: parse error: extra got an invalid argument
463 hg: parse error: extra got an invalid argument
464 [255]
464 [255]
465 $ log 'extra(branch, foo+bar=baz)'
465 $ log 'extra(branch, foo+bar=baz)'
466 hg: parse error: extra got an invalid argument
466 hg: parse error: extra got an invalid argument
467 [255]
467 [255]
468 $ log 'extra(unknown=branch)'
468 $ log 'extra(unknown=branch)'
469 hg: parse error: extra got an unexpected keyword argument 'unknown'
469 hg: parse error: extra got an unexpected keyword argument 'unknown'
470 [255]
470 [255]
471
471
472 $ try 'foo=bar|baz'
472 $ try 'foo=bar|baz'
473 (keyvalue
473 (keyvalue
474 ('symbol', 'foo')
474 ('symbol', 'foo')
475 (or
475 (or
476 (list
476 (list
477 ('symbol', 'bar')
477 ('symbol', 'bar')
478 ('symbol', 'baz'))))
478 ('symbol', 'baz'))))
479 hg: parse error: can't use a key-value pair in this context
479 hg: parse error: can't use a key-value pair in this context
480 [255]
480 [255]
481
481
482 right-hand side should be optimized recursively
482 right-hand side should be optimized recursively
483
483
484 $ try --optimize 'foo=(not public())'
484 $ try --optimize 'foo=(not public())'
485 (keyvalue
485 (keyvalue
486 ('symbol', 'foo')
486 ('symbol', 'foo')
487 (group
487 (group
488 (not
488 (not
489 (func
489 (func
490 ('symbol', 'public')
490 ('symbol', 'public')
491 None))))
491 None))))
492 * optimized:
492 * optimized:
493 (keyvalue
493 (keyvalue
494 ('symbol', 'foo')
494 ('symbol', 'foo')
495 (func
495 (func
496 ('symbol', '_notpublic')
496 ('symbol', '_notpublic')
497 None
497 None
498 any))
498 any))
499 hg: parse error: can't use a key-value pair in this context
499 hg: parse error: can't use a key-value pair in this context
500 [255]
500 [255]
501
501
502 parsed tree at stages:
502 parsed tree at stages:
503
503
504 $ hg debugrevspec -p all '()'
504 $ hg debugrevspec -p all '()'
505 * parsed:
505 * parsed:
506 (group
506 (group
507 None)
507 None)
508 * expanded:
508 * expanded:
509 (group
509 (group
510 None)
510 None)
511 * concatenated:
511 * concatenated:
512 (group
512 (group
513 None)
513 None)
514 * analyzed:
514 * analyzed:
515 None
515 None
516 * optimized:
516 * optimized:
517 None
517 None
518 hg: parse error: missing argument
518 hg: parse error: missing argument
519 [255]
519 [255]
520
520
521 $ hg debugrevspec --no-optimized -p all '()'
521 $ hg debugrevspec --no-optimized -p all '()'
522 * parsed:
522 * parsed:
523 (group
523 (group
524 None)
524 None)
525 * expanded:
525 * expanded:
526 (group
526 (group
527 None)
527 None)
528 * concatenated:
528 * concatenated:
529 (group
529 (group
530 None)
530 None)
531 * analyzed:
531 * analyzed:
532 None
532 None
533 hg: parse error: missing argument
533 hg: parse error: missing argument
534 [255]
534 [255]
535
535
536 $ hg debugrevspec -p parsed -p analyzed -p optimized '(0|1)-1'
536 $ hg debugrevspec -p parsed -p analyzed -p optimized '(0|1)-1'
537 * parsed:
537 * parsed:
538 (minus
538 (minus
539 (group
539 (group
540 (or
540 (or
541 (list
541 (list
542 ('symbol', '0')
542 ('symbol', '0')
543 ('symbol', '1'))))
543 ('symbol', '1'))))
544 ('symbol', '1'))
544 ('symbol', '1'))
545 * analyzed:
545 * analyzed:
546 (and
546 (and
547 (or
547 (or
548 (list
548 (list
549 ('symbol', '0')
549 ('symbol', '0')
550 ('symbol', '1'))
550 ('symbol', '1'))
551 define)
551 define)
552 (not
552 (not
553 ('symbol', '1')
553 ('symbol', '1')
554 follow)
554 follow)
555 define)
555 define)
556 * optimized:
556 * optimized:
557 (difference
557 (difference
558 (func
558 (func
559 ('symbol', '_list')
559 ('symbol', '_list')
560 ('string', '0\x001')
560 ('string', '0\x001')
561 define)
561 define)
562 ('symbol', '1')
562 ('symbol', '1')
563 define)
563 define)
564 0
564 0
565
565
566 $ hg debugrevspec -p unknown '0'
566 $ hg debugrevspec -p unknown '0'
567 abort: invalid stage name: unknown
567 abort: invalid stage name: unknown
568 [255]
568 [255]
569
569
570 $ hg debugrevspec -p all --optimize '0'
570 $ hg debugrevspec -p all --optimize '0'
571 abort: cannot use --optimize with --show-stage
571 abort: cannot use --optimize with --show-stage
572 [255]
572 [255]
573
573
574 verify optimized tree:
574 verify optimized tree:
575
575
576 $ hg debugrevspec --verify '0|1'
576 $ hg debugrevspec --verify '0|1'
577
577
578 $ hg debugrevspec --verify -v -p analyzed -p optimized 'r3232() & 2'
578 $ hg debugrevspec --verify -v -p analyzed -p optimized 'r3232() & 2'
579 * analyzed:
579 * analyzed:
580 (and
580 (and
581 (func
581 (func
582 ('symbol', 'r3232')
582 ('symbol', 'r3232')
583 None
583 None
584 define)
584 define)
585 ('symbol', '2')
585 ('symbol', '2')
586 define)
586 define)
587 * optimized:
587 * optimized:
588 (and
588 (and
589 ('symbol', '2')
589 ('symbol', '2')
590 (func
590 (func
591 ('symbol', 'r3232')
591 ('symbol', 'r3232')
592 None
592 None
593 define)
593 define)
594 define)
594 define)
595 * analyzed set:
595 * analyzed set:
596 <baseset [2]>
596 <baseset [2]>
597 * optimized set:
597 * optimized set:
598 <baseset [2, 2]>
598 <baseset [2, 2]>
599 --- analyzed
599 --- analyzed
600 +++ optimized
600 +++ optimized
601 2
601 2
602 +2
602 +2
603 [1]
603 [1]
604
604
605 $ hg debugrevspec --no-optimized --verify-optimized '0'
605 $ hg debugrevspec --no-optimized --verify-optimized '0'
606 abort: cannot use --verify-optimized with --no-optimized
606 abort: cannot use --verify-optimized with --no-optimized
607 [255]
607 [255]
608
608
609 Test that symbols only get parsed as functions if there's an opening
609 Test that symbols only get parsed as functions if there's an opening
610 parenthesis.
610 parenthesis.
611
611
612 $ hg book only -r 9
612 $ hg book only -r 9
613 $ log 'only(only)' # Outer "only" is a function, inner "only" is the bookmark
613 $ log 'only(only)' # Outer "only" is a function, inner "only" is the bookmark
614 8
614 8
615 9
615 9
616
616
617 ':y' behaves like '0:y', but can't be rewritten as such since the revision '0'
617 ':y' behaves like '0:y', but can't be rewritten as such since the revision '0'
618 may be hidden (issue5385)
618 may be hidden (issue5385)
619
619
620 $ try -p parsed -p analyzed ':'
620 $ try -p parsed -p analyzed ':'
621 * parsed:
621 * parsed:
622 (rangeall
622 (rangeall
623 None)
623 None)
624 * analyzed:
624 * analyzed:
625 (rangeall
625 (rangeall
626 None
626 None
627 define)
627 define)
628 * set:
628 * set:
629 <spanset+ 0:9>
629 <spanset+ 0:10>
630 0
630 0
631 1
631 1
632 2
632 2
633 3
633 3
634 4
634 4
635 5
635 5
636 6
636 6
637 7
637 7
638 8
638 8
639 9
639 9
640 $ try -p analyzed ':1'
640 $ try -p analyzed ':1'
641 * analyzed:
641 * analyzed:
642 (rangepre
642 (rangepre
643 ('symbol', '1')
643 ('symbol', '1')
644 define)
644 define)
645 * set:
645 * set:
646 <spanset+ 0:1>
646 <spanset+ 0:2>
647 0
647 0
648 1
648 1
649 $ try -p analyzed ':(1|2)'
649 $ try -p analyzed ':(1|2)'
650 * analyzed:
650 * analyzed:
651 (rangepre
651 (rangepre
652 (or
652 (or
653 (list
653 (list
654 ('symbol', '1')
654 ('symbol', '1')
655 ('symbol', '2'))
655 ('symbol', '2'))
656 define)
656 define)
657 define)
657 define)
658 * set:
658 * set:
659 <spanset+ 0:2>
659 <spanset+ 0:3>
660 0
660 0
661 1
661 1
662 2
662 2
663 $ try -p analyzed ':(1&2)'
663 $ try -p analyzed ':(1&2)'
664 * analyzed:
664 * analyzed:
665 (rangepre
665 (rangepre
666 (and
666 (and
667 ('symbol', '1')
667 ('symbol', '1')
668 ('symbol', '2')
668 ('symbol', '2')
669 define)
669 define)
670 define)
670 define)
671 * set:
671 * set:
672 <baseset []>
672 <baseset []>
673
673
674 infix/suffix resolution of ^ operator (issue2884):
674 infix/suffix resolution of ^ operator (issue2884):
675
675
676 x^:y means (x^):y
676 x^:y means (x^):y
677
677
678 $ try '1^:2'
678 $ try '1^:2'
679 (range
679 (range
680 (parentpost
680 (parentpost
681 ('symbol', '1'))
681 ('symbol', '1'))
682 ('symbol', '2'))
682 ('symbol', '2'))
683 * set:
683 * set:
684 <spanset+ 0:2>
684 <spanset+ 0:3>
685 0
685 0
686 1
686 1
687 2
687 2
688
688
689 $ try '1^::2'
689 $ try '1^::2'
690 (dagrange
690 (dagrange
691 (parentpost
691 (parentpost
692 ('symbol', '1'))
692 ('symbol', '1'))
693 ('symbol', '2'))
693 ('symbol', '2'))
694 * set:
694 * set:
695 <baseset+ [0, 1, 2]>
695 <baseset+ [0, 1, 2]>
696 0
696 0
697 1
697 1
698 2
698 2
699
699
700 $ try '9^:'
700 $ try '9^:'
701 (rangepost
701 (rangepost
702 (parentpost
702 (parentpost
703 ('symbol', '9')))
703 ('symbol', '9')))
704 * set:
704 * set:
705 <spanset+ 8:9>
705 <spanset+ 8:10>
706 8
706 8
707 9
707 9
708
708
709 x^:y should be resolved before omitting group operators
709 x^:y should be resolved before omitting group operators
710
710
711 $ try '1^(:2)'
711 $ try '1^(:2)'
712 (parent
712 (parent
713 ('symbol', '1')
713 ('symbol', '1')
714 (group
714 (group
715 (rangepre
715 (rangepre
716 ('symbol', '2'))))
716 ('symbol', '2'))))
717 hg: parse error: ^ expects a number 0, 1, or 2
717 hg: parse error: ^ expects a number 0, 1, or 2
718 [255]
718 [255]
719
719
720 x^:y should be resolved recursively
720 x^:y should be resolved recursively
721
721
722 $ try 'sort(1^:2)'
722 $ try 'sort(1^:2)'
723 (func
723 (func
724 ('symbol', 'sort')
724 ('symbol', 'sort')
725 (range
725 (range
726 (parentpost
726 (parentpost
727 ('symbol', '1'))
727 ('symbol', '1'))
728 ('symbol', '2')))
728 ('symbol', '2')))
729 * set:
729 * set:
730 <spanset+ 0:2>
730 <spanset+ 0:3>
731 0
731 0
732 1
732 1
733 2
733 2
734
734
735 $ try '(3^:4)^:2'
735 $ try '(3^:4)^:2'
736 (range
736 (range
737 (parentpost
737 (parentpost
738 (group
738 (group
739 (range
739 (range
740 (parentpost
740 (parentpost
741 ('symbol', '3'))
741 ('symbol', '3'))
742 ('symbol', '4'))))
742 ('symbol', '4'))))
743 ('symbol', '2'))
743 ('symbol', '2'))
744 * set:
744 * set:
745 <spanset+ 0:2>
745 <spanset+ 0:3>
746 0
746 0
747 1
747 1
748 2
748 2
749
749
750 $ try '(3^::4)^::2'
750 $ try '(3^::4)^::2'
751 (dagrange
751 (dagrange
752 (parentpost
752 (parentpost
753 (group
753 (group
754 (dagrange
754 (dagrange
755 (parentpost
755 (parentpost
756 ('symbol', '3'))
756 ('symbol', '3'))
757 ('symbol', '4'))))
757 ('symbol', '4'))))
758 ('symbol', '2'))
758 ('symbol', '2'))
759 * set:
759 * set:
760 <baseset+ [0, 1, 2]>
760 <baseset+ [0, 1, 2]>
761 0
761 0
762 1
762 1
763 2
763 2
764
764
765 $ try '(9^:)^:'
765 $ try '(9^:)^:'
766 (rangepost
766 (rangepost
767 (parentpost
767 (parentpost
768 (group
768 (group
769 (rangepost
769 (rangepost
770 (parentpost
770 (parentpost
771 ('symbol', '9'))))))
771 ('symbol', '9'))))))
772 * set:
772 * set:
773 <spanset+ 4:9>
773 <spanset+ 4:10>
774 4
774 4
775 5
775 5
776 6
776 6
777 7
777 7
778 8
778 8
779 9
779 9
780
780
781 x^ in alias should also be resolved
781 x^ in alias should also be resolved
782
782
783 $ try 'A' --config 'revsetalias.A=1^:2'
783 $ try 'A' --config 'revsetalias.A=1^:2'
784 ('symbol', 'A')
784 ('symbol', 'A')
785 * expanded:
785 * expanded:
786 (range
786 (range
787 (parentpost
787 (parentpost
788 ('symbol', '1'))
788 ('symbol', '1'))
789 ('symbol', '2'))
789 ('symbol', '2'))
790 * set:
790 * set:
791 <spanset+ 0:2>
791 <spanset+ 0:3>
792 0
792 0
793 1
793 1
794 2
794 2
795
795
796 $ try 'A:2' --config 'revsetalias.A=1^'
796 $ try 'A:2' --config 'revsetalias.A=1^'
797 (range
797 (range
798 ('symbol', 'A')
798 ('symbol', 'A')
799 ('symbol', '2'))
799 ('symbol', '2'))
800 * expanded:
800 * expanded:
801 (range
801 (range
802 (parentpost
802 (parentpost
803 ('symbol', '1'))
803 ('symbol', '1'))
804 ('symbol', '2'))
804 ('symbol', '2'))
805 * set:
805 * set:
806 <spanset+ 0:2>
806 <spanset+ 0:3>
807 0
807 0
808 1
808 1
809 2
809 2
810
810
811 but not beyond the boundary of alias expansion, because the resolution should
811 but not beyond the boundary of alias expansion, because the resolution should
812 be made at the parsing stage
812 be made at the parsing stage
813
813
814 $ try '1^A' --config 'revsetalias.A=:2'
814 $ try '1^A' --config 'revsetalias.A=:2'
815 (parent
815 (parent
816 ('symbol', '1')
816 ('symbol', '1')
817 ('symbol', 'A'))
817 ('symbol', 'A'))
818 * expanded:
818 * expanded:
819 (parent
819 (parent
820 ('symbol', '1')
820 ('symbol', '1')
821 (rangepre
821 (rangepre
822 ('symbol', '2')))
822 ('symbol', '2')))
823 hg: parse error: ^ expects a number 0, 1, or 2
823 hg: parse error: ^ expects a number 0, 1, or 2
824 [255]
824 [255]
825
825
826 ancestor can accept 0 or more arguments
826 ancestor can accept 0 or more arguments
827
827
828 $ log 'ancestor()'
828 $ log 'ancestor()'
829 $ log 'ancestor(1)'
829 $ log 'ancestor(1)'
830 1
830 1
831 $ log 'ancestor(4,5)'
831 $ log 'ancestor(4,5)'
832 1
832 1
833 $ log 'ancestor(4,5) and 4'
833 $ log 'ancestor(4,5) and 4'
834 $ log 'ancestor(0,0,1,3)'
834 $ log 'ancestor(0,0,1,3)'
835 0
835 0
836 $ log 'ancestor(3,1,5,3,5,1)'
836 $ log 'ancestor(3,1,5,3,5,1)'
837 1
837 1
838 $ log 'ancestor(0,1,3,5)'
838 $ log 'ancestor(0,1,3,5)'
839 0
839 0
840 $ log 'ancestor(1,2,3,4,5)'
840 $ log 'ancestor(1,2,3,4,5)'
841 1
841 1
842
842
843 test ancestors
843 test ancestors
844
844
845 $ log 'ancestors(5)'
845 $ log 'ancestors(5)'
846 0
846 0
847 1
847 1
848 3
848 3
849 5
849 5
850 $ log 'ancestor(ancestors(5))'
850 $ log 'ancestor(ancestors(5))'
851 0
851 0
852 $ log '::r3232()'
852 $ log '::r3232()'
853 0
853 0
854 1
854 1
855 2
855 2
856 3
856 3
857
857
858 $ log 'author(bob)'
858 $ log 'author(bob)'
859 2
859 2
860 $ log 'author("re:bob|test")'
860 $ log 'author("re:bob|test")'
861 0
861 0
862 1
862 1
863 2
863 2
864 3
864 3
865 4
865 4
866 5
866 5
867 6
867 6
868 7
868 7
869 8
869 8
870 9
870 9
871 $ log 'author(r"re:\S")'
871 $ log 'author(r"re:\S")'
872 0
872 0
873 1
873 1
874 2
874 2
875 3
875 3
876 4
876 4
877 5
877 5
878 6
878 6
879 7
879 7
880 8
880 8
881 9
881 9
882 $ log 'branch(Γ©)'
882 $ log 'branch(Γ©)'
883 8
883 8
884 9
884 9
885 $ log 'branch(a)'
885 $ log 'branch(a)'
886 0
886 0
887 $ hg log -r 'branch("re:a")' --template '{rev} {branch}\n'
887 $ hg log -r 'branch("re:a")' --template '{rev} {branch}\n'
888 0 a
888 0 a
889 2 a-b-c-
889 2 a-b-c-
890 3 +a+b+c+
890 3 +a+b+c+
891 4 -a-b-c-
891 4 -a-b-c-
892 5 !a/b/c/
892 5 !a/b/c/
893 6 _a_b_c_
893 6 _a_b_c_
894 7 .a.b.c.
894 7 .a.b.c.
895 $ log 'children(ancestor(4,5))'
895 $ log 'children(ancestor(4,5))'
896 2
896 2
897 3
897 3
898
898
899 $ log 'children(4)'
899 $ log 'children(4)'
900 6
900 6
901 8
901 8
902 $ log 'children(null)'
902 $ log 'children(null)'
903 0
903 0
904
904
905 $ log 'closed()'
905 $ log 'closed()'
906 $ log 'contains(a)'
906 $ log 'contains(a)'
907 0
907 0
908 1
908 1
909 3
909 3
910 5
910 5
911 $ log 'contains("../repo/a")'
911 $ log 'contains("../repo/a")'
912 0
912 0
913 1
913 1
914 3
914 3
915 5
915 5
916 $ log 'desc(B)'
916 $ log 'desc(B)'
917 5
917 5
918 $ hg log -r 'desc(r"re:S?u")' --template "{rev} {desc|firstline}\n"
918 $ hg log -r 'desc(r"re:S?u")' --template "{rev} {desc|firstline}\n"
919 5 5 bug
919 5 5 bug
920 6 6 issue619
920 6 6 issue619
921 $ log 'descendants(2 or 3)'
921 $ log 'descendants(2 or 3)'
922 2
922 2
923 3
923 3
924 4
924 4
925 5
925 5
926 6
926 6
927 7
927 7
928 8
928 8
929 9
929 9
930 $ log 'file("b*")'
930 $ log 'file("b*")'
931 1
931 1
932 4
932 4
933 $ log 'filelog("b")'
933 $ log 'filelog("b")'
934 1
934 1
935 4
935 4
936 $ log 'filelog("../repo/b")'
936 $ log 'filelog("../repo/b")'
937 1
937 1
938 4
938 4
939 $ log 'follow()'
939 $ log 'follow()'
940 0
940 0
941 1
941 1
942 2
942 2
943 4
943 4
944 8
944 8
945 9
945 9
946 $ log 'grep("issue\d+")'
946 $ log 'grep("issue\d+")'
947 6
947 6
948 $ try 'grep("(")' # invalid regular expression
948 $ try 'grep("(")' # invalid regular expression
949 (func
949 (func
950 ('symbol', 'grep')
950 ('symbol', 'grep')
951 ('string', '('))
951 ('string', '('))
952 hg: parse error: invalid match pattern: unbalanced parenthesis
952 hg: parse error: invalid match pattern: unbalanced parenthesis
953 [255]
953 [255]
954 $ try 'grep("\bissue\d+")'
954 $ try 'grep("\bissue\d+")'
955 (func
955 (func
956 ('symbol', 'grep')
956 ('symbol', 'grep')
957 ('string', '\x08issue\\d+'))
957 ('string', '\x08issue\\d+'))
958 * set:
958 * set:
959 <filteredset
959 <filteredset
960 <fullreposet+ 0:9>,
960 <fullreposet+ 0:10>,
961 <grep '\x08issue\\d+'>>
961 <grep '\x08issue\\d+'>>
962 $ try 'grep(r"\bissue\d+")'
962 $ try 'grep(r"\bissue\d+")'
963 (func
963 (func
964 ('symbol', 'grep')
964 ('symbol', 'grep')
965 ('string', '\\bissue\\d+'))
965 ('string', '\\bissue\\d+'))
966 * set:
966 * set:
967 <filteredset
967 <filteredset
968 <fullreposet+ 0:9>,
968 <fullreposet+ 0:10>,
969 <grep '\\bissue\\d+'>>
969 <grep '\\bissue\\d+'>>
970 6
970 6
971 $ try 'grep(r"\")'
971 $ try 'grep(r"\")'
972 hg: parse error at 7: unterminated string
972 hg: parse error at 7: unterminated string
973 [255]
973 [255]
974 $ log 'head()'
974 $ log 'head()'
975 0
975 0
976 1
976 1
977 2
977 2
978 3
978 3
979 4
979 4
980 5
980 5
981 6
981 6
982 7
982 7
983 9
983 9
984 $ log 'heads(6::)'
984 $ log 'heads(6::)'
985 7
985 7
986 $ log 'keyword(issue)'
986 $ log 'keyword(issue)'
987 6
987 6
988 $ log 'keyword("test a")'
988 $ log 'keyword("test a")'
989
989
990 Test first (=limit) and last
990 Test first (=limit) and last
991
991
992 $ log 'limit(head(), 1)'
992 $ log 'limit(head(), 1)'
993 0
993 0
994 $ log 'limit(author("re:bob|test"), 3, 5)'
994 $ log 'limit(author("re:bob|test"), 3, 5)'
995 5
995 5
996 6
996 6
997 7
997 7
998 $ log 'limit(author("re:bob|test"), offset=6)'
998 $ log 'limit(author("re:bob|test"), offset=6)'
999 6
999 6
1000 $ log 'limit(author("re:bob|test"), offset=10)'
1000 $ log 'limit(author("re:bob|test"), offset=10)'
1001 $ log 'limit(all(), 1, -1)'
1001 $ log 'limit(all(), 1, -1)'
1002 hg: parse error: negative offset
1002 hg: parse error: negative offset
1003 [255]
1003 [255]
1004 $ log 'limit(all(), -1)'
1004 $ log 'limit(all(), -1)'
1005 hg: parse error: negative number to select
1005 hg: parse error: negative number to select
1006 [255]
1006 [255]
1007 $ log 'limit(all(), 0)'
1007 $ log 'limit(all(), 0)'
1008
1008
1009 $ log 'last(all(), -1)'
1009 $ log 'last(all(), -1)'
1010 hg: parse error: negative number to select
1010 hg: parse error: negative number to select
1011 [255]
1011 [255]
1012 $ log 'last(all(), 0)'
1012 $ log 'last(all(), 0)'
1013 $ log 'last(all(), 1)'
1013 $ log 'last(all(), 1)'
1014 9
1014 9
1015 $ log 'last(all(), 2)'
1015 $ log 'last(all(), 2)'
1016 8
1016 8
1017 9
1017 9
1018
1018
1019 Test order of first/last revisions
1019 Test order of first/last revisions
1020
1020
1021 $ hg debugrevspec -s 'first(4:0, 3) & 3:'
1021 $ hg debugrevspec -s 'first(4:0, 3) & 3:'
1022 * set:
1022 * set:
1023 <filteredset
1023 <filteredset
1024 <baseset
1024 <baseset
1025 <limit n=3, offset=0,
1025 <limit n=3, offset=0,
1026 <spanset- 0:4>>>,
1026 <spanset- 0:5>>>,
1027 <spanset+ 3:9>>
1027 <spanset+ 3:10>>
1028 4
1028 4
1029 3
1029 3
1030
1030
1031 $ hg debugrevspec -s '3: & first(4:0, 3)'
1031 $ hg debugrevspec -s '3: & first(4:0, 3)'
1032 * set:
1032 * set:
1033 <filteredset
1033 <filteredset
1034 <spanset+ 3:9>,
1034 <spanset+ 3:10>,
1035 <baseset
1035 <baseset
1036 <limit n=3, offset=0,
1036 <limit n=3, offset=0,
1037 <spanset- 0:4>>>>
1037 <spanset- 0:5>>>>
1038 3
1038 3
1039 4
1039 4
1040
1040
1041 $ hg debugrevspec -s 'last(4:0, 3) & :1'
1041 $ hg debugrevspec -s 'last(4:0, 3) & :1'
1042 * set:
1042 * set:
1043 <filteredset
1043 <filteredset
1044 <baseset
1044 <baseset
1045 <last n=3,
1045 <last n=3,
1046 <spanset+ 0:4>>>,
1046 <spanset+ 0:5>>>,
1047 <spanset+ 0:1>>
1047 <spanset+ 0:2>>
1048 1
1048 1
1049 0
1049 0
1050
1050
1051 $ hg debugrevspec -s ':1 & last(4:0, 3)'
1051 $ hg debugrevspec -s ':1 & last(4:0, 3)'
1052 * set:
1052 * set:
1053 <filteredset
1053 <filteredset
1054 <spanset+ 0:1>,
1054 <spanset+ 0:2>,
1055 <baseset
1055 <baseset
1056 <last n=3,
1056 <last n=3,
1057 <spanset+ 0:4>>>>
1057 <spanset+ 0:5>>>>
1058 0
1058 0
1059 1
1059 1
1060
1060
1061 Test matching
1061 Test matching
1062
1062
1063 $ log 'matching(6)'
1063 $ log 'matching(6)'
1064 6
1064 6
1065 $ log 'matching(6:7, "phase parents user date branch summary files description substate")'
1065 $ log 'matching(6:7, "phase parents user date branch summary files description substate")'
1066 6
1066 6
1067 7
1067 7
1068
1068
1069 Testing min and max
1069 Testing min and max
1070
1070
1071 max: simple
1071 max: simple
1072
1072
1073 $ log 'max(contains(a))'
1073 $ log 'max(contains(a))'
1074 5
1074 5
1075
1075
1076 max: simple on unordered set)
1076 max: simple on unordered set)
1077
1077
1078 $ log 'max((4+0+2+5+7) and contains(a))'
1078 $ log 'max((4+0+2+5+7) and contains(a))'
1079 5
1079 5
1080
1080
1081 max: no result
1081 max: no result
1082
1082
1083 $ log 'max(contains(stringthatdoesnotappearanywhere))'
1083 $ log 'max(contains(stringthatdoesnotappearanywhere))'
1084
1084
1085 max: no result on unordered set
1085 max: no result on unordered set
1086
1086
1087 $ log 'max((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1087 $ log 'max((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1088
1088
1089 min: simple
1089 min: simple
1090
1090
1091 $ log 'min(contains(a))'
1091 $ log 'min(contains(a))'
1092 0
1092 0
1093
1093
1094 min: simple on unordered set
1094 min: simple on unordered set
1095
1095
1096 $ log 'min((4+0+2+5+7) and contains(a))'
1096 $ log 'min((4+0+2+5+7) and contains(a))'
1097 0
1097 0
1098
1098
1099 min: empty
1099 min: empty
1100
1100
1101 $ log 'min(contains(stringthatdoesnotappearanywhere))'
1101 $ log 'min(contains(stringthatdoesnotappearanywhere))'
1102
1102
1103 min: empty on unordered set
1103 min: empty on unordered set
1104
1104
1105 $ log 'min((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1105 $ log 'min((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1106
1106
1107
1107
1108 $ log 'merge()'
1108 $ log 'merge()'
1109 6
1109 6
1110 $ log 'branchpoint()'
1110 $ log 'branchpoint()'
1111 1
1111 1
1112 4
1112 4
1113 $ log 'modifies(b)'
1113 $ log 'modifies(b)'
1114 4
1114 4
1115 $ log 'modifies("path:b")'
1115 $ log 'modifies("path:b")'
1116 4
1116 4
1117 $ log 'modifies("*")'
1117 $ log 'modifies("*")'
1118 4
1118 4
1119 6
1119 6
1120 $ log 'modifies("set:modified()")'
1120 $ log 'modifies("set:modified()")'
1121 4
1121 4
1122 $ log 'id(5)'
1122 $ log 'id(5)'
1123 2
1123 2
1124 $ log 'only(9)'
1124 $ log 'only(9)'
1125 8
1125 8
1126 9
1126 9
1127 $ log 'only(8)'
1127 $ log 'only(8)'
1128 8
1128 8
1129 $ log 'only(9, 5)'
1129 $ log 'only(9, 5)'
1130 2
1130 2
1131 4
1131 4
1132 8
1132 8
1133 9
1133 9
1134 $ log 'only(7 + 9, 5 + 2)'
1134 $ log 'only(7 + 9, 5 + 2)'
1135 4
1135 4
1136 6
1136 6
1137 7
1137 7
1138 8
1138 8
1139 9
1139 9
1140
1140
1141 Test empty set input
1141 Test empty set input
1142 $ log 'only(p2())'
1142 $ log 'only(p2())'
1143 $ log 'only(p1(), p2())'
1143 $ log 'only(p1(), p2())'
1144 0
1144 0
1145 1
1145 1
1146 2
1146 2
1147 4
1147 4
1148 8
1148 8
1149 9
1149 9
1150
1150
1151 Test '%' operator
1151 Test '%' operator
1152
1152
1153 $ log '9%'
1153 $ log '9%'
1154 8
1154 8
1155 9
1155 9
1156 $ log '9%5'
1156 $ log '9%5'
1157 2
1157 2
1158 4
1158 4
1159 8
1159 8
1160 9
1160 9
1161 $ log '(7 + 9)%(5 + 2)'
1161 $ log '(7 + 9)%(5 + 2)'
1162 4
1162 4
1163 6
1163 6
1164 7
1164 7
1165 8
1165 8
1166 9
1166 9
1167
1167
1168 Test operand of '%' is optimized recursively (issue4670)
1168 Test operand of '%' is optimized recursively (issue4670)
1169
1169
1170 $ try --optimize '8:9-8%'
1170 $ try --optimize '8:9-8%'
1171 (onlypost
1171 (onlypost
1172 (minus
1172 (minus
1173 (range
1173 (range
1174 ('symbol', '8')
1174 ('symbol', '8')
1175 ('symbol', '9'))
1175 ('symbol', '9'))
1176 ('symbol', '8')))
1176 ('symbol', '8')))
1177 * optimized:
1177 * optimized:
1178 (func
1178 (func
1179 ('symbol', 'only')
1179 ('symbol', 'only')
1180 (difference
1180 (difference
1181 (range
1181 (range
1182 ('symbol', '8')
1182 ('symbol', '8')
1183 ('symbol', '9')
1183 ('symbol', '9')
1184 define)
1184 define)
1185 ('symbol', '8')
1185 ('symbol', '8')
1186 define)
1186 define)
1187 define)
1187 define)
1188 * set:
1188 * set:
1189 <baseset+ [8, 9]>
1189 <baseset+ [8, 9]>
1190 8
1190 8
1191 9
1191 9
1192 $ try --optimize '(9)%(5)'
1192 $ try --optimize '(9)%(5)'
1193 (only
1193 (only
1194 (group
1194 (group
1195 ('symbol', '9'))
1195 ('symbol', '9'))
1196 (group
1196 (group
1197 ('symbol', '5')))
1197 ('symbol', '5')))
1198 * optimized:
1198 * optimized:
1199 (func
1199 (func
1200 ('symbol', 'only')
1200 ('symbol', 'only')
1201 (list
1201 (list
1202 ('symbol', '9')
1202 ('symbol', '9')
1203 ('symbol', '5'))
1203 ('symbol', '5'))
1204 define)
1204 define)
1205 * set:
1205 * set:
1206 <baseset+ [2, 4, 8, 9]>
1206 <baseset+ [2, 4, 8, 9]>
1207 2
1207 2
1208 4
1208 4
1209 8
1209 8
1210 9
1210 9
1211
1211
1212 Test the order of operations
1212 Test the order of operations
1213
1213
1214 $ log '7 + 9%5 + 2'
1214 $ log '7 + 9%5 + 2'
1215 7
1215 7
1216 2
1216 2
1217 4
1217 4
1218 8
1218 8
1219 9
1219 9
1220
1220
1221 Test explicit numeric revision
1221 Test explicit numeric revision
1222 $ log 'rev(-2)'
1222 $ log 'rev(-2)'
1223 $ log 'rev(-1)'
1223 $ log 'rev(-1)'
1224 -1
1224 -1
1225 $ log 'rev(0)'
1225 $ log 'rev(0)'
1226 0
1226 0
1227 $ log 'rev(9)'
1227 $ log 'rev(9)'
1228 9
1228 9
1229 $ log 'rev(10)'
1229 $ log 'rev(10)'
1230 $ log 'rev(tip)'
1230 $ log 'rev(tip)'
1231 hg: parse error: rev expects a number
1231 hg: parse error: rev expects a number
1232 [255]
1232 [255]
1233
1233
1234 Test hexadecimal revision
1234 Test hexadecimal revision
1235 $ log 'id(2)'
1235 $ log 'id(2)'
1236 abort: 00changelog.i@2: ambiguous identifier!
1236 abort: 00changelog.i@2: ambiguous identifier!
1237 [255]
1237 [255]
1238 $ log 'id(23268)'
1238 $ log 'id(23268)'
1239 4
1239 4
1240 $ log 'id(2785f51eece)'
1240 $ log 'id(2785f51eece)'
1241 0
1241 0
1242 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532c)'
1242 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532c)'
1243 8
1243 8
1244 $ log 'id(d5d0dcbdc4a)'
1244 $ log 'id(d5d0dcbdc4a)'
1245 $ log 'id(d5d0dcbdc4w)'
1245 $ log 'id(d5d0dcbdc4w)'
1246 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532d)'
1246 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532d)'
1247 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532q)'
1247 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532q)'
1248 $ log 'id(1.0)'
1248 $ log 'id(1.0)'
1249 $ log 'id(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)'
1249 $ log 'id(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)'
1250
1250
1251 Test null revision
1251 Test null revision
1252 $ log '(null)'
1252 $ log '(null)'
1253 -1
1253 -1
1254 $ log '(null:0)'
1254 $ log '(null:0)'
1255 -1
1255 -1
1256 0
1256 0
1257 $ log '(0:null)'
1257 $ log '(0:null)'
1258 0
1258 0
1259 -1
1259 -1
1260 $ log 'null::0'
1260 $ log 'null::0'
1261 -1
1261 -1
1262 0
1262 0
1263 $ log 'null:tip - 0:'
1263 $ log 'null:tip - 0:'
1264 -1
1264 -1
1265 $ log 'null: and null::' | head -1
1265 $ log 'null: and null::' | head -1
1266 -1
1266 -1
1267 $ log 'null: or 0:' | head -2
1267 $ log 'null: or 0:' | head -2
1268 -1
1268 -1
1269 0
1269 0
1270 $ log 'ancestors(null)'
1270 $ log 'ancestors(null)'
1271 -1
1271 -1
1272 $ log 'reverse(null:)' | tail -2
1272 $ log 'reverse(null:)' | tail -2
1273 0
1273 0
1274 -1
1274 -1
1275 $ log 'first(null:)'
1275 $ log 'first(null:)'
1276 -1
1276 -1
1277 $ log 'min(null:)'
1277 $ log 'min(null:)'
1278 BROKEN: should be '-1'
1278 BROKEN: should be '-1'
1279 $ log 'tip:null and all()' | tail -2
1279 $ log 'tip:null and all()' | tail -2
1280 1
1280 1
1281 0
1281 0
1282
1282
1283 Test working-directory revision
1283 Test working-directory revision
1284 $ hg debugrevspec 'wdir()'
1284 $ hg debugrevspec 'wdir()'
1285 2147483647
1285 2147483647
1286 $ hg debugrevspec 'wdir()^'
1286 $ hg debugrevspec 'wdir()^'
1287 9
1287 9
1288 $ hg up 7
1288 $ hg up 7
1289 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1289 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1290 $ hg debugrevspec 'wdir()^'
1290 $ hg debugrevspec 'wdir()^'
1291 7
1291 7
1292 $ hg debugrevspec 'wdir()^0'
1292 $ hg debugrevspec 'wdir()^0'
1293 2147483647
1293 2147483647
1294 $ hg debugrevspec 'wdir()~3'
1294 $ hg debugrevspec 'wdir()~3'
1295 5
1295 5
1296 $ hg debugrevspec 'ancestors(wdir())'
1296 $ hg debugrevspec 'ancestors(wdir())'
1297 0
1297 0
1298 1
1298 1
1299 2
1299 2
1300 3
1300 3
1301 4
1301 4
1302 5
1302 5
1303 6
1303 6
1304 7
1304 7
1305 2147483647
1305 2147483647
1306 $ hg debugrevspec 'wdir()~0'
1306 $ hg debugrevspec 'wdir()~0'
1307 2147483647
1307 2147483647
1308 $ hg debugrevspec 'p1(wdir())'
1308 $ hg debugrevspec 'p1(wdir())'
1309 7
1309 7
1310 $ hg debugrevspec 'p2(wdir())'
1310 $ hg debugrevspec 'p2(wdir())'
1311 $ hg debugrevspec 'parents(wdir())'
1311 $ hg debugrevspec 'parents(wdir())'
1312 7
1312 7
1313 $ hg debugrevspec 'wdir()^1'
1313 $ hg debugrevspec 'wdir()^1'
1314 7
1314 7
1315 $ hg debugrevspec 'wdir()^2'
1315 $ hg debugrevspec 'wdir()^2'
1316 $ hg debugrevspec 'wdir()^3'
1316 $ hg debugrevspec 'wdir()^3'
1317 hg: parse error: ^ expects a number 0, 1, or 2
1317 hg: parse error: ^ expects a number 0, 1, or 2
1318 [255]
1318 [255]
1319 For tests consistency
1319 For tests consistency
1320 $ hg up 9
1320 $ hg up 9
1321 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1321 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1322 $ hg debugrevspec 'tip or wdir()'
1322 $ hg debugrevspec 'tip or wdir()'
1323 9
1323 9
1324 2147483647
1324 2147483647
1325 $ hg debugrevspec '0:tip and wdir()'
1325 $ hg debugrevspec '0:tip and wdir()'
1326 $ log '0:wdir()' | tail -3
1326 $ log '0:wdir()' | tail -3
1327 8
1327 8
1328 9
1328 9
1329 2147483647
1329 2147483647
1330 $ log 'wdir():0' | head -3
1330 $ log 'wdir():0' | head -3
1331 2147483647
1331 2147483647
1332 9
1332 9
1333 8
1333 8
1334 $ log 'wdir():wdir()'
1334 $ log 'wdir():wdir()'
1335 2147483647
1335 2147483647
1336 $ log '(all() + wdir()) & min(. + wdir())'
1336 $ log '(all() + wdir()) & min(. + wdir())'
1337 9
1337 9
1338 $ log '(all() + wdir()) & max(. + wdir())'
1338 $ log '(all() + wdir()) & max(. + wdir())'
1339 2147483647
1339 2147483647
1340 $ log 'first(wdir() + .)'
1340 $ log 'first(wdir() + .)'
1341 2147483647
1341 2147483647
1342 $ log 'last(. + wdir())'
1342 $ log 'last(. + wdir())'
1343 2147483647
1343 2147483647
1344
1344
1345 Test working-directory integer revision and node id
1345 Test working-directory integer revision and node id
1346 (BUG: '0:wdir()' is still needed to populate wdir revision)
1346 (BUG: '0:wdir()' is still needed to populate wdir revision)
1347
1347
1348 $ hg debugrevspec '0:wdir() & 2147483647'
1348 $ hg debugrevspec '0:wdir() & 2147483647'
1349 2147483647
1349 2147483647
1350 $ hg debugrevspec '0:wdir() & rev(2147483647)'
1350 $ hg debugrevspec '0:wdir() & rev(2147483647)'
1351 2147483647
1351 2147483647
1352 $ hg debugrevspec '0:wdir() & ffffffffffffffffffffffffffffffffffffffff'
1352 $ hg debugrevspec '0:wdir() & ffffffffffffffffffffffffffffffffffffffff'
1353 2147483647
1353 2147483647
1354 $ hg debugrevspec '0:wdir() & ffffffffffff'
1354 $ hg debugrevspec '0:wdir() & ffffffffffff'
1355 2147483647
1355 2147483647
1356 $ hg debugrevspec '0:wdir() & id(ffffffffffffffffffffffffffffffffffffffff)'
1356 $ hg debugrevspec '0:wdir() & id(ffffffffffffffffffffffffffffffffffffffff)'
1357 2147483647
1357 2147483647
1358 $ hg debugrevspec '0:wdir() & id(ffffffffffff)'
1358 $ hg debugrevspec '0:wdir() & id(ffffffffffff)'
1359 2147483647
1359 2147483647
1360
1360
1361 $ cd ..
1361 $ cd ..
1362
1362
1363 Test short 'ff...' hash collision
1363 Test short 'ff...' hash collision
1364 (BUG: '0:wdir()' is still needed to populate wdir revision)
1364 (BUG: '0:wdir()' is still needed to populate wdir revision)
1365
1365
1366 $ hg init wdir-hashcollision
1366 $ hg init wdir-hashcollision
1367 $ cd wdir-hashcollision
1367 $ cd wdir-hashcollision
1368 $ cat <<EOF >> .hg/hgrc
1368 $ cat <<EOF >> .hg/hgrc
1369 > [experimental]
1369 > [experimental]
1370 > evolution = createmarkers
1370 > evolution = createmarkers
1371 > EOF
1371 > EOF
1372 $ echo 0 > a
1372 $ echo 0 > a
1373 $ hg ci -qAm 0
1373 $ hg ci -qAm 0
1374 $ for i in 2463 2961 6726 78127; do
1374 $ for i in 2463 2961 6726 78127; do
1375 > hg up -q 0
1375 > hg up -q 0
1376 > echo $i > a
1376 > echo $i > a
1377 > hg ci -qm $i
1377 > hg ci -qm $i
1378 > done
1378 > done
1379 $ hg up -q null
1379 $ hg up -q null
1380 $ hg log -r '0:wdir()' -T '{rev}:{node} {shortest(node, 3)}\n'
1380 $ hg log -r '0:wdir()' -T '{rev}:{node} {shortest(node, 3)}\n'
1381 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a b4e
1381 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a b4e
1382 1:fffbae3886c8fbb2114296380d276fd37715d571 fffba
1382 1:fffbae3886c8fbb2114296380d276fd37715d571 fffba
1383 2:fffb6093b00943f91034b9bdad069402c834e572 fffb6
1383 2:fffb6093b00943f91034b9bdad069402c834e572 fffb6
1384 3:fff48a9b9de34a4d64120c29548214c67980ade3 fff4
1384 3:fff48a9b9de34a4d64120c29548214c67980ade3 fff4
1385 4:ffff85cff0ff78504fcdc3c0bc10de0c65379249 ffff8
1385 4:ffff85cff0ff78504fcdc3c0bc10de0c65379249 ffff8
1386 2147483647:ffffffffffffffffffffffffffffffffffffffff fffff
1386 2147483647:ffffffffffffffffffffffffffffffffffffffff fffff
1387 $ hg debugobsolete fffbae3886c8fbb2114296380d276fd37715d571
1387 $ hg debugobsolete fffbae3886c8fbb2114296380d276fd37715d571
1388
1388
1389 $ hg debugrevspec '0:wdir() & fff'
1389 $ hg debugrevspec '0:wdir() & fff'
1390 abort: 00changelog.i@fff: ambiguous identifier!
1390 abort: 00changelog.i@fff: ambiguous identifier!
1391 [255]
1391 [255]
1392 $ hg debugrevspec '0:wdir() & ffff'
1392 $ hg debugrevspec '0:wdir() & ffff'
1393 abort: 00changelog.i@ffff: ambiguous identifier!
1393 abort: 00changelog.i@ffff: ambiguous identifier!
1394 [255]
1394 [255]
1395 $ hg debugrevspec '0:wdir() & fffb'
1395 $ hg debugrevspec '0:wdir() & fffb'
1396 abort: 00changelog.i@fffb: ambiguous identifier!
1396 abort: 00changelog.i@fffb: ambiguous identifier!
1397 [255]
1397 [255]
1398 BROKEN should be '2' (node lookup uses unfiltered repo since dc25ed84bee8)
1398 BROKEN should be '2' (node lookup uses unfiltered repo since dc25ed84bee8)
1399 $ hg debugrevspec '0:wdir() & id(fffb)'
1399 $ hg debugrevspec '0:wdir() & id(fffb)'
1400 2
1400 2
1401 $ hg debugrevspec '0:wdir() & ffff8'
1401 $ hg debugrevspec '0:wdir() & ffff8'
1402 4
1402 4
1403 $ hg debugrevspec '0:wdir() & fffff'
1403 $ hg debugrevspec '0:wdir() & fffff'
1404 2147483647
1404 2147483647
1405
1405
1406 $ cd ..
1406 $ cd ..
1407
1407
1408 Test branch() with wdir()
1408 Test branch() with wdir()
1409
1409
1410 $ cd repo
1410 $ cd repo
1411
1411
1412 $ log '0:wdir() & branch("literal:Γ©")'
1412 $ log '0:wdir() & branch("literal:Γ©")'
1413 8
1413 8
1414 9
1414 9
1415 2147483647
1415 2147483647
1416 $ log '0:wdir() & branch("re:Γ©")'
1416 $ log '0:wdir() & branch("re:Γ©")'
1417 8
1417 8
1418 9
1418 9
1419 2147483647
1419 2147483647
1420 $ log '0:wdir() & branch("re:^a")'
1420 $ log '0:wdir() & branch("re:^a")'
1421 0
1421 0
1422 2
1422 2
1423 $ log '0:wdir() & branch(8)'
1423 $ log '0:wdir() & branch(8)'
1424 8
1424 8
1425 9
1425 9
1426 2147483647
1426 2147483647
1427
1427
1428 branch(wdir()) returns all revisions belonging to the working branch. The wdir
1428 branch(wdir()) returns all revisions belonging to the working branch. The wdir
1429 itself isn't returned unless it is explicitly populated.
1429 itself isn't returned unless it is explicitly populated.
1430
1430
1431 $ log 'branch(wdir())'
1431 $ log 'branch(wdir())'
1432 8
1432 8
1433 9
1433 9
1434 $ log '0:wdir() & branch(wdir())'
1434 $ log '0:wdir() & branch(wdir())'
1435 8
1435 8
1436 9
1436 9
1437 2147483647
1437 2147483647
1438
1438
1439 $ log 'outgoing()'
1439 $ log 'outgoing()'
1440 8
1440 8
1441 9
1441 9
1442 $ log 'outgoing("../remote1")'
1442 $ log 'outgoing("../remote1")'
1443 8
1443 8
1444 9
1444 9
1445 $ log 'outgoing("../remote2")'
1445 $ log 'outgoing("../remote2")'
1446 3
1446 3
1447 5
1447 5
1448 6
1448 6
1449 7
1449 7
1450 9
1450 9
1451 $ log 'p1(merge())'
1451 $ log 'p1(merge())'
1452 5
1452 5
1453 $ log 'p2(merge())'
1453 $ log 'p2(merge())'
1454 4
1454 4
1455 $ log 'parents(merge())'
1455 $ log 'parents(merge())'
1456 4
1456 4
1457 5
1457 5
1458 $ log 'p1(branchpoint())'
1458 $ log 'p1(branchpoint())'
1459 0
1459 0
1460 2
1460 2
1461 $ log 'p2(branchpoint())'
1461 $ log 'p2(branchpoint())'
1462 $ log 'parents(branchpoint())'
1462 $ log 'parents(branchpoint())'
1463 0
1463 0
1464 2
1464 2
1465 $ log 'removes(a)'
1465 $ log 'removes(a)'
1466 2
1466 2
1467 6
1467 6
1468 $ log 'roots(all())'
1468 $ log 'roots(all())'
1469 0
1469 0
1470 $ log 'reverse(2 or 3 or 4 or 5)'
1470 $ log 'reverse(2 or 3 or 4 or 5)'
1471 5
1471 5
1472 4
1472 4
1473 3
1473 3
1474 2
1474 2
1475 $ log 'reverse(all())'
1475 $ log 'reverse(all())'
1476 9
1476 9
1477 8
1477 8
1478 7
1478 7
1479 6
1479 6
1480 5
1480 5
1481 4
1481 4
1482 3
1482 3
1483 2
1483 2
1484 1
1484 1
1485 0
1485 0
1486 $ log 'reverse(all()) & filelog(b)'
1486 $ log 'reverse(all()) & filelog(b)'
1487 4
1487 4
1488 1
1488 1
1489 $ log 'rev(5)'
1489 $ log 'rev(5)'
1490 5
1490 5
1491 $ log 'sort(limit(reverse(all()), 3))'
1491 $ log 'sort(limit(reverse(all()), 3))'
1492 7
1492 7
1493 8
1493 8
1494 9
1494 9
1495 $ log 'sort(2 or 3 or 4 or 5, date)'
1495 $ log 'sort(2 or 3 or 4 or 5, date)'
1496 2
1496 2
1497 3
1497 3
1498 5
1498 5
1499 4
1499 4
1500 $ log 'tagged()'
1500 $ log 'tagged()'
1501 6
1501 6
1502 $ log 'tag()'
1502 $ log 'tag()'
1503 6
1503 6
1504 $ log 'tag(1.0)'
1504 $ log 'tag(1.0)'
1505 6
1505 6
1506 $ log 'tag(tip)'
1506 $ log 'tag(tip)'
1507 9
1507 9
1508
1508
1509 Test order of revisions in compound expression
1509 Test order of revisions in compound expression
1510 ----------------------------------------------
1510 ----------------------------------------------
1511
1511
1512 The general rule is that only the outermost (= leftmost) predicate can
1512 The general rule is that only the outermost (= leftmost) predicate can
1513 enforce its ordering requirement. The other predicates should take the
1513 enforce its ordering requirement. The other predicates should take the
1514 ordering defined by it.
1514 ordering defined by it.
1515
1515
1516 'A & B' should follow the order of 'A':
1516 'A & B' should follow the order of 'A':
1517
1517
1518 $ log '2:0 & 0::2'
1518 $ log '2:0 & 0::2'
1519 2
1519 2
1520 1
1520 1
1521 0
1521 0
1522
1522
1523 'head()' combines sets in right order:
1523 'head()' combines sets in right order:
1524
1524
1525 $ log '2:0 & head()'
1525 $ log '2:0 & head()'
1526 2
1526 2
1527 1
1527 1
1528 0
1528 0
1529
1529
1530 'x:y' takes ordering parameter into account:
1530 'x:y' takes ordering parameter into account:
1531
1531
1532 $ try -p optimized '3:0 & 0:3 & not 2:1'
1532 $ try -p optimized '3:0 & 0:3 & not 2:1'
1533 * optimized:
1533 * optimized:
1534 (difference
1534 (difference
1535 (and
1535 (and
1536 (range
1536 (range
1537 ('symbol', '3')
1537 ('symbol', '3')
1538 ('symbol', '0')
1538 ('symbol', '0')
1539 define)
1539 define)
1540 (range
1540 (range
1541 ('symbol', '0')
1541 ('symbol', '0')
1542 ('symbol', '3')
1542 ('symbol', '3')
1543 follow)
1543 follow)
1544 define)
1544 define)
1545 (range
1545 (range
1546 ('symbol', '2')
1546 ('symbol', '2')
1547 ('symbol', '1')
1547 ('symbol', '1')
1548 any)
1548 any)
1549 define)
1549 define)
1550 * set:
1550 * set:
1551 <filteredset
1551 <filteredset
1552 <filteredset
1552 <filteredset
1553 <spanset- 0:3>,
1553 <spanset- 0:4>,
1554 <spanset+ 0:3>>,
1554 <spanset+ 0:4>>,
1555 <not
1555 <not
1556 <spanset+ 1:2>>>
1556 <spanset+ 1:3>>>
1557 3
1557 3
1558 0
1558 0
1559
1559
1560 'a + b', which is optimized to '_list(a b)', should take the ordering of
1560 'a + b', which is optimized to '_list(a b)', should take the ordering of
1561 the left expression:
1561 the left expression:
1562
1562
1563 $ try --optimize '2:0 & (0 + 1 + 2)'
1563 $ try --optimize '2:0 & (0 + 1 + 2)'
1564 (and
1564 (and
1565 (range
1565 (range
1566 ('symbol', '2')
1566 ('symbol', '2')
1567 ('symbol', '0'))
1567 ('symbol', '0'))
1568 (group
1568 (group
1569 (or
1569 (or
1570 (list
1570 (list
1571 ('symbol', '0')
1571 ('symbol', '0')
1572 ('symbol', '1')
1572 ('symbol', '1')
1573 ('symbol', '2')))))
1573 ('symbol', '2')))))
1574 * optimized:
1574 * optimized:
1575 (and
1575 (and
1576 (range
1576 (range
1577 ('symbol', '2')
1577 ('symbol', '2')
1578 ('symbol', '0')
1578 ('symbol', '0')
1579 define)
1579 define)
1580 (func
1580 (func
1581 ('symbol', '_list')
1581 ('symbol', '_list')
1582 ('string', '0\x001\x002')
1582 ('string', '0\x001\x002')
1583 follow)
1583 follow)
1584 define)
1584 define)
1585 * set:
1585 * set:
1586 <filteredset
1586 <filteredset
1587 <spanset- 0:2>,
1587 <spanset- 0:3>,
1588 <baseset [0, 1, 2]>>
1588 <baseset [0, 1, 2]>>
1589 2
1589 2
1590 1
1590 1
1591 0
1591 0
1592
1592
1593 'A + B' should take the ordering of the left expression:
1593 'A + B' should take the ordering of the left expression:
1594
1594
1595 $ try --optimize '2:0 & (0:1 + 2)'
1595 $ try --optimize '2:0 & (0:1 + 2)'
1596 (and
1596 (and
1597 (range
1597 (range
1598 ('symbol', '2')
1598 ('symbol', '2')
1599 ('symbol', '0'))
1599 ('symbol', '0'))
1600 (group
1600 (group
1601 (or
1601 (or
1602 (list
1602 (list
1603 (range
1603 (range
1604 ('symbol', '0')
1604 ('symbol', '0')
1605 ('symbol', '1'))
1605 ('symbol', '1'))
1606 ('symbol', '2')))))
1606 ('symbol', '2')))))
1607 * optimized:
1607 * optimized:
1608 (and
1608 (and
1609 (range
1609 (range
1610 ('symbol', '2')
1610 ('symbol', '2')
1611 ('symbol', '0')
1611 ('symbol', '0')
1612 define)
1612 define)
1613 (or
1613 (or
1614 (list
1614 (list
1615 ('symbol', '2')
1615 ('symbol', '2')
1616 (range
1616 (range
1617 ('symbol', '0')
1617 ('symbol', '0')
1618 ('symbol', '1')
1618 ('symbol', '1')
1619 follow))
1619 follow))
1620 follow)
1620 follow)
1621 define)
1621 define)
1622 * set:
1622 * set:
1623 <filteredset
1623 <filteredset
1624 <spanset- 0:2>,
1624 <spanset- 0:3>,
1625 <addset
1625 <addset
1626 <baseset [2]>,
1626 <baseset [2]>,
1627 <spanset+ 0:1>>>
1627 <spanset+ 0:2>>>
1628 2
1628 2
1629 1
1629 1
1630 0
1630 0
1631
1631
1632 '_intlist(a b)' should behave like 'a + b':
1632 '_intlist(a b)' should behave like 'a + b':
1633
1633
1634 $ trylist --optimize '2:0 & %ld' 0 1 2
1634 $ trylist --optimize '2:0 & %ld' 0 1 2
1635 (and
1635 (and
1636 (range
1636 (range
1637 ('symbol', '2')
1637 ('symbol', '2')
1638 ('symbol', '0'))
1638 ('symbol', '0'))
1639 (func
1639 (func
1640 ('symbol', '_intlist')
1640 ('symbol', '_intlist')
1641 ('string', '0\x001\x002')))
1641 ('string', '0\x001\x002')))
1642 * optimized:
1642 * optimized:
1643 (and
1643 (and
1644 (func
1644 (func
1645 ('symbol', '_intlist')
1645 ('symbol', '_intlist')
1646 ('string', '0\x001\x002')
1646 ('string', '0\x001\x002')
1647 follow)
1647 follow)
1648 (range
1648 (range
1649 ('symbol', '2')
1649 ('symbol', '2')
1650 ('symbol', '0')
1650 ('symbol', '0')
1651 define)
1651 define)
1652 define)
1652 define)
1653 * set:
1653 * set:
1654 <filteredset
1654 <filteredset
1655 <spanset- 0:2>,
1655 <spanset- 0:3>,
1656 <baseset+ [0, 1, 2]>>
1656 <baseset+ [0, 1, 2]>>
1657 2
1657 2
1658 1
1658 1
1659 0
1659 0
1660
1660
1661 $ trylist --optimize '%ld & 2:0' 0 2 1
1661 $ trylist --optimize '%ld & 2:0' 0 2 1
1662 (and
1662 (and
1663 (func
1663 (func
1664 ('symbol', '_intlist')
1664 ('symbol', '_intlist')
1665 ('string', '0\x002\x001'))
1665 ('string', '0\x002\x001'))
1666 (range
1666 (range
1667 ('symbol', '2')
1667 ('symbol', '2')
1668 ('symbol', '0')))
1668 ('symbol', '0')))
1669 * optimized:
1669 * optimized:
1670 (and
1670 (and
1671 (func
1671 (func
1672 ('symbol', '_intlist')
1672 ('symbol', '_intlist')
1673 ('string', '0\x002\x001')
1673 ('string', '0\x002\x001')
1674 define)
1674 define)
1675 (range
1675 (range
1676 ('symbol', '2')
1676 ('symbol', '2')
1677 ('symbol', '0')
1677 ('symbol', '0')
1678 follow)
1678 follow)
1679 define)
1679 define)
1680 * set:
1680 * set:
1681 <filteredset
1681 <filteredset
1682 <baseset [0, 2, 1]>,
1682 <baseset [0, 2, 1]>,
1683 <spanset- 0:2>>
1683 <spanset- 0:3>>
1684 0
1684 0
1685 2
1685 2
1686 1
1686 1
1687
1687
1688 '_hexlist(a b)' should behave like 'a + b':
1688 '_hexlist(a b)' should behave like 'a + b':
1689
1689
1690 $ trylist --optimize --bin '2:0 & %ln' `hg log -T '{node} ' -r0:2`
1690 $ trylist --optimize --bin '2:0 & %ln' `hg log -T '{node} ' -r0:2`
1691 (and
1691 (and
1692 (range
1692 (range
1693 ('symbol', '2')
1693 ('symbol', '2')
1694 ('symbol', '0'))
1694 ('symbol', '0'))
1695 (func
1695 (func
1696 ('symbol', '_hexlist')
1696 ('symbol', '_hexlist')
1697 ('string', '*'))) (glob)
1697 ('string', '*'))) (glob)
1698 * optimized:
1698 * optimized:
1699 (and
1699 (and
1700 (range
1700 (range
1701 ('symbol', '2')
1701 ('symbol', '2')
1702 ('symbol', '0')
1702 ('symbol', '0')
1703 define)
1703 define)
1704 (func
1704 (func
1705 ('symbol', '_hexlist')
1705 ('symbol', '_hexlist')
1706 ('string', '*') (glob)
1706 ('string', '*') (glob)
1707 follow)
1707 follow)
1708 define)
1708 define)
1709 * set:
1709 * set:
1710 <filteredset
1710 <filteredset
1711 <spanset- 0:2>,
1711 <spanset- 0:3>,
1712 <baseset [0, 1, 2]>>
1712 <baseset [0, 1, 2]>>
1713 2
1713 2
1714 1
1714 1
1715 0
1715 0
1716
1716
1717 $ trylist --optimize --bin '%ln & 2:0' `hg log -T '{node} ' -r0+2+1`
1717 $ trylist --optimize --bin '%ln & 2:0' `hg log -T '{node} ' -r0+2+1`
1718 (and
1718 (and
1719 (func
1719 (func
1720 ('symbol', '_hexlist')
1720 ('symbol', '_hexlist')
1721 ('string', '*')) (glob)
1721 ('string', '*')) (glob)
1722 (range
1722 (range
1723 ('symbol', '2')
1723 ('symbol', '2')
1724 ('symbol', '0')))
1724 ('symbol', '0')))
1725 * optimized:
1725 * optimized:
1726 (and
1726 (and
1727 (range
1727 (range
1728 ('symbol', '2')
1728 ('symbol', '2')
1729 ('symbol', '0')
1729 ('symbol', '0')
1730 follow)
1730 follow)
1731 (func
1731 (func
1732 ('symbol', '_hexlist')
1732 ('symbol', '_hexlist')
1733 ('string', '*') (glob)
1733 ('string', '*') (glob)
1734 define)
1734 define)
1735 define)
1735 define)
1736 * set:
1736 * set:
1737 <baseset [0, 2, 1]>
1737 <baseset [0, 2, 1]>
1738 0
1738 0
1739 2
1739 2
1740 1
1740 1
1741
1741
1742 '_list' should not go through the slow follow-order path if order doesn't
1742 '_list' should not go through the slow follow-order path if order doesn't
1743 matter:
1743 matter:
1744
1744
1745 $ try -p optimized '2:0 & not (0 + 1)'
1745 $ try -p optimized '2:0 & not (0 + 1)'
1746 * optimized:
1746 * optimized:
1747 (difference
1747 (difference
1748 (range
1748 (range
1749 ('symbol', '2')
1749 ('symbol', '2')
1750 ('symbol', '0')
1750 ('symbol', '0')
1751 define)
1751 define)
1752 (func
1752 (func
1753 ('symbol', '_list')
1753 ('symbol', '_list')
1754 ('string', '0\x001')
1754 ('string', '0\x001')
1755 any)
1755 any)
1756 define)
1756 define)
1757 * set:
1757 * set:
1758 <filteredset
1758 <filteredset
1759 <spanset- 0:2>,
1759 <spanset- 0:3>,
1760 <not
1760 <not
1761 <baseset [0, 1]>>>
1761 <baseset [0, 1]>>>
1762 2
1762 2
1763
1763
1764 $ try -p optimized '2:0 & not (0:2 & (0 + 1))'
1764 $ try -p optimized '2:0 & not (0:2 & (0 + 1))'
1765 * optimized:
1765 * optimized:
1766 (difference
1766 (difference
1767 (range
1767 (range
1768 ('symbol', '2')
1768 ('symbol', '2')
1769 ('symbol', '0')
1769 ('symbol', '0')
1770 define)
1770 define)
1771 (and
1771 (and
1772 (range
1772 (range
1773 ('symbol', '0')
1773 ('symbol', '0')
1774 ('symbol', '2')
1774 ('symbol', '2')
1775 any)
1775 any)
1776 (func
1776 (func
1777 ('symbol', '_list')
1777 ('symbol', '_list')
1778 ('string', '0\x001')
1778 ('string', '0\x001')
1779 any)
1779 any)
1780 any)
1780 any)
1781 define)
1781 define)
1782 * set:
1782 * set:
1783 <filteredset
1783 <filteredset
1784 <spanset- 0:2>,
1784 <spanset- 0:3>,
1785 <not
1785 <not
1786 <baseset [0, 1]>>>
1786 <baseset [0, 1]>>>
1787 2
1787 2
1788
1788
1789 because 'present()' does nothing other than suppressing an error, the
1789 because 'present()' does nothing other than suppressing an error, the
1790 ordering requirement should be forwarded to the nested expression
1790 ordering requirement should be forwarded to the nested expression
1791
1791
1792 $ try -p optimized 'present(2 + 0 + 1)'
1792 $ try -p optimized 'present(2 + 0 + 1)'
1793 * optimized:
1793 * optimized:
1794 (func
1794 (func
1795 ('symbol', 'present')
1795 ('symbol', 'present')
1796 (func
1796 (func
1797 ('symbol', '_list')
1797 ('symbol', '_list')
1798 ('string', '2\x000\x001')
1798 ('string', '2\x000\x001')
1799 define)
1799 define)
1800 define)
1800 define)
1801 * set:
1801 * set:
1802 <baseset [2, 0, 1]>
1802 <baseset [2, 0, 1]>
1803 2
1803 2
1804 0
1804 0
1805 1
1805 1
1806
1806
1807 $ try --optimize '2:0 & present(0 + 1 + 2)'
1807 $ try --optimize '2:0 & present(0 + 1 + 2)'
1808 (and
1808 (and
1809 (range
1809 (range
1810 ('symbol', '2')
1810 ('symbol', '2')
1811 ('symbol', '0'))
1811 ('symbol', '0'))
1812 (func
1812 (func
1813 ('symbol', 'present')
1813 ('symbol', 'present')
1814 (or
1814 (or
1815 (list
1815 (list
1816 ('symbol', '0')
1816 ('symbol', '0')
1817 ('symbol', '1')
1817 ('symbol', '1')
1818 ('symbol', '2')))))
1818 ('symbol', '2')))))
1819 * optimized:
1819 * optimized:
1820 (and
1820 (and
1821 (range
1821 (range
1822 ('symbol', '2')
1822 ('symbol', '2')
1823 ('symbol', '0')
1823 ('symbol', '0')
1824 define)
1824 define)
1825 (func
1825 (func
1826 ('symbol', 'present')
1826 ('symbol', 'present')
1827 (func
1827 (func
1828 ('symbol', '_list')
1828 ('symbol', '_list')
1829 ('string', '0\x001\x002')
1829 ('string', '0\x001\x002')
1830 follow)
1830 follow)
1831 follow)
1831 follow)
1832 define)
1832 define)
1833 * set:
1833 * set:
1834 <filteredset
1834 <filteredset
1835 <spanset- 0:2>,
1835 <spanset- 0:3>,
1836 <baseset [0, 1, 2]>>
1836 <baseset [0, 1, 2]>>
1837 2
1837 2
1838 1
1838 1
1839 0
1839 0
1840
1840
1841 'reverse()' should take effect only if it is the outermost expression:
1841 'reverse()' should take effect only if it is the outermost expression:
1842
1842
1843 $ try --optimize '0:2 & reverse(all())'
1843 $ try --optimize '0:2 & reverse(all())'
1844 (and
1844 (and
1845 (range
1845 (range
1846 ('symbol', '0')
1846 ('symbol', '0')
1847 ('symbol', '2'))
1847 ('symbol', '2'))
1848 (func
1848 (func
1849 ('symbol', 'reverse')
1849 ('symbol', 'reverse')
1850 (func
1850 (func
1851 ('symbol', 'all')
1851 ('symbol', 'all')
1852 None)))
1852 None)))
1853 * optimized:
1853 * optimized:
1854 (and
1854 (and
1855 (range
1855 (range
1856 ('symbol', '0')
1856 ('symbol', '0')
1857 ('symbol', '2')
1857 ('symbol', '2')
1858 define)
1858 define)
1859 (func
1859 (func
1860 ('symbol', 'reverse')
1860 ('symbol', 'reverse')
1861 (func
1861 (func
1862 ('symbol', 'all')
1862 ('symbol', 'all')
1863 None
1863 None
1864 define)
1864 define)
1865 follow)
1865 follow)
1866 define)
1866 define)
1867 * set:
1867 * set:
1868 <filteredset
1868 <filteredset
1869 <spanset+ 0:2>,
1869 <spanset+ 0:3>,
1870 <spanset+ 0:9>>
1870 <spanset+ 0:10>>
1871 0
1871 0
1872 1
1872 1
1873 2
1873 2
1874
1874
1875 'sort()' should take effect only if it is the outermost expression:
1875 'sort()' should take effect only if it is the outermost expression:
1876
1876
1877 $ try --optimize '0:2 & sort(all(), -rev)'
1877 $ try --optimize '0:2 & sort(all(), -rev)'
1878 (and
1878 (and
1879 (range
1879 (range
1880 ('symbol', '0')
1880 ('symbol', '0')
1881 ('symbol', '2'))
1881 ('symbol', '2'))
1882 (func
1882 (func
1883 ('symbol', 'sort')
1883 ('symbol', 'sort')
1884 (list
1884 (list
1885 (func
1885 (func
1886 ('symbol', 'all')
1886 ('symbol', 'all')
1887 None)
1887 None)
1888 (negate
1888 (negate
1889 ('symbol', 'rev')))))
1889 ('symbol', 'rev')))))
1890 * optimized:
1890 * optimized:
1891 (and
1891 (and
1892 (range
1892 (range
1893 ('symbol', '0')
1893 ('symbol', '0')
1894 ('symbol', '2')
1894 ('symbol', '2')
1895 define)
1895 define)
1896 (func
1896 (func
1897 ('symbol', 'sort')
1897 ('symbol', 'sort')
1898 (list
1898 (list
1899 (func
1899 (func
1900 ('symbol', 'all')
1900 ('symbol', 'all')
1901 None
1901 None
1902 define)
1902 define)
1903 ('string', '-rev'))
1903 ('string', '-rev'))
1904 follow)
1904 follow)
1905 define)
1905 define)
1906 * set:
1906 * set:
1907 <filteredset
1907 <filteredset
1908 <spanset+ 0:2>,
1908 <spanset+ 0:3>,
1909 <spanset+ 0:9>>
1909 <spanset+ 0:10>>
1910 0
1910 0
1911 1
1911 1
1912 2
1912 2
1913
1913
1914 invalid argument passed to noop sort():
1914 invalid argument passed to noop sort():
1915
1915
1916 $ log '0:2 & sort()'
1916 $ log '0:2 & sort()'
1917 hg: parse error: sort requires one or two arguments
1917 hg: parse error: sort requires one or two arguments
1918 [255]
1918 [255]
1919 $ log '0:2 & sort(all(), -invalid)'
1919 $ log '0:2 & sort(all(), -invalid)'
1920 hg: parse error: unknown sort key '-invalid'
1920 hg: parse error: unknown sort key '-invalid'
1921 [255]
1921 [255]
1922
1922
1923 for 'A & f(B)', 'B' should not be affected by the order of 'A':
1923 for 'A & f(B)', 'B' should not be affected by the order of 'A':
1924
1924
1925 $ try --optimize '2:0 & first(1 + 0 + 2)'
1925 $ try --optimize '2:0 & first(1 + 0 + 2)'
1926 (and
1926 (and
1927 (range
1927 (range
1928 ('symbol', '2')
1928 ('symbol', '2')
1929 ('symbol', '0'))
1929 ('symbol', '0'))
1930 (func
1930 (func
1931 ('symbol', 'first')
1931 ('symbol', 'first')
1932 (or
1932 (or
1933 (list
1933 (list
1934 ('symbol', '1')
1934 ('symbol', '1')
1935 ('symbol', '0')
1935 ('symbol', '0')
1936 ('symbol', '2')))))
1936 ('symbol', '2')))))
1937 * optimized:
1937 * optimized:
1938 (and
1938 (and
1939 (range
1939 (range
1940 ('symbol', '2')
1940 ('symbol', '2')
1941 ('symbol', '0')
1941 ('symbol', '0')
1942 define)
1942 define)
1943 (func
1943 (func
1944 ('symbol', 'first')
1944 ('symbol', 'first')
1945 (func
1945 (func
1946 ('symbol', '_list')
1946 ('symbol', '_list')
1947 ('string', '1\x000\x002')
1947 ('string', '1\x000\x002')
1948 define)
1948 define)
1949 follow)
1949 follow)
1950 define)
1950 define)
1951 * set:
1951 * set:
1952 <filteredset
1952 <filteredset
1953 <baseset
1953 <baseset
1954 <limit n=1, offset=0,
1954 <limit n=1, offset=0,
1955 <baseset [1, 0, 2]>>>,
1955 <baseset [1, 0, 2]>>>,
1956 <spanset- 0:2>>
1956 <spanset- 0:3>>
1957 1
1957 1
1958
1958
1959 $ try --optimize '2:0 & not last(0 + 2 + 1)'
1959 $ try --optimize '2:0 & not last(0 + 2 + 1)'
1960 (and
1960 (and
1961 (range
1961 (range
1962 ('symbol', '2')
1962 ('symbol', '2')
1963 ('symbol', '0'))
1963 ('symbol', '0'))
1964 (not
1964 (not
1965 (func
1965 (func
1966 ('symbol', 'last')
1966 ('symbol', 'last')
1967 (or
1967 (or
1968 (list
1968 (list
1969 ('symbol', '0')
1969 ('symbol', '0')
1970 ('symbol', '2')
1970 ('symbol', '2')
1971 ('symbol', '1'))))))
1971 ('symbol', '1'))))))
1972 * optimized:
1972 * optimized:
1973 (difference
1973 (difference
1974 (range
1974 (range
1975 ('symbol', '2')
1975 ('symbol', '2')
1976 ('symbol', '0')
1976 ('symbol', '0')
1977 define)
1977 define)
1978 (func
1978 (func
1979 ('symbol', 'last')
1979 ('symbol', 'last')
1980 (func
1980 (func
1981 ('symbol', '_list')
1981 ('symbol', '_list')
1982 ('string', '0\x002\x001')
1982 ('string', '0\x002\x001')
1983 define)
1983 define)
1984 any)
1984 any)
1985 define)
1985 define)
1986 * set:
1986 * set:
1987 <filteredset
1987 <filteredset
1988 <spanset- 0:2>,
1988 <spanset- 0:3>,
1989 <not
1989 <not
1990 <baseset
1990 <baseset
1991 <last n=1,
1991 <last n=1,
1992 <baseset [1, 2, 0]>>>>>
1992 <baseset [1, 2, 0]>>>>>
1993 2
1993 2
1994 0
1994 0
1995
1995
1996 for 'A & (op)(B)', 'B' should not be affected by the order of 'A':
1996 for 'A & (op)(B)', 'B' should not be affected by the order of 'A':
1997
1997
1998 $ try --optimize '2:0 & (1 + 0 + 2):(0 + 2 + 1)'
1998 $ try --optimize '2:0 & (1 + 0 + 2):(0 + 2 + 1)'
1999 (and
1999 (and
2000 (range
2000 (range
2001 ('symbol', '2')
2001 ('symbol', '2')
2002 ('symbol', '0'))
2002 ('symbol', '0'))
2003 (range
2003 (range
2004 (group
2004 (group
2005 (or
2005 (or
2006 (list
2006 (list
2007 ('symbol', '1')
2007 ('symbol', '1')
2008 ('symbol', '0')
2008 ('symbol', '0')
2009 ('symbol', '2'))))
2009 ('symbol', '2'))))
2010 (group
2010 (group
2011 (or
2011 (or
2012 (list
2012 (list
2013 ('symbol', '0')
2013 ('symbol', '0')
2014 ('symbol', '2')
2014 ('symbol', '2')
2015 ('symbol', '1'))))))
2015 ('symbol', '1'))))))
2016 * optimized:
2016 * optimized:
2017 (and
2017 (and
2018 (range
2018 (range
2019 ('symbol', '2')
2019 ('symbol', '2')
2020 ('symbol', '0')
2020 ('symbol', '0')
2021 define)
2021 define)
2022 (range
2022 (range
2023 (func
2023 (func
2024 ('symbol', '_list')
2024 ('symbol', '_list')
2025 ('string', '1\x000\x002')
2025 ('string', '1\x000\x002')
2026 define)
2026 define)
2027 (func
2027 (func
2028 ('symbol', '_list')
2028 ('symbol', '_list')
2029 ('string', '0\x002\x001')
2029 ('string', '0\x002\x001')
2030 define)
2030 define)
2031 follow)
2031 follow)
2032 define)
2032 define)
2033 * set:
2033 * set:
2034 <filteredset
2034 <filteredset
2035 <spanset- 0:2>,
2035 <spanset- 0:3>,
2036 <baseset [1]>>
2036 <baseset [1]>>
2037 1
2037 1
2038
2038
2039 'A & B' can be rewritten as 'B & A' by weight, but that's fine as long as
2039 'A & B' can be rewritten as 'B & A' by weight, but that's fine as long as
2040 the ordering rule is determined before the rewrite; in this example,
2040 the ordering rule is determined before the rewrite; in this example,
2041 'B' follows the order of the initial set, which is the same order as 'A'
2041 'B' follows the order of the initial set, which is the same order as 'A'
2042 since 'A' also follows the order:
2042 since 'A' also follows the order:
2043
2043
2044 $ try --optimize 'contains("glob:*") & (2 + 0 + 1)'
2044 $ try --optimize 'contains("glob:*") & (2 + 0 + 1)'
2045 (and
2045 (and
2046 (func
2046 (func
2047 ('symbol', 'contains')
2047 ('symbol', 'contains')
2048 ('string', 'glob:*'))
2048 ('string', 'glob:*'))
2049 (group
2049 (group
2050 (or
2050 (or
2051 (list
2051 (list
2052 ('symbol', '2')
2052 ('symbol', '2')
2053 ('symbol', '0')
2053 ('symbol', '0')
2054 ('symbol', '1')))))
2054 ('symbol', '1')))))
2055 * optimized:
2055 * optimized:
2056 (and
2056 (and
2057 (func
2057 (func
2058 ('symbol', '_list')
2058 ('symbol', '_list')
2059 ('string', '2\x000\x001')
2059 ('string', '2\x000\x001')
2060 follow)
2060 follow)
2061 (func
2061 (func
2062 ('symbol', 'contains')
2062 ('symbol', 'contains')
2063 ('string', 'glob:*')
2063 ('string', 'glob:*')
2064 define)
2064 define)
2065 define)
2065 define)
2066 * set:
2066 * set:
2067 <filteredset
2067 <filteredset
2068 <baseset+ [0, 1, 2]>,
2068 <baseset+ [0, 1, 2]>,
2069 <contains 'glob:*'>>
2069 <contains 'glob:*'>>
2070 0
2070 0
2071 1
2071 1
2072 2
2072 2
2073
2073
2074 and in this example, 'A & B' is rewritten as 'B & A', but 'A' overrides
2074 and in this example, 'A & B' is rewritten as 'B & A', but 'A' overrides
2075 the order appropriately:
2075 the order appropriately:
2076
2076
2077 $ try --optimize 'reverse(contains("glob:*")) & (0 + 2 + 1)'
2077 $ try --optimize 'reverse(contains("glob:*")) & (0 + 2 + 1)'
2078 (and
2078 (and
2079 (func
2079 (func
2080 ('symbol', 'reverse')
2080 ('symbol', 'reverse')
2081 (func
2081 (func
2082 ('symbol', 'contains')
2082 ('symbol', 'contains')
2083 ('string', 'glob:*')))
2083 ('string', 'glob:*')))
2084 (group
2084 (group
2085 (or
2085 (or
2086 (list
2086 (list
2087 ('symbol', '0')
2087 ('symbol', '0')
2088 ('symbol', '2')
2088 ('symbol', '2')
2089 ('symbol', '1')))))
2089 ('symbol', '1')))))
2090 * optimized:
2090 * optimized:
2091 (and
2091 (and
2092 (func
2092 (func
2093 ('symbol', '_list')
2093 ('symbol', '_list')
2094 ('string', '0\x002\x001')
2094 ('string', '0\x002\x001')
2095 follow)
2095 follow)
2096 (func
2096 (func
2097 ('symbol', 'reverse')
2097 ('symbol', 'reverse')
2098 (func
2098 (func
2099 ('symbol', 'contains')
2099 ('symbol', 'contains')
2100 ('string', 'glob:*')
2100 ('string', 'glob:*')
2101 define)
2101 define)
2102 define)
2102 define)
2103 define)
2103 define)
2104 * set:
2104 * set:
2105 <filteredset
2105 <filteredset
2106 <baseset- [0, 1, 2]>,
2106 <baseset- [0, 1, 2]>,
2107 <contains 'glob:*'>>
2107 <contains 'glob:*'>>
2108 2
2108 2
2109 1
2109 1
2110 0
2110 0
2111
2111
2112 'A + B' can be rewritten to 'B + A' by weight only when the order doesn't
2112 'A + B' can be rewritten to 'B + A' by weight only when the order doesn't
2113 matter (e.g. 'X & (A + B)' can be 'X & (B + A)', but '(A + B) & X' can't):
2113 matter (e.g. 'X & (A + B)' can be 'X & (B + A)', but '(A + B) & X' can't):
2114
2114
2115 $ try -p optimized '0:2 & (reverse(contains("a")) + 2)'
2115 $ try -p optimized '0:2 & (reverse(contains("a")) + 2)'
2116 * optimized:
2116 * optimized:
2117 (and
2117 (and
2118 (range
2118 (range
2119 ('symbol', '0')
2119 ('symbol', '0')
2120 ('symbol', '2')
2120 ('symbol', '2')
2121 define)
2121 define)
2122 (or
2122 (or
2123 (list
2123 (list
2124 ('symbol', '2')
2124 ('symbol', '2')
2125 (func
2125 (func
2126 ('symbol', 'reverse')
2126 ('symbol', 'reverse')
2127 (func
2127 (func
2128 ('symbol', 'contains')
2128 ('symbol', 'contains')
2129 ('string', 'a')
2129 ('string', 'a')
2130 define)
2130 define)
2131 follow))
2131 follow))
2132 follow)
2132 follow)
2133 define)
2133 define)
2134 * set:
2134 * set:
2135 <filteredset
2135 <filteredset
2136 <spanset+ 0:2>,
2136 <spanset+ 0:3>,
2137 <addset
2137 <addset
2138 <baseset [2]>,
2138 <baseset [2]>,
2139 <filteredset
2139 <filteredset
2140 <fullreposet+ 0:9>,
2140 <fullreposet+ 0:10>,
2141 <contains 'a'>>>>
2141 <contains 'a'>>>>
2142 0
2142 0
2143 1
2143 1
2144 2
2144 2
2145
2145
2146 $ try -p optimized '(reverse(contains("a")) + 2) & 0:2'
2146 $ try -p optimized '(reverse(contains("a")) + 2) & 0:2'
2147 * optimized:
2147 * optimized:
2148 (and
2148 (and
2149 (range
2149 (range
2150 ('symbol', '0')
2150 ('symbol', '0')
2151 ('symbol', '2')
2151 ('symbol', '2')
2152 follow)
2152 follow)
2153 (or
2153 (or
2154 (list
2154 (list
2155 (func
2155 (func
2156 ('symbol', 'reverse')
2156 ('symbol', 'reverse')
2157 (func
2157 (func
2158 ('symbol', 'contains')
2158 ('symbol', 'contains')
2159 ('string', 'a')
2159 ('string', 'a')
2160 define)
2160 define)
2161 define)
2161 define)
2162 ('symbol', '2'))
2162 ('symbol', '2'))
2163 define)
2163 define)
2164 define)
2164 define)
2165 * set:
2165 * set:
2166 <addset
2166 <addset
2167 <filteredset
2167 <filteredset
2168 <spanset- 0:2>,
2168 <spanset- 0:3>,
2169 <contains 'a'>>,
2169 <contains 'a'>>,
2170 <baseset [2]>>
2170 <baseset [2]>>
2171 1
2171 1
2172 0
2172 0
2173 2
2173 2
2174
2174
2175 test sort revset
2175 test sort revset
2176 --------------------------------------------
2176 --------------------------------------------
2177
2177
2178 test when adding two unordered revsets
2178 test when adding two unordered revsets
2179
2179
2180 $ log 'sort(keyword(issue) or modifies(b))'
2180 $ log 'sort(keyword(issue) or modifies(b))'
2181 4
2181 4
2182 6
2182 6
2183
2183
2184 test when sorting a reversed collection in the same way it is
2184 test when sorting a reversed collection in the same way it is
2185
2185
2186 $ log 'sort(reverse(all()), -rev)'
2186 $ log 'sort(reverse(all()), -rev)'
2187 9
2187 9
2188 8
2188 8
2189 7
2189 7
2190 6
2190 6
2191 5
2191 5
2192 4
2192 4
2193 3
2193 3
2194 2
2194 2
2195 1
2195 1
2196 0
2196 0
2197
2197
2198 test when sorting a reversed collection
2198 test when sorting a reversed collection
2199
2199
2200 $ log 'sort(reverse(all()), rev)'
2200 $ log 'sort(reverse(all()), rev)'
2201 0
2201 0
2202 1
2202 1
2203 2
2203 2
2204 3
2204 3
2205 4
2205 4
2206 5
2206 5
2207 6
2207 6
2208 7
2208 7
2209 8
2209 8
2210 9
2210 9
2211
2211
2212
2212
2213 test sorting two sorted collections in different orders
2213 test sorting two sorted collections in different orders
2214
2214
2215 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
2215 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
2216 2
2216 2
2217 6
2217 6
2218 8
2218 8
2219 9
2219 9
2220
2220
2221 test sorting two sorted collections in different orders backwards
2221 test sorting two sorted collections in different orders backwards
2222
2222
2223 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
2223 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
2224 9
2224 9
2225 8
2225 8
2226 6
2226 6
2227 2
2227 2
2228
2228
2229 test empty sort key which is noop
2229 test empty sort key which is noop
2230
2230
2231 $ log 'sort(0 + 2 + 1, "")'
2231 $ log 'sort(0 + 2 + 1, "")'
2232 0
2232 0
2233 2
2233 2
2234 1
2234 1
2235
2235
2236 test invalid sort keys
2236 test invalid sort keys
2237
2237
2238 $ log 'sort(all(), -invalid)'
2238 $ log 'sort(all(), -invalid)'
2239 hg: parse error: unknown sort key '-invalid'
2239 hg: parse error: unknown sort key '-invalid'
2240 [255]
2240 [255]
2241
2241
2242 $ cd ..
2242 $ cd ..
2243
2243
2244 test sorting by multiple keys including variable-length strings
2244 test sorting by multiple keys including variable-length strings
2245
2245
2246 $ hg init sorting
2246 $ hg init sorting
2247 $ cd sorting
2247 $ cd sorting
2248 $ cat <<EOF >> .hg/hgrc
2248 $ cat <<EOF >> .hg/hgrc
2249 > [ui]
2249 > [ui]
2250 > logtemplate = '{rev} {branch|p5}{desc|p5}{author|p5}{date|hgdate}\n'
2250 > logtemplate = '{rev} {branch|p5}{desc|p5}{author|p5}{date|hgdate}\n'
2251 > [templatealias]
2251 > [templatealias]
2252 > p5(s) = pad(s, 5)
2252 > p5(s) = pad(s, 5)
2253 > EOF
2253 > EOF
2254 $ hg branch -qf b12
2254 $ hg branch -qf b12
2255 $ hg ci -m m111 -u u112 -d '111 10800'
2255 $ hg ci -m m111 -u u112 -d '111 10800'
2256 $ hg branch -qf b11
2256 $ hg branch -qf b11
2257 $ hg ci -m m12 -u u111 -d '112 7200'
2257 $ hg ci -m m12 -u u111 -d '112 7200'
2258 $ hg branch -qf b111
2258 $ hg branch -qf b111
2259 $ hg ci -m m11 -u u12 -d '111 3600'
2259 $ hg ci -m m11 -u u12 -d '111 3600'
2260 $ hg branch -qf b112
2260 $ hg branch -qf b112
2261 $ hg ci -m m111 -u u11 -d '120 0'
2261 $ hg ci -m m111 -u u11 -d '120 0'
2262 $ hg branch -qf b111
2262 $ hg branch -qf b111
2263 $ hg ci -m m112 -u u111 -d '110 14400'
2263 $ hg ci -m m112 -u u111 -d '110 14400'
2264 created new head
2264 created new head
2265
2265
2266 compare revisions (has fast path):
2266 compare revisions (has fast path):
2267
2267
2268 $ hg log -r 'sort(all(), rev)'
2268 $ hg log -r 'sort(all(), rev)'
2269 0 b12 m111 u112 111 10800
2269 0 b12 m111 u112 111 10800
2270 1 b11 m12 u111 112 7200
2270 1 b11 m12 u111 112 7200
2271 2 b111 m11 u12 111 3600
2271 2 b111 m11 u12 111 3600
2272 3 b112 m111 u11 120 0
2272 3 b112 m111 u11 120 0
2273 4 b111 m112 u111 110 14400
2273 4 b111 m112 u111 110 14400
2274
2274
2275 $ hg log -r 'sort(all(), -rev)'
2275 $ hg log -r 'sort(all(), -rev)'
2276 4 b111 m112 u111 110 14400
2276 4 b111 m112 u111 110 14400
2277 3 b112 m111 u11 120 0
2277 3 b112 m111 u11 120 0
2278 2 b111 m11 u12 111 3600
2278 2 b111 m11 u12 111 3600
2279 1 b11 m12 u111 112 7200
2279 1 b11 m12 u111 112 7200
2280 0 b12 m111 u112 111 10800
2280 0 b12 m111 u112 111 10800
2281
2281
2282 compare variable-length strings (issue5218):
2282 compare variable-length strings (issue5218):
2283
2283
2284 $ hg log -r 'sort(all(), branch)'
2284 $ hg log -r 'sort(all(), branch)'
2285 1 b11 m12 u111 112 7200
2285 1 b11 m12 u111 112 7200
2286 2 b111 m11 u12 111 3600
2286 2 b111 m11 u12 111 3600
2287 4 b111 m112 u111 110 14400
2287 4 b111 m112 u111 110 14400
2288 3 b112 m111 u11 120 0
2288 3 b112 m111 u11 120 0
2289 0 b12 m111 u112 111 10800
2289 0 b12 m111 u112 111 10800
2290
2290
2291 $ hg log -r 'sort(all(), -branch)'
2291 $ hg log -r 'sort(all(), -branch)'
2292 0 b12 m111 u112 111 10800
2292 0 b12 m111 u112 111 10800
2293 3 b112 m111 u11 120 0
2293 3 b112 m111 u11 120 0
2294 2 b111 m11 u12 111 3600
2294 2 b111 m11 u12 111 3600
2295 4 b111 m112 u111 110 14400
2295 4 b111 m112 u111 110 14400
2296 1 b11 m12 u111 112 7200
2296 1 b11 m12 u111 112 7200
2297
2297
2298 $ hg log -r 'sort(all(), desc)'
2298 $ hg log -r 'sort(all(), desc)'
2299 2 b111 m11 u12 111 3600
2299 2 b111 m11 u12 111 3600
2300 0 b12 m111 u112 111 10800
2300 0 b12 m111 u112 111 10800
2301 3 b112 m111 u11 120 0
2301 3 b112 m111 u11 120 0
2302 4 b111 m112 u111 110 14400
2302 4 b111 m112 u111 110 14400
2303 1 b11 m12 u111 112 7200
2303 1 b11 m12 u111 112 7200
2304
2304
2305 $ hg log -r 'sort(all(), -desc)'
2305 $ hg log -r 'sort(all(), -desc)'
2306 1 b11 m12 u111 112 7200
2306 1 b11 m12 u111 112 7200
2307 4 b111 m112 u111 110 14400
2307 4 b111 m112 u111 110 14400
2308 0 b12 m111 u112 111 10800
2308 0 b12 m111 u112 111 10800
2309 3 b112 m111 u11 120 0
2309 3 b112 m111 u11 120 0
2310 2 b111 m11 u12 111 3600
2310 2 b111 m11 u12 111 3600
2311
2311
2312 $ hg log -r 'sort(all(), user)'
2312 $ hg log -r 'sort(all(), user)'
2313 3 b112 m111 u11 120 0
2313 3 b112 m111 u11 120 0
2314 1 b11 m12 u111 112 7200
2314 1 b11 m12 u111 112 7200
2315 4 b111 m112 u111 110 14400
2315 4 b111 m112 u111 110 14400
2316 0 b12 m111 u112 111 10800
2316 0 b12 m111 u112 111 10800
2317 2 b111 m11 u12 111 3600
2317 2 b111 m11 u12 111 3600
2318
2318
2319 $ hg log -r 'sort(all(), -user)'
2319 $ hg log -r 'sort(all(), -user)'
2320 2 b111 m11 u12 111 3600
2320 2 b111 m11 u12 111 3600
2321 0 b12 m111 u112 111 10800
2321 0 b12 m111 u112 111 10800
2322 1 b11 m12 u111 112 7200
2322 1 b11 m12 u111 112 7200
2323 4 b111 m112 u111 110 14400
2323 4 b111 m112 u111 110 14400
2324 3 b112 m111 u11 120 0
2324 3 b112 m111 u11 120 0
2325
2325
2326 compare dates (tz offset should have no effect):
2326 compare dates (tz offset should have no effect):
2327
2327
2328 $ hg log -r 'sort(all(), date)'
2328 $ hg log -r 'sort(all(), date)'
2329 4 b111 m112 u111 110 14400
2329 4 b111 m112 u111 110 14400
2330 0 b12 m111 u112 111 10800
2330 0 b12 m111 u112 111 10800
2331 2 b111 m11 u12 111 3600
2331 2 b111 m11 u12 111 3600
2332 1 b11 m12 u111 112 7200
2332 1 b11 m12 u111 112 7200
2333 3 b112 m111 u11 120 0
2333 3 b112 m111 u11 120 0
2334
2334
2335 $ hg log -r 'sort(all(), -date)'
2335 $ hg log -r 'sort(all(), -date)'
2336 3 b112 m111 u11 120 0
2336 3 b112 m111 u11 120 0
2337 1 b11 m12 u111 112 7200
2337 1 b11 m12 u111 112 7200
2338 0 b12 m111 u112 111 10800
2338 0 b12 m111 u112 111 10800
2339 2 b111 m11 u12 111 3600
2339 2 b111 m11 u12 111 3600
2340 4 b111 m112 u111 110 14400
2340 4 b111 m112 u111 110 14400
2341
2341
2342 be aware that 'sort(x, -k)' is not exactly the same as 'reverse(sort(x, k))'
2342 be aware that 'sort(x, -k)' is not exactly the same as 'reverse(sort(x, k))'
2343 because '-k' reverses the comparison, not the list itself:
2343 because '-k' reverses the comparison, not the list itself:
2344
2344
2345 $ hg log -r 'sort(0 + 2, date)'
2345 $ hg log -r 'sort(0 + 2, date)'
2346 0 b12 m111 u112 111 10800
2346 0 b12 m111 u112 111 10800
2347 2 b111 m11 u12 111 3600
2347 2 b111 m11 u12 111 3600
2348
2348
2349 $ hg log -r 'sort(0 + 2, -date)'
2349 $ hg log -r 'sort(0 + 2, -date)'
2350 0 b12 m111 u112 111 10800
2350 0 b12 m111 u112 111 10800
2351 2 b111 m11 u12 111 3600
2351 2 b111 m11 u12 111 3600
2352
2352
2353 $ hg log -r 'reverse(sort(0 + 2, date))'
2353 $ hg log -r 'reverse(sort(0 + 2, date))'
2354 2 b111 m11 u12 111 3600
2354 2 b111 m11 u12 111 3600
2355 0 b12 m111 u112 111 10800
2355 0 b12 m111 u112 111 10800
2356
2356
2357 sort by multiple keys:
2357 sort by multiple keys:
2358
2358
2359 $ hg log -r 'sort(all(), "branch -rev")'
2359 $ hg log -r 'sort(all(), "branch -rev")'
2360 1 b11 m12 u111 112 7200
2360 1 b11 m12 u111 112 7200
2361 4 b111 m112 u111 110 14400
2361 4 b111 m112 u111 110 14400
2362 2 b111 m11 u12 111 3600
2362 2 b111 m11 u12 111 3600
2363 3 b112 m111 u11 120 0
2363 3 b112 m111 u11 120 0
2364 0 b12 m111 u112 111 10800
2364 0 b12 m111 u112 111 10800
2365
2365
2366 $ hg log -r 'sort(all(), "-desc -date")'
2366 $ hg log -r 'sort(all(), "-desc -date")'
2367 1 b11 m12 u111 112 7200
2367 1 b11 m12 u111 112 7200
2368 4 b111 m112 u111 110 14400
2368 4 b111 m112 u111 110 14400
2369 3 b112 m111 u11 120 0
2369 3 b112 m111 u11 120 0
2370 0 b12 m111 u112 111 10800
2370 0 b12 m111 u112 111 10800
2371 2 b111 m11 u12 111 3600
2371 2 b111 m11 u12 111 3600
2372
2372
2373 $ hg log -r 'sort(all(), "user -branch date rev")'
2373 $ hg log -r 'sort(all(), "user -branch date rev")'
2374 3 b112 m111 u11 120 0
2374 3 b112 m111 u11 120 0
2375 4 b111 m112 u111 110 14400
2375 4 b111 m112 u111 110 14400
2376 1 b11 m12 u111 112 7200
2376 1 b11 m12 u111 112 7200
2377 0 b12 m111 u112 111 10800
2377 0 b12 m111 u112 111 10800
2378 2 b111 m11 u12 111 3600
2378 2 b111 m11 u12 111 3600
2379
2379
2380 toposort prioritises graph branches
2380 toposort prioritises graph branches
2381
2381
2382 $ hg up 2
2382 $ hg up 2
2383 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2383 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2384 $ touch a
2384 $ touch a
2385 $ hg addremove
2385 $ hg addremove
2386 adding a
2386 adding a
2387 $ hg ci -m 't1' -u 'tu' -d '130 0'
2387 $ hg ci -m 't1' -u 'tu' -d '130 0'
2388 created new head
2388 created new head
2389 $ echo 'a' >> a
2389 $ echo 'a' >> a
2390 $ hg ci -m 't2' -u 'tu' -d '130 0'
2390 $ hg ci -m 't2' -u 'tu' -d '130 0'
2391 $ hg book book1
2391 $ hg book book1
2392 $ hg up 4
2392 $ hg up 4
2393 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2393 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2394 (leaving bookmark book1)
2394 (leaving bookmark book1)
2395 $ touch a
2395 $ touch a
2396 $ hg addremove
2396 $ hg addremove
2397 adding a
2397 adding a
2398 $ hg ci -m 't3' -u 'tu' -d '130 0'
2398 $ hg ci -m 't3' -u 'tu' -d '130 0'
2399
2399
2400 $ hg log -r 'sort(all(), topo)'
2400 $ hg log -r 'sort(all(), topo)'
2401 7 b111 t3 tu 130 0
2401 7 b111 t3 tu 130 0
2402 4 b111 m112 u111 110 14400
2402 4 b111 m112 u111 110 14400
2403 3 b112 m111 u11 120 0
2403 3 b112 m111 u11 120 0
2404 6 b111 t2 tu 130 0
2404 6 b111 t2 tu 130 0
2405 5 b111 t1 tu 130 0
2405 5 b111 t1 tu 130 0
2406 2 b111 m11 u12 111 3600
2406 2 b111 m11 u12 111 3600
2407 1 b11 m12 u111 112 7200
2407 1 b11 m12 u111 112 7200
2408 0 b12 m111 u112 111 10800
2408 0 b12 m111 u112 111 10800
2409
2409
2410 $ hg log -r 'sort(all(), -topo)'
2410 $ hg log -r 'sort(all(), -topo)'
2411 0 b12 m111 u112 111 10800
2411 0 b12 m111 u112 111 10800
2412 1 b11 m12 u111 112 7200
2412 1 b11 m12 u111 112 7200
2413 2 b111 m11 u12 111 3600
2413 2 b111 m11 u12 111 3600
2414 5 b111 t1 tu 130 0
2414 5 b111 t1 tu 130 0
2415 6 b111 t2 tu 130 0
2415 6 b111 t2 tu 130 0
2416 3 b112 m111 u11 120 0
2416 3 b112 m111 u11 120 0
2417 4 b111 m112 u111 110 14400
2417 4 b111 m112 u111 110 14400
2418 7 b111 t3 tu 130 0
2418 7 b111 t3 tu 130 0
2419
2419
2420 $ hg log -r 'sort(all(), topo, topo.firstbranch=book1)'
2420 $ hg log -r 'sort(all(), topo, topo.firstbranch=book1)'
2421 6 b111 t2 tu 130 0
2421 6 b111 t2 tu 130 0
2422 5 b111 t1 tu 130 0
2422 5 b111 t1 tu 130 0
2423 7 b111 t3 tu 130 0
2423 7 b111 t3 tu 130 0
2424 4 b111 m112 u111 110 14400
2424 4 b111 m112 u111 110 14400
2425 3 b112 m111 u11 120 0
2425 3 b112 m111 u11 120 0
2426 2 b111 m11 u12 111 3600
2426 2 b111 m11 u12 111 3600
2427 1 b11 m12 u111 112 7200
2427 1 b11 m12 u111 112 7200
2428 0 b12 m111 u112 111 10800
2428 0 b12 m111 u112 111 10800
2429
2429
2430 topographical sorting can't be combined with other sort keys, and you can't
2430 topographical sorting can't be combined with other sort keys, and you can't
2431 use the topo.firstbranch option when topo sort is not active:
2431 use the topo.firstbranch option when topo sort is not active:
2432
2432
2433 $ hg log -r 'sort(all(), "topo user")'
2433 $ hg log -r 'sort(all(), "topo user")'
2434 hg: parse error: topo sort order cannot be combined with other sort keys
2434 hg: parse error: topo sort order cannot be combined with other sort keys
2435 [255]
2435 [255]
2436
2436
2437 $ hg log -r 'sort(all(), user, topo.firstbranch=book1)'
2437 $ hg log -r 'sort(all(), user, topo.firstbranch=book1)'
2438 hg: parse error: topo.firstbranch can only be used when using the topo sort key
2438 hg: parse error: topo.firstbranch can only be used when using the topo sort key
2439 [255]
2439 [255]
2440
2440
2441 topo.firstbranch should accept any kind of expressions:
2441 topo.firstbranch should accept any kind of expressions:
2442
2442
2443 $ hg log -r 'sort(0, topo, topo.firstbranch=(book1))'
2443 $ hg log -r 'sort(0, topo, topo.firstbranch=(book1))'
2444 0 b12 m111 u112 111 10800
2444 0 b12 m111 u112 111 10800
2445
2445
2446 $ cd ..
2446 $ cd ..
2447 $ cd repo
2447 $ cd repo
2448
2448
2449 test subtracting something from an addset
2449 test subtracting something from an addset
2450
2450
2451 $ log '(outgoing() or removes(a)) - removes(a)'
2451 $ log '(outgoing() or removes(a)) - removes(a)'
2452 8
2452 8
2453 9
2453 9
2454
2454
2455 test intersecting something with an addset
2455 test intersecting something with an addset
2456
2456
2457 $ log 'parents(outgoing() or removes(a))'
2457 $ log 'parents(outgoing() or removes(a))'
2458 1
2458 1
2459 4
2459 4
2460 5
2460 5
2461 8
2461 8
2462
2462
2463 test that `or` operation combines elements in the right order:
2463 test that `or` operation combines elements in the right order:
2464
2464
2465 $ log '3:4 or 2:5'
2465 $ log '3:4 or 2:5'
2466 3
2466 3
2467 4
2467 4
2468 2
2468 2
2469 5
2469 5
2470 $ log '3:4 or 5:2'
2470 $ log '3:4 or 5:2'
2471 3
2471 3
2472 4
2472 4
2473 5
2473 5
2474 2
2474 2
2475 $ log 'sort(3:4 or 2:5)'
2475 $ log 'sort(3:4 or 2:5)'
2476 2
2476 2
2477 3
2477 3
2478 4
2478 4
2479 5
2479 5
2480 $ log 'sort(3:4 or 5:2)'
2480 $ log 'sort(3:4 or 5:2)'
2481 2
2481 2
2482 3
2482 3
2483 4
2483 4
2484 5
2484 5
2485
2485
2486 test that more than one `-r`s are combined in the right order and deduplicated:
2486 test that more than one `-r`s are combined in the right order and deduplicated:
2487
2487
2488 $ hg log -T '{rev}\n' -r 3 -r 3 -r 4 -r 5:2 -r 'ancestors(4)'
2488 $ hg log -T '{rev}\n' -r 3 -r 3 -r 4 -r 5:2 -r 'ancestors(4)'
2489 3
2489 3
2490 4
2490 4
2491 5
2491 5
2492 2
2492 2
2493 0
2493 0
2494 1
2494 1
2495
2495
2496 test that `or` operation skips duplicated revisions from right-hand side
2496 test that `or` operation skips duplicated revisions from right-hand side
2497
2497
2498 $ try 'reverse(1::5) or ancestors(4)'
2498 $ try 'reverse(1::5) or ancestors(4)'
2499 (or
2499 (or
2500 (list
2500 (list
2501 (func
2501 (func
2502 ('symbol', 'reverse')
2502 ('symbol', 'reverse')
2503 (dagrange
2503 (dagrange
2504 ('symbol', '1')
2504 ('symbol', '1')
2505 ('symbol', '5')))
2505 ('symbol', '5')))
2506 (func
2506 (func
2507 ('symbol', 'ancestors')
2507 ('symbol', 'ancestors')
2508 ('symbol', '4'))))
2508 ('symbol', '4'))))
2509 * set:
2509 * set:
2510 <addset
2510 <addset
2511 <baseset- [1, 3, 5]>,
2511 <baseset- [1, 3, 5]>,
2512 <generatorset+>>
2512 <generatorset+>>
2513 5
2513 5
2514 3
2514 3
2515 1
2515 1
2516 0
2516 0
2517 2
2517 2
2518 4
2518 4
2519 $ try 'sort(ancestors(4) or reverse(1::5))'
2519 $ try 'sort(ancestors(4) or reverse(1::5))'
2520 (func
2520 (func
2521 ('symbol', 'sort')
2521 ('symbol', 'sort')
2522 (or
2522 (or
2523 (list
2523 (list
2524 (func
2524 (func
2525 ('symbol', 'ancestors')
2525 ('symbol', 'ancestors')
2526 ('symbol', '4'))
2526 ('symbol', '4'))
2527 (func
2527 (func
2528 ('symbol', 'reverse')
2528 ('symbol', 'reverse')
2529 (dagrange
2529 (dagrange
2530 ('symbol', '1')
2530 ('symbol', '1')
2531 ('symbol', '5'))))))
2531 ('symbol', '5'))))))
2532 * set:
2532 * set:
2533 <addset+
2533 <addset+
2534 <generatorset+>,
2534 <generatorset+>,
2535 <baseset- [1, 3, 5]>>
2535 <baseset- [1, 3, 5]>>
2536 0
2536 0
2537 1
2537 1
2538 2
2538 2
2539 3
2539 3
2540 4
2540 4
2541 5
2541 5
2542
2542
2543 test optimization of trivial `or` operation
2543 test optimization of trivial `or` operation
2544
2544
2545 $ try --optimize '0|(1)|"2"|-2|tip|null'
2545 $ try --optimize '0|(1)|"2"|-2|tip|null'
2546 (or
2546 (or
2547 (list
2547 (list
2548 ('symbol', '0')
2548 ('symbol', '0')
2549 (group
2549 (group
2550 ('symbol', '1'))
2550 ('symbol', '1'))
2551 ('string', '2')
2551 ('string', '2')
2552 (negate
2552 (negate
2553 ('symbol', '2'))
2553 ('symbol', '2'))
2554 ('symbol', 'tip')
2554 ('symbol', 'tip')
2555 ('symbol', 'null')))
2555 ('symbol', 'null')))
2556 * optimized:
2556 * optimized:
2557 (func
2557 (func
2558 ('symbol', '_list')
2558 ('symbol', '_list')
2559 ('string', '0\x001\x002\x00-2\x00tip\x00null')
2559 ('string', '0\x001\x002\x00-2\x00tip\x00null')
2560 define)
2560 define)
2561 * set:
2561 * set:
2562 <baseset [0, 1, 2, 8, 9, -1]>
2562 <baseset [0, 1, 2, 8, 9, -1]>
2563 0
2563 0
2564 1
2564 1
2565 2
2565 2
2566 8
2566 8
2567 9
2567 9
2568 -1
2568 -1
2569
2569
2570 $ try --optimize '0|1|2:3'
2570 $ try --optimize '0|1|2:3'
2571 (or
2571 (or
2572 (list
2572 (list
2573 ('symbol', '0')
2573 ('symbol', '0')
2574 ('symbol', '1')
2574 ('symbol', '1')
2575 (range
2575 (range
2576 ('symbol', '2')
2576 ('symbol', '2')
2577 ('symbol', '3'))))
2577 ('symbol', '3'))))
2578 * optimized:
2578 * optimized:
2579 (or
2579 (or
2580 (list
2580 (list
2581 (func
2581 (func
2582 ('symbol', '_list')
2582 ('symbol', '_list')
2583 ('string', '0\x001')
2583 ('string', '0\x001')
2584 define)
2584 define)
2585 (range
2585 (range
2586 ('symbol', '2')
2586 ('symbol', '2')
2587 ('symbol', '3')
2587 ('symbol', '3')
2588 define))
2588 define))
2589 define)
2589 define)
2590 * set:
2590 * set:
2591 <addset
2591 <addset
2592 <baseset [0, 1]>,
2592 <baseset [0, 1]>,
2593 <spanset+ 2:3>>
2593 <spanset+ 2:4>>
2594 0
2594 0
2595 1
2595 1
2596 2
2596 2
2597 3
2597 3
2598
2598
2599 $ try --optimize '0:1|2|3:4|5|6'
2599 $ try --optimize '0:1|2|3:4|5|6'
2600 (or
2600 (or
2601 (list
2601 (list
2602 (range
2602 (range
2603 ('symbol', '0')
2603 ('symbol', '0')
2604 ('symbol', '1'))
2604 ('symbol', '1'))
2605 ('symbol', '2')
2605 ('symbol', '2')
2606 (range
2606 (range
2607 ('symbol', '3')
2607 ('symbol', '3')
2608 ('symbol', '4'))
2608 ('symbol', '4'))
2609 ('symbol', '5')
2609 ('symbol', '5')
2610 ('symbol', '6')))
2610 ('symbol', '6')))
2611 * optimized:
2611 * optimized:
2612 (or
2612 (or
2613 (list
2613 (list
2614 (range
2614 (range
2615 ('symbol', '0')
2615 ('symbol', '0')
2616 ('symbol', '1')
2616 ('symbol', '1')
2617 define)
2617 define)
2618 ('symbol', '2')
2618 ('symbol', '2')
2619 (range
2619 (range
2620 ('symbol', '3')
2620 ('symbol', '3')
2621 ('symbol', '4')
2621 ('symbol', '4')
2622 define)
2622 define)
2623 (func
2623 (func
2624 ('symbol', '_list')
2624 ('symbol', '_list')
2625 ('string', '5\x006')
2625 ('string', '5\x006')
2626 define))
2626 define))
2627 define)
2627 define)
2628 * set:
2628 * set:
2629 <addset
2629 <addset
2630 <addset
2630 <addset
2631 <spanset+ 0:1>,
2631 <spanset+ 0:2>,
2632 <baseset [2]>>,
2632 <baseset [2]>>,
2633 <addset
2633 <addset
2634 <spanset+ 3:4>,
2634 <spanset+ 3:5>,
2635 <baseset [5, 6]>>>
2635 <baseset [5, 6]>>>
2636 0
2636 0
2637 1
2637 1
2638 2
2638 2
2639 3
2639 3
2640 4
2640 4
2641 5
2641 5
2642 6
2642 6
2643
2643
2644 unoptimized `or` looks like this
2644 unoptimized `or` looks like this
2645
2645
2646 $ try --no-optimized -p analyzed '0|1|2|3|4'
2646 $ try --no-optimized -p analyzed '0|1|2|3|4'
2647 * analyzed:
2647 * analyzed:
2648 (or
2648 (or
2649 (list
2649 (list
2650 ('symbol', '0')
2650 ('symbol', '0')
2651 ('symbol', '1')
2651 ('symbol', '1')
2652 ('symbol', '2')
2652 ('symbol', '2')
2653 ('symbol', '3')
2653 ('symbol', '3')
2654 ('symbol', '4'))
2654 ('symbol', '4'))
2655 define)
2655 define)
2656 * set:
2656 * set:
2657 <addset
2657 <addset
2658 <addset
2658 <addset
2659 <baseset [0]>,
2659 <baseset [0]>,
2660 <baseset [1]>>,
2660 <baseset [1]>>,
2661 <addset
2661 <addset
2662 <baseset [2]>,
2662 <baseset [2]>,
2663 <addset
2663 <addset
2664 <baseset [3]>,
2664 <baseset [3]>,
2665 <baseset [4]>>>>
2665 <baseset [4]>>>>
2666 0
2666 0
2667 1
2667 1
2668 2
2668 2
2669 3
2669 3
2670 4
2670 4
2671
2671
2672 test that `_list` should be narrowed by provided `subset`
2672 test that `_list` should be narrowed by provided `subset`
2673
2673
2674 $ log '0:2 and (null|1|2|3)'
2674 $ log '0:2 and (null|1|2|3)'
2675 1
2675 1
2676 2
2676 2
2677
2677
2678 test that `_list` should remove duplicates
2678 test that `_list` should remove duplicates
2679
2679
2680 $ log '0|1|2|1|2|-1|tip'
2680 $ log '0|1|2|1|2|-1|tip'
2681 0
2681 0
2682 1
2682 1
2683 2
2683 2
2684 9
2684 9
2685
2685
2686 test unknown revision in `_list`
2686 test unknown revision in `_list`
2687
2687
2688 $ log '0|unknown'
2688 $ log '0|unknown'
2689 abort: unknown revision 'unknown'!
2689 abort: unknown revision 'unknown'!
2690 [255]
2690 [255]
2691
2691
2692 test integer range in `_list`
2692 test integer range in `_list`
2693
2693
2694 $ log '-1|-10'
2694 $ log '-1|-10'
2695 9
2695 9
2696 0
2696 0
2697
2697
2698 $ log '-10|-11'
2698 $ log '-10|-11'
2699 abort: unknown revision '-11'!
2699 abort: unknown revision '-11'!
2700 [255]
2700 [255]
2701
2701
2702 $ log '9|10'
2702 $ log '9|10'
2703 abort: unknown revision '10'!
2703 abort: unknown revision '10'!
2704 [255]
2704 [255]
2705
2705
2706 test '0000' != '0' in `_list`
2706 test '0000' != '0' in `_list`
2707
2707
2708 $ log '0|0000'
2708 $ log '0|0000'
2709 0
2709 0
2710 -1
2710 -1
2711
2711
2712 test ',' in `_list`
2712 test ',' in `_list`
2713 $ log '0,1'
2713 $ log '0,1'
2714 hg: parse error: can't use a list in this context
2714 hg: parse error: can't use a list in this context
2715 (see hg help "revsets.x or y")
2715 (see hg help "revsets.x or y")
2716 [255]
2716 [255]
2717 $ try '0,1,2'
2717 $ try '0,1,2'
2718 (list
2718 (list
2719 ('symbol', '0')
2719 ('symbol', '0')
2720 ('symbol', '1')
2720 ('symbol', '1')
2721 ('symbol', '2'))
2721 ('symbol', '2'))
2722 hg: parse error: can't use a list in this context
2722 hg: parse error: can't use a list in this context
2723 (see hg help "revsets.x or y")
2723 (see hg help "revsets.x or y")
2724 [255]
2724 [255]
2725
2725
2726 test that chained `or` operations make balanced addsets
2726 test that chained `or` operations make balanced addsets
2727
2727
2728 $ try '0:1|1:2|2:3|3:4|4:5'
2728 $ try '0:1|1:2|2:3|3:4|4:5'
2729 (or
2729 (or
2730 (list
2730 (list
2731 (range
2731 (range
2732 ('symbol', '0')
2732 ('symbol', '0')
2733 ('symbol', '1'))
2733 ('symbol', '1'))
2734 (range
2734 (range
2735 ('symbol', '1')
2735 ('symbol', '1')
2736 ('symbol', '2'))
2736 ('symbol', '2'))
2737 (range
2737 (range
2738 ('symbol', '2')
2738 ('symbol', '2')
2739 ('symbol', '3'))
2739 ('symbol', '3'))
2740 (range
2740 (range
2741 ('symbol', '3')
2741 ('symbol', '3')
2742 ('symbol', '4'))
2742 ('symbol', '4'))
2743 (range
2743 (range
2744 ('symbol', '4')
2744 ('symbol', '4')
2745 ('symbol', '5'))))
2745 ('symbol', '5'))))
2746 * set:
2746 * set:
2747 <addset
2747 <addset
2748 <addset
2748 <addset
2749 <spanset+ 0:1>,
2749 <spanset+ 0:2>,
2750 <spanset+ 1:2>>,
2750 <spanset+ 1:3>>,
2751 <addset
2751 <addset
2752 <spanset+ 2:3>,
2752 <spanset+ 2:4>,
2753 <addset
2753 <addset
2754 <spanset+ 3:4>,
2754 <spanset+ 3:5>,
2755 <spanset+ 4:5>>>>
2755 <spanset+ 4:6>>>>
2756 0
2756 0
2757 1
2757 1
2758 2
2758 2
2759 3
2759 3
2760 4
2760 4
2761 5
2761 5
2762
2762
2763 no crash by empty group "()" while optimizing `or` operations
2763 no crash by empty group "()" while optimizing `or` operations
2764
2764
2765 $ try --optimize '0|()'
2765 $ try --optimize '0|()'
2766 (or
2766 (or
2767 (list
2767 (list
2768 ('symbol', '0')
2768 ('symbol', '0')
2769 (group
2769 (group
2770 None)))
2770 None)))
2771 * optimized:
2771 * optimized:
2772 (or
2772 (or
2773 (list
2773 (list
2774 ('symbol', '0')
2774 ('symbol', '0')
2775 None)
2775 None)
2776 define)
2776 define)
2777 hg: parse error: missing argument
2777 hg: parse error: missing argument
2778 [255]
2778 [255]
2779
2779
2780 test that chained `or` operations never eat up stack (issue4624)
2780 test that chained `or` operations never eat up stack (issue4624)
2781 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
2781 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
2782
2782
2783 $ hg log -T '{rev}\n' -r `python -c "print '+'.join(['0:1'] * 500)"`
2783 $ hg log -T '{rev}\n' -r `python -c "print '+'.join(['0:1'] * 500)"`
2784 0
2784 0
2785 1
2785 1
2786
2786
2787 test that repeated `-r` options never eat up stack (issue4565)
2787 test that repeated `-r` options never eat up stack (issue4565)
2788 (uses `-r 0::1` to avoid possible optimization at old-style parser)
2788 (uses `-r 0::1` to avoid possible optimization at old-style parser)
2789
2789
2790 $ hg log -T '{rev}\n' `python -c "for i in xrange(500): print '-r 0::1 ',"`
2790 $ hg log -T '{rev}\n' `python -c "for i in xrange(500): print '-r 0::1 ',"`
2791 0
2791 0
2792 1
2792 1
2793
2793
2794 check that conversion to only works
2794 check that conversion to only works
2795 $ try --optimize '::3 - ::1'
2795 $ try --optimize '::3 - ::1'
2796 (minus
2796 (minus
2797 (dagrangepre
2797 (dagrangepre
2798 ('symbol', '3'))
2798 ('symbol', '3'))
2799 (dagrangepre
2799 (dagrangepre
2800 ('symbol', '1')))
2800 ('symbol', '1')))
2801 * optimized:
2801 * optimized:
2802 (func
2802 (func
2803 ('symbol', 'only')
2803 ('symbol', 'only')
2804 (list
2804 (list
2805 ('symbol', '3')
2805 ('symbol', '3')
2806 ('symbol', '1'))
2806 ('symbol', '1'))
2807 define)
2807 define)
2808 * set:
2808 * set:
2809 <baseset+ [3]>
2809 <baseset+ [3]>
2810 3
2810 3
2811 $ try --optimize 'ancestors(1) - ancestors(3)'
2811 $ try --optimize 'ancestors(1) - ancestors(3)'
2812 (minus
2812 (minus
2813 (func
2813 (func
2814 ('symbol', 'ancestors')
2814 ('symbol', 'ancestors')
2815 ('symbol', '1'))
2815 ('symbol', '1'))
2816 (func
2816 (func
2817 ('symbol', 'ancestors')
2817 ('symbol', 'ancestors')
2818 ('symbol', '3')))
2818 ('symbol', '3')))
2819 * optimized:
2819 * optimized:
2820 (func
2820 (func
2821 ('symbol', 'only')
2821 ('symbol', 'only')
2822 (list
2822 (list
2823 ('symbol', '1')
2823 ('symbol', '1')
2824 ('symbol', '3'))
2824 ('symbol', '3'))
2825 define)
2825 define)
2826 * set:
2826 * set:
2827 <baseset+ []>
2827 <baseset+ []>
2828 $ try --optimize 'not ::2 and ::6'
2828 $ try --optimize 'not ::2 and ::6'
2829 (and
2829 (and
2830 (not
2830 (not
2831 (dagrangepre
2831 (dagrangepre
2832 ('symbol', '2')))
2832 ('symbol', '2')))
2833 (dagrangepre
2833 (dagrangepre
2834 ('symbol', '6')))
2834 ('symbol', '6')))
2835 * optimized:
2835 * optimized:
2836 (func
2836 (func
2837 ('symbol', 'only')
2837 ('symbol', 'only')
2838 (list
2838 (list
2839 ('symbol', '6')
2839 ('symbol', '6')
2840 ('symbol', '2'))
2840 ('symbol', '2'))
2841 define)
2841 define)
2842 * set:
2842 * set:
2843 <baseset+ [3, 4, 5, 6]>
2843 <baseset+ [3, 4, 5, 6]>
2844 3
2844 3
2845 4
2845 4
2846 5
2846 5
2847 6
2847 6
2848 $ try --optimize 'ancestors(6) and not ancestors(4)'
2848 $ try --optimize 'ancestors(6) and not ancestors(4)'
2849 (and
2849 (and
2850 (func
2850 (func
2851 ('symbol', 'ancestors')
2851 ('symbol', 'ancestors')
2852 ('symbol', '6'))
2852 ('symbol', '6'))
2853 (not
2853 (not
2854 (func
2854 (func
2855 ('symbol', 'ancestors')
2855 ('symbol', 'ancestors')
2856 ('symbol', '4'))))
2856 ('symbol', '4'))))
2857 * optimized:
2857 * optimized:
2858 (func
2858 (func
2859 ('symbol', 'only')
2859 ('symbol', 'only')
2860 (list
2860 (list
2861 ('symbol', '6')
2861 ('symbol', '6')
2862 ('symbol', '4'))
2862 ('symbol', '4'))
2863 define)
2863 define)
2864 * set:
2864 * set:
2865 <baseset+ [3, 5, 6]>
2865 <baseset+ [3, 5, 6]>
2866 3
2866 3
2867 5
2867 5
2868 6
2868 6
2869
2869
2870 no crash by empty group "()" while optimizing to "only()"
2870 no crash by empty group "()" while optimizing to "only()"
2871
2871
2872 $ try --optimize '::1 and ()'
2872 $ try --optimize '::1 and ()'
2873 (and
2873 (and
2874 (dagrangepre
2874 (dagrangepre
2875 ('symbol', '1'))
2875 ('symbol', '1'))
2876 (group
2876 (group
2877 None))
2877 None))
2878 * optimized:
2878 * optimized:
2879 (and
2879 (and
2880 None
2880 None
2881 (func
2881 (func
2882 ('symbol', 'ancestors')
2882 ('symbol', 'ancestors')
2883 ('symbol', '1')
2883 ('symbol', '1')
2884 define)
2884 define)
2885 define)
2885 define)
2886 hg: parse error: missing argument
2886 hg: parse error: missing argument
2887 [255]
2887 [255]
2888
2888
2889 invalid function call should not be optimized to only()
2889 invalid function call should not be optimized to only()
2890
2890
2891 $ log '"ancestors"(6) and not ancestors(4)'
2891 $ log '"ancestors"(6) and not ancestors(4)'
2892 hg: parse error: not a symbol
2892 hg: parse error: not a symbol
2893 [255]
2893 [255]
2894
2894
2895 $ log 'ancestors(6) and not "ancestors"(4)'
2895 $ log 'ancestors(6) and not "ancestors"(4)'
2896 hg: parse error: not a symbol
2896 hg: parse error: not a symbol
2897 [255]
2897 [255]
2898
2898
2899 we can use patterns when searching for tags
2899 we can use patterns when searching for tags
2900
2900
2901 $ log 'tag("1..*")'
2901 $ log 'tag("1..*")'
2902 abort: tag '1..*' does not exist!
2902 abort: tag '1..*' does not exist!
2903 [255]
2903 [255]
2904 $ log 'tag("re:1..*")'
2904 $ log 'tag("re:1..*")'
2905 6
2905 6
2906 $ log 'tag("re:[0-9].[0-9]")'
2906 $ log 'tag("re:[0-9].[0-9]")'
2907 6
2907 6
2908 $ log 'tag("literal:1.0")'
2908 $ log 'tag("literal:1.0")'
2909 6
2909 6
2910 $ log 'tag("re:0..*")'
2910 $ log 'tag("re:0..*")'
2911
2911
2912 $ log 'tag(unknown)'
2912 $ log 'tag(unknown)'
2913 abort: tag 'unknown' does not exist!
2913 abort: tag 'unknown' does not exist!
2914 [255]
2914 [255]
2915 $ log 'tag("re:unknown")'
2915 $ log 'tag("re:unknown")'
2916 $ log 'present(tag("unknown"))'
2916 $ log 'present(tag("unknown"))'
2917 $ log 'present(tag("re:unknown"))'
2917 $ log 'present(tag("re:unknown"))'
2918 $ log 'branch(unknown)'
2918 $ log 'branch(unknown)'
2919 abort: unknown revision 'unknown'!
2919 abort: unknown revision 'unknown'!
2920 [255]
2920 [255]
2921 $ log 'branch("literal:unknown")'
2921 $ log 'branch("literal:unknown")'
2922 abort: branch 'unknown' does not exist!
2922 abort: branch 'unknown' does not exist!
2923 [255]
2923 [255]
2924 $ log 'branch("re:unknown")'
2924 $ log 'branch("re:unknown")'
2925 $ log 'present(branch("unknown"))'
2925 $ log 'present(branch("unknown"))'
2926 $ log 'present(branch("re:unknown"))'
2926 $ log 'present(branch("re:unknown"))'
2927 $ log 'user(bob)'
2927 $ log 'user(bob)'
2928 2
2928 2
2929
2929
2930 $ log '4::8'
2930 $ log '4::8'
2931 4
2931 4
2932 8
2932 8
2933 $ log '4:8'
2933 $ log '4:8'
2934 4
2934 4
2935 5
2935 5
2936 6
2936 6
2937 7
2937 7
2938 8
2938 8
2939
2939
2940 $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
2940 $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
2941 4
2941 4
2942 2
2942 2
2943 5
2943 5
2944
2944
2945 $ log 'not 0 and 0:2'
2945 $ log 'not 0 and 0:2'
2946 1
2946 1
2947 2
2947 2
2948 $ log 'not 1 and 0:2'
2948 $ log 'not 1 and 0:2'
2949 0
2949 0
2950 2
2950 2
2951 $ log 'not 2 and 0:2'
2951 $ log 'not 2 and 0:2'
2952 0
2952 0
2953 1
2953 1
2954 $ log '(1 and 2)::'
2954 $ log '(1 and 2)::'
2955 $ log '(1 and 2):'
2955 $ log '(1 and 2):'
2956 $ log '(1 and 2):3'
2956 $ log '(1 and 2):3'
2957 $ log 'sort(head(), -rev)'
2957 $ log 'sort(head(), -rev)'
2958 9
2958 9
2959 7
2959 7
2960 6
2960 6
2961 5
2961 5
2962 4
2962 4
2963 3
2963 3
2964 2
2964 2
2965 1
2965 1
2966 0
2966 0
2967 $ log '4::8 - 8'
2967 $ log '4::8 - 8'
2968 4
2968 4
2969
2969
2970 matching() should preserve the order of the input set:
2970 matching() should preserve the order of the input set:
2971
2971
2972 $ log '(2 or 3 or 1) and matching(1 or 2 or 3)'
2972 $ log '(2 or 3 or 1) and matching(1 or 2 or 3)'
2973 2
2973 2
2974 3
2974 3
2975 1
2975 1
2976
2976
2977 $ log 'named("unknown")'
2977 $ log 'named("unknown")'
2978 abort: namespace 'unknown' does not exist!
2978 abort: namespace 'unknown' does not exist!
2979 [255]
2979 [255]
2980 $ log 'named("re:unknown")'
2980 $ log 'named("re:unknown")'
2981 abort: no namespace exists that match 'unknown'!
2981 abort: no namespace exists that match 'unknown'!
2982 [255]
2982 [255]
2983 $ log 'present(named("unknown"))'
2983 $ log 'present(named("unknown"))'
2984 $ log 'present(named("re:unknown"))'
2984 $ log 'present(named("re:unknown"))'
2985
2985
2986 $ log 'tag()'
2986 $ log 'tag()'
2987 6
2987 6
2988 $ log 'named("tags")'
2988 $ log 'named("tags")'
2989 6
2989 6
2990
2990
2991 issue2437
2991 issue2437
2992
2992
2993 $ log '3 and p1(5)'
2993 $ log '3 and p1(5)'
2994 3
2994 3
2995 $ log '4 and p2(6)'
2995 $ log '4 and p2(6)'
2996 4
2996 4
2997 $ log '1 and parents(:2)'
2997 $ log '1 and parents(:2)'
2998 1
2998 1
2999 $ log '2 and children(1:)'
2999 $ log '2 and children(1:)'
3000 2
3000 2
3001 $ log 'roots(all()) or roots(all())'
3001 $ log 'roots(all()) or roots(all())'
3002 0
3002 0
3003 $ hg debugrevspec 'roots(all()) or roots(all())'
3003 $ hg debugrevspec 'roots(all()) or roots(all())'
3004 0
3004 0
3005 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
3005 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
3006 9
3006 9
3007 $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(Γ©)))'
3007 $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(Γ©)))'
3008 4
3008 4
3009
3009
3010 issue2654: report a parse error if the revset was not completely parsed
3010 issue2654: report a parse error if the revset was not completely parsed
3011
3011
3012 $ log '1 OR 2'
3012 $ log '1 OR 2'
3013 hg: parse error at 2: invalid token
3013 hg: parse error at 2: invalid token
3014 [255]
3014 [255]
3015
3015
3016 or operator should preserve ordering:
3016 or operator should preserve ordering:
3017 $ log 'reverse(2::4) or tip'
3017 $ log 'reverse(2::4) or tip'
3018 4
3018 4
3019 2
3019 2
3020 9
3020 9
3021
3021
3022 parentrevspec
3022 parentrevspec
3023
3023
3024 $ log 'merge()^0'
3024 $ log 'merge()^0'
3025 6
3025 6
3026 $ log 'merge()^'
3026 $ log 'merge()^'
3027 5
3027 5
3028 $ log 'merge()^1'
3028 $ log 'merge()^1'
3029 5
3029 5
3030 $ log 'merge()^2'
3030 $ log 'merge()^2'
3031 4
3031 4
3032 $ log '(not merge())^2'
3032 $ log '(not merge())^2'
3033 $ log 'merge()^^'
3033 $ log 'merge()^^'
3034 3
3034 3
3035 $ log 'merge()^1^'
3035 $ log 'merge()^1^'
3036 3
3036 3
3037 $ log 'merge()^^^'
3037 $ log 'merge()^^^'
3038 1
3038 1
3039
3039
3040 $ log '(merge() | 0)~-1'
3040 $ log '(merge() | 0)~-1'
3041 7
3041 7
3042 1
3042 1
3043 $ log 'merge()~-1'
3043 $ log 'merge()~-1'
3044 7
3044 7
3045 $ log 'tip~-1'
3045 $ log 'tip~-1'
3046 $ log '(tip | merge())~-1'
3046 $ log '(tip | merge())~-1'
3047 7
3047 7
3048 $ log 'merge()~0'
3048 $ log 'merge()~0'
3049 6
3049 6
3050 $ log 'merge()~1'
3050 $ log 'merge()~1'
3051 5
3051 5
3052 $ log 'merge()~2'
3052 $ log 'merge()~2'
3053 3
3053 3
3054 $ log 'merge()~2^1'
3054 $ log 'merge()~2^1'
3055 1
3055 1
3056 $ log 'merge()~3'
3056 $ log 'merge()~3'
3057 1
3057 1
3058
3058
3059 $ log '(-3:tip)^'
3059 $ log '(-3:tip)^'
3060 4
3060 4
3061 6
3061 6
3062 8
3062 8
3063
3063
3064 $ log 'tip^foo'
3064 $ log 'tip^foo'
3065 hg: parse error: ^ expects a number 0, 1, or 2
3065 hg: parse error: ^ expects a number 0, 1, or 2
3066 [255]
3066 [255]
3067
3067
3068 $ log 'branchpoint()~-1'
3068 $ log 'branchpoint()~-1'
3069 abort: revision in set has more than one child!
3069 abort: revision in set has more than one child!
3070 [255]
3070 [255]
3071
3071
3072 Bogus function gets suggestions
3072 Bogus function gets suggestions
3073 $ log 'add()'
3073 $ log 'add()'
3074 hg: parse error: unknown identifier: add
3074 hg: parse error: unknown identifier: add
3075 (did you mean adds?)
3075 (did you mean adds?)
3076 [255]
3076 [255]
3077 $ log 'added()'
3077 $ log 'added()'
3078 hg: parse error: unknown identifier: added
3078 hg: parse error: unknown identifier: added
3079 (did you mean adds?)
3079 (did you mean adds?)
3080 [255]
3080 [255]
3081 $ log 'remo()'
3081 $ log 'remo()'
3082 hg: parse error: unknown identifier: remo
3082 hg: parse error: unknown identifier: remo
3083 (did you mean one of remote, removes?)
3083 (did you mean one of remote, removes?)
3084 [255]
3084 [255]
3085 $ log 'babar()'
3085 $ log 'babar()'
3086 hg: parse error: unknown identifier: babar
3086 hg: parse error: unknown identifier: babar
3087 [255]
3087 [255]
3088
3088
3089 Bogus function with a similar internal name doesn't suggest the internal name
3089 Bogus function with a similar internal name doesn't suggest the internal name
3090 $ log 'matches()'
3090 $ log 'matches()'
3091 hg: parse error: unknown identifier: matches
3091 hg: parse error: unknown identifier: matches
3092 (did you mean matching?)
3092 (did you mean matching?)
3093 [255]
3093 [255]
3094
3094
3095 Undocumented functions aren't suggested as similar either
3095 Undocumented functions aren't suggested as similar either
3096 $ log 'tagged2()'
3096 $ log 'tagged2()'
3097 hg: parse error: unknown identifier: tagged2
3097 hg: parse error: unknown identifier: tagged2
3098 [255]
3098 [255]
3099
3099
3100 multiple revspecs
3100 multiple revspecs
3101
3101
3102 $ hg log -r 'tip~1:tip' -r 'tip~2:tip~1' --template '{rev}\n'
3102 $ hg log -r 'tip~1:tip' -r 'tip~2:tip~1' --template '{rev}\n'
3103 8
3103 8
3104 9
3104 9
3105 4
3105 4
3106 5
3106 5
3107 6
3107 6
3108 7
3108 7
3109
3109
3110 test usage in revpair (with "+")
3110 test usage in revpair (with "+")
3111
3111
3112 (real pair)
3112 (real pair)
3113
3113
3114 $ hg diff -r 'tip^^' -r 'tip'
3114 $ hg diff -r 'tip^^' -r 'tip'
3115 diff -r 2326846efdab -r 24286f4ae135 .hgtags
3115 diff -r 2326846efdab -r 24286f4ae135 .hgtags
3116 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3116 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3117 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
3117 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
3118 @@ -0,0 +1,1 @@
3118 @@ -0,0 +1,1 @@
3119 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
3119 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
3120 $ hg diff -r 'tip^^::tip'
3120 $ hg diff -r 'tip^^::tip'
3121 diff -r 2326846efdab -r 24286f4ae135 .hgtags
3121 diff -r 2326846efdab -r 24286f4ae135 .hgtags
3122 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3122 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3123 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
3123 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
3124 @@ -0,0 +1,1 @@
3124 @@ -0,0 +1,1 @@
3125 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
3125 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
3126
3126
3127 (single rev)
3127 (single rev)
3128
3128
3129 $ hg diff -r 'tip^' -r 'tip^'
3129 $ hg diff -r 'tip^' -r 'tip^'
3130 $ hg diff -r 'tip^:tip^'
3130 $ hg diff -r 'tip^:tip^'
3131
3131
3132 (single rev that does not looks like a range)
3132 (single rev that does not looks like a range)
3133
3133
3134 $ hg diff -r 'tip^::tip^ or tip^'
3134 $ hg diff -r 'tip^::tip^ or tip^'
3135 diff -r d5d0dcbdc4d9 .hgtags
3135 diff -r d5d0dcbdc4d9 .hgtags
3136 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3136 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3137 +++ b/.hgtags * (glob)
3137 +++ b/.hgtags * (glob)
3138 @@ -0,0 +1,1 @@
3138 @@ -0,0 +1,1 @@
3139 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
3139 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
3140 $ hg diff -r 'tip^ or tip^'
3140 $ hg diff -r 'tip^ or tip^'
3141 diff -r d5d0dcbdc4d9 .hgtags
3141 diff -r d5d0dcbdc4d9 .hgtags
3142 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3142 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3143 +++ b/.hgtags * (glob)
3143 +++ b/.hgtags * (glob)
3144 @@ -0,0 +1,1 @@
3144 @@ -0,0 +1,1 @@
3145 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
3145 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
3146
3146
3147 (no rev)
3147 (no rev)
3148
3148
3149 $ hg diff -r 'author("babar") or author("celeste")'
3149 $ hg diff -r 'author("babar") or author("celeste")'
3150 abort: empty revision range
3150 abort: empty revision range
3151 [255]
3151 [255]
3152
3152
3153 aliases:
3153 aliases:
3154
3154
3155 $ echo '[revsetalias]' >> .hg/hgrc
3155 $ echo '[revsetalias]' >> .hg/hgrc
3156 $ echo 'm = merge()' >> .hg/hgrc
3156 $ echo 'm = merge()' >> .hg/hgrc
3157 (revset aliases can override builtin revsets)
3157 (revset aliases can override builtin revsets)
3158 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
3158 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
3159 $ echo 'sincem = descendants(m)' >> .hg/hgrc
3159 $ echo 'sincem = descendants(m)' >> .hg/hgrc
3160 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
3160 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
3161 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
3161 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
3162 $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
3162 $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
3163
3163
3164 $ try m
3164 $ try m
3165 ('symbol', 'm')
3165 ('symbol', 'm')
3166 * expanded:
3166 * expanded:
3167 (func
3167 (func
3168 ('symbol', 'merge')
3168 ('symbol', 'merge')
3169 None)
3169 None)
3170 * set:
3170 * set:
3171 <filteredset
3171 <filteredset
3172 <fullreposet+ 0:9>,
3172 <fullreposet+ 0:10>,
3173 <merge>>
3173 <merge>>
3174 6
3174 6
3175
3175
3176 $ HGPLAIN=1
3176 $ HGPLAIN=1
3177 $ export HGPLAIN
3177 $ export HGPLAIN
3178 $ try m
3178 $ try m
3179 ('symbol', 'm')
3179 ('symbol', 'm')
3180 abort: unknown revision 'm'!
3180 abort: unknown revision 'm'!
3181 [255]
3181 [255]
3182
3182
3183 $ HGPLAINEXCEPT=revsetalias
3183 $ HGPLAINEXCEPT=revsetalias
3184 $ export HGPLAINEXCEPT
3184 $ export HGPLAINEXCEPT
3185 $ try m
3185 $ try m
3186 ('symbol', 'm')
3186 ('symbol', 'm')
3187 * expanded:
3187 * expanded:
3188 (func
3188 (func
3189 ('symbol', 'merge')
3189 ('symbol', 'merge')
3190 None)
3190 None)
3191 * set:
3191 * set:
3192 <filteredset
3192 <filteredset
3193 <fullreposet+ 0:9>,
3193 <fullreposet+ 0:10>,
3194 <merge>>
3194 <merge>>
3195 6
3195 6
3196
3196
3197 $ unset HGPLAIN
3197 $ unset HGPLAIN
3198 $ unset HGPLAINEXCEPT
3198 $ unset HGPLAINEXCEPT
3199
3199
3200 $ try 'p2(.)'
3200 $ try 'p2(.)'
3201 (func
3201 (func
3202 ('symbol', 'p2')
3202 ('symbol', 'p2')
3203 ('symbol', '.'))
3203 ('symbol', '.'))
3204 * expanded:
3204 * expanded:
3205 (func
3205 (func
3206 ('symbol', 'p1')
3206 ('symbol', 'p1')
3207 ('symbol', '.'))
3207 ('symbol', '.'))
3208 * set:
3208 * set:
3209 <baseset+ [8]>
3209 <baseset+ [8]>
3210 8
3210 8
3211
3211
3212 $ HGPLAIN=1
3212 $ HGPLAIN=1
3213 $ export HGPLAIN
3213 $ export HGPLAIN
3214 $ try 'p2(.)'
3214 $ try 'p2(.)'
3215 (func
3215 (func
3216 ('symbol', 'p2')
3216 ('symbol', 'p2')
3217 ('symbol', '.'))
3217 ('symbol', '.'))
3218 * set:
3218 * set:
3219 <baseset+ []>
3219 <baseset+ []>
3220
3220
3221 $ HGPLAINEXCEPT=revsetalias
3221 $ HGPLAINEXCEPT=revsetalias
3222 $ export HGPLAINEXCEPT
3222 $ export HGPLAINEXCEPT
3223 $ try 'p2(.)'
3223 $ try 'p2(.)'
3224 (func
3224 (func
3225 ('symbol', 'p2')
3225 ('symbol', 'p2')
3226 ('symbol', '.'))
3226 ('symbol', '.'))
3227 * expanded:
3227 * expanded:
3228 (func
3228 (func
3229 ('symbol', 'p1')
3229 ('symbol', 'p1')
3230 ('symbol', '.'))
3230 ('symbol', '.'))
3231 * set:
3231 * set:
3232 <baseset+ [8]>
3232 <baseset+ [8]>
3233 8
3233 8
3234
3234
3235 $ unset HGPLAIN
3235 $ unset HGPLAIN
3236 $ unset HGPLAINEXCEPT
3236 $ unset HGPLAINEXCEPT
3237
3237
3238 test alias recursion
3238 test alias recursion
3239
3239
3240 $ try sincem
3240 $ try sincem
3241 ('symbol', 'sincem')
3241 ('symbol', 'sincem')
3242 * expanded:
3242 * expanded:
3243 (func
3243 (func
3244 ('symbol', 'descendants')
3244 ('symbol', 'descendants')
3245 (func
3245 (func
3246 ('symbol', 'merge')
3246 ('symbol', 'merge')
3247 None))
3247 None))
3248 * set:
3248 * set:
3249 <addset+
3249 <addset+
3250 <filteredset
3250 <filteredset
3251 <fullreposet+ 0:9>,
3251 <fullreposet+ 0:10>,
3252 <merge>>,
3252 <merge>>,
3253 <generatorset+>>
3253 <generatorset+>>
3254 6
3254 6
3255 7
3255 7
3256
3256
3257 test infinite recursion
3257 test infinite recursion
3258
3258
3259 $ echo 'recurse1 = recurse2' >> .hg/hgrc
3259 $ echo 'recurse1 = recurse2' >> .hg/hgrc
3260 $ echo 'recurse2 = recurse1' >> .hg/hgrc
3260 $ echo 'recurse2 = recurse1' >> .hg/hgrc
3261 $ try recurse1
3261 $ try recurse1
3262 ('symbol', 'recurse1')
3262 ('symbol', 'recurse1')
3263 hg: parse error: infinite expansion of revset alias "recurse1" detected
3263 hg: parse error: infinite expansion of revset alias "recurse1" detected
3264 [255]
3264 [255]
3265
3265
3266 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
3266 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
3267 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
3267 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
3268 $ try "level2(level1(1, 2), 3)"
3268 $ try "level2(level1(1, 2), 3)"
3269 (func
3269 (func
3270 ('symbol', 'level2')
3270 ('symbol', 'level2')
3271 (list
3271 (list
3272 (func
3272 (func
3273 ('symbol', 'level1')
3273 ('symbol', 'level1')
3274 (list
3274 (list
3275 ('symbol', '1')
3275 ('symbol', '1')
3276 ('symbol', '2')))
3276 ('symbol', '2')))
3277 ('symbol', '3')))
3277 ('symbol', '3')))
3278 * expanded:
3278 * expanded:
3279 (or
3279 (or
3280 (list
3280 (list
3281 ('symbol', '3')
3281 ('symbol', '3')
3282 (or
3282 (or
3283 (list
3283 (list
3284 ('symbol', '1')
3284 ('symbol', '1')
3285 ('symbol', '2')))))
3285 ('symbol', '2')))))
3286 * set:
3286 * set:
3287 <addset
3287 <addset
3288 <baseset [3]>,
3288 <baseset [3]>,
3289 <baseset [1, 2]>>
3289 <baseset [1, 2]>>
3290 3
3290 3
3291 1
3291 1
3292 2
3292 2
3293
3293
3294 test nesting and variable passing
3294 test nesting and variable passing
3295
3295
3296 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
3296 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
3297 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
3297 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
3298 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
3298 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
3299 $ try 'nested(2:5)'
3299 $ try 'nested(2:5)'
3300 (func
3300 (func
3301 ('symbol', 'nested')
3301 ('symbol', 'nested')
3302 (range
3302 (range
3303 ('symbol', '2')
3303 ('symbol', '2')
3304 ('symbol', '5')))
3304 ('symbol', '5')))
3305 * expanded:
3305 * expanded:
3306 (func
3306 (func
3307 ('symbol', 'max')
3307 ('symbol', 'max')
3308 (range
3308 (range
3309 ('symbol', '2')
3309 ('symbol', '2')
3310 ('symbol', '5')))
3310 ('symbol', '5')))
3311 * set:
3311 * set:
3312 <baseset
3312 <baseset
3313 <max
3313 <max
3314 <fullreposet+ 0:9>,
3314 <fullreposet+ 0:10>,
3315 <spanset+ 2:5>>>
3315 <spanset+ 2:6>>>
3316 5
3316 5
3317
3317
3318 test chained `or` operations are flattened at parsing phase
3318 test chained `or` operations are flattened at parsing phase
3319
3319
3320 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
3320 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
3321 $ try 'chainedorops(0:1, 1:2, 2:3)'
3321 $ try 'chainedorops(0:1, 1:2, 2:3)'
3322 (func
3322 (func
3323 ('symbol', 'chainedorops')
3323 ('symbol', 'chainedorops')
3324 (list
3324 (list
3325 (range
3325 (range
3326 ('symbol', '0')
3326 ('symbol', '0')
3327 ('symbol', '1'))
3327 ('symbol', '1'))
3328 (range
3328 (range
3329 ('symbol', '1')
3329 ('symbol', '1')
3330 ('symbol', '2'))
3330 ('symbol', '2'))
3331 (range
3331 (range
3332 ('symbol', '2')
3332 ('symbol', '2')
3333 ('symbol', '3'))))
3333 ('symbol', '3'))))
3334 * expanded:
3334 * expanded:
3335 (or
3335 (or
3336 (list
3336 (list
3337 (range
3337 (range
3338 ('symbol', '0')
3338 ('symbol', '0')
3339 ('symbol', '1'))
3339 ('symbol', '1'))
3340 (range
3340 (range
3341 ('symbol', '1')
3341 ('symbol', '1')
3342 ('symbol', '2'))
3342 ('symbol', '2'))
3343 (range
3343 (range
3344 ('symbol', '2')
3344 ('symbol', '2')
3345 ('symbol', '3'))))
3345 ('symbol', '3'))))
3346 * set:
3346 * set:
3347 <addset
3347 <addset
3348 <spanset+ 0:1>,
3348 <spanset+ 0:2>,
3349 <addset
3349 <addset
3350 <spanset+ 1:2>,
3350 <spanset+ 1:3>,
3351 <spanset+ 2:3>>>
3351 <spanset+ 2:4>>>
3352 0
3352 0
3353 1
3353 1
3354 2
3354 2
3355 3
3355 3
3356
3356
3357 test variable isolation, variable placeholders are rewritten as string
3357 test variable isolation, variable placeholders are rewritten as string
3358 then parsed and matched again as string. Check they do not leak too
3358 then parsed and matched again as string. Check they do not leak too
3359 far away.
3359 far away.
3360
3360
3361 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
3361 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
3362 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
3362 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
3363 $ try 'callinjection(2:5)'
3363 $ try 'callinjection(2:5)'
3364 (func
3364 (func
3365 ('symbol', 'callinjection')
3365 ('symbol', 'callinjection')
3366 (range
3366 (range
3367 ('symbol', '2')
3367 ('symbol', '2')
3368 ('symbol', '5')))
3368 ('symbol', '5')))
3369 * expanded:
3369 * expanded:
3370 (func
3370 (func
3371 ('symbol', 'descendants')
3371 ('symbol', 'descendants')
3372 (func
3372 (func
3373 ('symbol', 'max')
3373 ('symbol', 'max')
3374 ('string', '$1')))
3374 ('string', '$1')))
3375 abort: unknown revision '$1'!
3375 abort: unknown revision '$1'!
3376 [255]
3376 [255]
3377
3377
3378 test scope of alias expansion: 'universe' is expanded prior to 'shadowall(0)',
3378 test scope of alias expansion: 'universe' is expanded prior to 'shadowall(0)',
3379 but 'all()' should never be substituted to '0()'.
3379 but 'all()' should never be substituted to '0()'.
3380
3380
3381 $ echo 'universe = all()' >> .hg/hgrc
3381 $ echo 'universe = all()' >> .hg/hgrc
3382 $ echo 'shadowall(all) = all and universe' >> .hg/hgrc
3382 $ echo 'shadowall(all) = all and universe' >> .hg/hgrc
3383 $ try 'shadowall(0)'
3383 $ try 'shadowall(0)'
3384 (func
3384 (func
3385 ('symbol', 'shadowall')
3385 ('symbol', 'shadowall')
3386 ('symbol', '0'))
3386 ('symbol', '0'))
3387 * expanded:
3387 * expanded:
3388 (and
3388 (and
3389 ('symbol', '0')
3389 ('symbol', '0')
3390 (func
3390 (func
3391 ('symbol', 'all')
3391 ('symbol', 'all')
3392 None))
3392 None))
3393 * set:
3393 * set:
3394 <filteredset
3394 <filteredset
3395 <baseset [0]>,
3395 <baseset [0]>,
3396 <spanset+ 0:9>>
3396 <spanset+ 0:10>>
3397 0
3397 0
3398
3398
3399 test unknown reference:
3399 test unknown reference:
3400
3400
3401 $ try "unknownref(0)" --config 'revsetalias.unknownref($1)=$1:$2'
3401 $ try "unknownref(0)" --config 'revsetalias.unknownref($1)=$1:$2'
3402 (func
3402 (func
3403 ('symbol', 'unknownref')
3403 ('symbol', 'unknownref')
3404 ('symbol', '0'))
3404 ('symbol', '0'))
3405 abort: bad definition of revset alias "unknownref": invalid symbol '$2'
3405 abort: bad definition of revset alias "unknownref": invalid symbol '$2'
3406 [255]
3406 [255]
3407
3407
3408 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
3408 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
3409 ('symbol', 'tip')
3409 ('symbol', 'tip')
3410 warning: bad definition of revset alias "anotherbadone": at 7: not a prefix: end
3410 warning: bad definition of revset alias "anotherbadone": at 7: not a prefix: end
3411 * set:
3411 * set:
3412 <baseset [9]>
3412 <baseset [9]>
3413 9
3413 9
3414
3414
3415 $ try 'tip'
3415 $ try 'tip'
3416 ('symbol', 'tip')
3416 ('symbol', 'tip')
3417 * set:
3417 * set:
3418 <baseset [9]>
3418 <baseset [9]>
3419 9
3419 9
3420
3420
3421 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
3421 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
3422 ('symbol', 'tip')
3422 ('symbol', 'tip')
3423 warning: bad declaration of revset alias "bad name": at 4: invalid token
3423 warning: bad declaration of revset alias "bad name": at 4: invalid token
3424 * set:
3424 * set:
3425 <baseset [9]>
3425 <baseset [9]>
3426 9
3426 9
3427 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
3427 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
3428 $ try 'strictreplacing("foo", tip)'
3428 $ try 'strictreplacing("foo", tip)'
3429 (func
3429 (func
3430 ('symbol', 'strictreplacing')
3430 ('symbol', 'strictreplacing')
3431 (list
3431 (list
3432 ('string', 'foo')
3432 ('string', 'foo')
3433 ('symbol', 'tip')))
3433 ('symbol', 'tip')))
3434 * expanded:
3434 * expanded:
3435 (or
3435 (or
3436 (list
3436 (list
3437 ('symbol', 'tip')
3437 ('symbol', 'tip')
3438 (func
3438 (func
3439 ('symbol', 'desc')
3439 ('symbol', 'desc')
3440 ('string', '$1'))))
3440 ('string', '$1'))))
3441 * set:
3441 * set:
3442 <addset
3442 <addset
3443 <baseset [9]>,
3443 <baseset [9]>,
3444 <filteredset
3444 <filteredset
3445 <fullreposet+ 0:9>,
3445 <fullreposet+ 0:10>,
3446 <desc '$1'>>>
3446 <desc '$1'>>>
3447 9
3447 9
3448
3448
3449 $ try 'd(2:5)'
3449 $ try 'd(2:5)'
3450 (func
3450 (func
3451 ('symbol', 'd')
3451 ('symbol', 'd')
3452 (range
3452 (range
3453 ('symbol', '2')
3453 ('symbol', '2')
3454 ('symbol', '5')))
3454 ('symbol', '5')))
3455 * expanded:
3455 * expanded:
3456 (func
3456 (func
3457 ('symbol', 'reverse')
3457 ('symbol', 'reverse')
3458 (func
3458 (func
3459 ('symbol', 'sort')
3459 ('symbol', 'sort')
3460 (list
3460 (list
3461 (range
3461 (range
3462 ('symbol', '2')
3462 ('symbol', '2')
3463 ('symbol', '5'))
3463 ('symbol', '5'))
3464 ('symbol', 'date'))))
3464 ('symbol', 'date'))))
3465 * set:
3465 * set:
3466 <baseset [4, 5, 3, 2]>
3466 <baseset [4, 5, 3, 2]>
3467 4
3467 4
3468 5
3468 5
3469 3
3469 3
3470 2
3470 2
3471 $ try 'rs(2 or 3, date)'
3471 $ try 'rs(2 or 3, date)'
3472 (func
3472 (func
3473 ('symbol', 'rs')
3473 ('symbol', 'rs')
3474 (list
3474 (list
3475 (or
3475 (or
3476 (list
3476 (list
3477 ('symbol', '2')
3477 ('symbol', '2')
3478 ('symbol', '3')))
3478 ('symbol', '3')))
3479 ('symbol', 'date')))
3479 ('symbol', 'date')))
3480 * expanded:
3480 * expanded:
3481 (func
3481 (func
3482 ('symbol', 'reverse')
3482 ('symbol', 'reverse')
3483 (func
3483 (func
3484 ('symbol', 'sort')
3484 ('symbol', 'sort')
3485 (list
3485 (list
3486 (or
3486 (or
3487 (list
3487 (list
3488 ('symbol', '2')
3488 ('symbol', '2')
3489 ('symbol', '3')))
3489 ('symbol', '3')))
3490 ('symbol', 'date'))))
3490 ('symbol', 'date'))))
3491 * set:
3491 * set:
3492 <baseset [3, 2]>
3492 <baseset [3, 2]>
3493 3
3493 3
3494 2
3494 2
3495 $ try 'rs()'
3495 $ try 'rs()'
3496 (func
3496 (func
3497 ('symbol', 'rs')
3497 ('symbol', 'rs')
3498 None)
3498 None)
3499 hg: parse error: invalid number of arguments: 0
3499 hg: parse error: invalid number of arguments: 0
3500 [255]
3500 [255]
3501 $ try 'rs(2)'
3501 $ try 'rs(2)'
3502 (func
3502 (func
3503 ('symbol', 'rs')
3503 ('symbol', 'rs')
3504 ('symbol', '2'))
3504 ('symbol', '2'))
3505 hg: parse error: invalid number of arguments: 1
3505 hg: parse error: invalid number of arguments: 1
3506 [255]
3506 [255]
3507 $ try 'rs(2, data, 7)'
3507 $ try 'rs(2, data, 7)'
3508 (func
3508 (func
3509 ('symbol', 'rs')
3509 ('symbol', 'rs')
3510 (list
3510 (list
3511 ('symbol', '2')
3511 ('symbol', '2')
3512 ('symbol', 'data')
3512 ('symbol', 'data')
3513 ('symbol', '7')))
3513 ('symbol', '7')))
3514 hg: parse error: invalid number of arguments: 3
3514 hg: parse error: invalid number of arguments: 3
3515 [255]
3515 [255]
3516 $ try 'rs4(2 or 3, x, x, date)'
3516 $ try 'rs4(2 or 3, x, x, date)'
3517 (func
3517 (func
3518 ('symbol', 'rs4')
3518 ('symbol', 'rs4')
3519 (list
3519 (list
3520 (or
3520 (or
3521 (list
3521 (list
3522 ('symbol', '2')
3522 ('symbol', '2')
3523 ('symbol', '3')))
3523 ('symbol', '3')))
3524 ('symbol', 'x')
3524 ('symbol', 'x')
3525 ('symbol', 'x')
3525 ('symbol', 'x')
3526 ('symbol', 'date')))
3526 ('symbol', 'date')))
3527 * expanded:
3527 * expanded:
3528 (func
3528 (func
3529 ('symbol', 'reverse')
3529 ('symbol', 'reverse')
3530 (func
3530 (func
3531 ('symbol', 'sort')
3531 ('symbol', 'sort')
3532 (list
3532 (list
3533 (or
3533 (or
3534 (list
3534 (list
3535 ('symbol', '2')
3535 ('symbol', '2')
3536 ('symbol', '3')))
3536 ('symbol', '3')))
3537 ('symbol', 'date'))))
3537 ('symbol', 'date'))))
3538 * set:
3538 * set:
3539 <baseset [3, 2]>
3539 <baseset [3, 2]>
3540 3
3540 3
3541 2
3541 2
3542
3542
3543 issue4553: check that revset aliases override existing hash prefix
3543 issue4553: check that revset aliases override existing hash prefix
3544
3544
3545 $ hg log -qr e
3545 $ hg log -qr e
3546 6:e0cc66ef77e8
3546 6:e0cc66ef77e8
3547
3547
3548 $ hg log -qr e --config revsetalias.e="all()"
3548 $ hg log -qr e --config revsetalias.e="all()"
3549 0:2785f51eece5
3549 0:2785f51eece5
3550 1:d75937da8da0
3550 1:d75937da8da0
3551 2:5ed5505e9f1c
3551 2:5ed5505e9f1c
3552 3:8528aa5637f2
3552 3:8528aa5637f2
3553 4:2326846efdab
3553 4:2326846efdab
3554 5:904fa392b941
3554 5:904fa392b941
3555 6:e0cc66ef77e8
3555 6:e0cc66ef77e8
3556 7:013af1973af4
3556 7:013af1973af4
3557 8:d5d0dcbdc4d9
3557 8:d5d0dcbdc4d9
3558 9:24286f4ae135
3558 9:24286f4ae135
3559
3559
3560 $ hg log -qr e: --config revsetalias.e="0"
3560 $ hg log -qr e: --config revsetalias.e="0"
3561 0:2785f51eece5
3561 0:2785f51eece5
3562 1:d75937da8da0
3562 1:d75937da8da0
3563 2:5ed5505e9f1c
3563 2:5ed5505e9f1c
3564 3:8528aa5637f2
3564 3:8528aa5637f2
3565 4:2326846efdab
3565 4:2326846efdab
3566 5:904fa392b941
3566 5:904fa392b941
3567 6:e0cc66ef77e8
3567 6:e0cc66ef77e8
3568 7:013af1973af4
3568 7:013af1973af4
3569 8:d5d0dcbdc4d9
3569 8:d5d0dcbdc4d9
3570 9:24286f4ae135
3570 9:24286f4ae135
3571
3571
3572 $ hg log -qr :e --config revsetalias.e="9"
3572 $ hg log -qr :e --config revsetalias.e="9"
3573 0:2785f51eece5
3573 0:2785f51eece5
3574 1:d75937da8da0
3574 1:d75937da8da0
3575 2:5ed5505e9f1c
3575 2:5ed5505e9f1c
3576 3:8528aa5637f2
3576 3:8528aa5637f2
3577 4:2326846efdab
3577 4:2326846efdab
3578 5:904fa392b941
3578 5:904fa392b941
3579 6:e0cc66ef77e8
3579 6:e0cc66ef77e8
3580 7:013af1973af4
3580 7:013af1973af4
3581 8:d5d0dcbdc4d9
3581 8:d5d0dcbdc4d9
3582 9:24286f4ae135
3582 9:24286f4ae135
3583
3583
3584 $ hg log -qr e:
3584 $ hg log -qr e:
3585 6:e0cc66ef77e8
3585 6:e0cc66ef77e8
3586 7:013af1973af4
3586 7:013af1973af4
3587 8:d5d0dcbdc4d9
3587 8:d5d0dcbdc4d9
3588 9:24286f4ae135
3588 9:24286f4ae135
3589
3589
3590 $ hg log -qr :e
3590 $ hg log -qr :e
3591 0:2785f51eece5
3591 0:2785f51eece5
3592 1:d75937da8da0
3592 1:d75937da8da0
3593 2:5ed5505e9f1c
3593 2:5ed5505e9f1c
3594 3:8528aa5637f2
3594 3:8528aa5637f2
3595 4:2326846efdab
3595 4:2326846efdab
3596 5:904fa392b941
3596 5:904fa392b941
3597 6:e0cc66ef77e8
3597 6:e0cc66ef77e8
3598
3598
3599 issue2549 - correct optimizations
3599 issue2549 - correct optimizations
3600
3600
3601 $ try 'limit(1 or 2 or 3, 2) and not 2'
3601 $ try 'limit(1 or 2 or 3, 2) and not 2'
3602 (and
3602 (and
3603 (func
3603 (func
3604 ('symbol', 'limit')
3604 ('symbol', 'limit')
3605 (list
3605 (list
3606 (or
3606 (or
3607 (list
3607 (list
3608 ('symbol', '1')
3608 ('symbol', '1')
3609 ('symbol', '2')
3609 ('symbol', '2')
3610 ('symbol', '3')))
3610 ('symbol', '3')))
3611 ('symbol', '2')))
3611 ('symbol', '2')))
3612 (not
3612 (not
3613 ('symbol', '2')))
3613 ('symbol', '2')))
3614 * set:
3614 * set:
3615 <filteredset
3615 <filteredset
3616 <baseset
3616 <baseset
3617 <limit n=2, offset=0,
3617 <limit n=2, offset=0,
3618 <baseset [1, 2, 3]>>>,
3618 <baseset [1, 2, 3]>>>,
3619 <not
3619 <not
3620 <baseset [2]>>>
3620 <baseset [2]>>>
3621 1
3621 1
3622 $ try 'max(1 or 2) and not 2'
3622 $ try 'max(1 or 2) and not 2'
3623 (and
3623 (and
3624 (func
3624 (func
3625 ('symbol', 'max')
3625 ('symbol', 'max')
3626 (or
3626 (or
3627 (list
3627 (list
3628 ('symbol', '1')
3628 ('symbol', '1')
3629 ('symbol', '2'))))
3629 ('symbol', '2'))))
3630 (not
3630 (not
3631 ('symbol', '2')))
3631 ('symbol', '2')))
3632 * set:
3632 * set:
3633 <filteredset
3633 <filteredset
3634 <baseset
3634 <baseset
3635 <max
3635 <max
3636 <fullreposet+ 0:9>,
3636 <fullreposet+ 0:10>,
3637 <baseset [1, 2]>>>,
3637 <baseset [1, 2]>>>,
3638 <not
3638 <not
3639 <baseset [2]>>>
3639 <baseset [2]>>>
3640 $ try 'min(1 or 2) and not 1'
3640 $ try 'min(1 or 2) and not 1'
3641 (and
3641 (and
3642 (func
3642 (func
3643 ('symbol', 'min')
3643 ('symbol', 'min')
3644 (or
3644 (or
3645 (list
3645 (list
3646 ('symbol', '1')
3646 ('symbol', '1')
3647 ('symbol', '2'))))
3647 ('symbol', '2'))))
3648 (not
3648 (not
3649 ('symbol', '1')))
3649 ('symbol', '1')))
3650 * set:
3650 * set:
3651 <filteredset
3651 <filteredset
3652 <baseset
3652 <baseset
3653 <min
3653 <min
3654 <fullreposet+ 0:9>,
3654 <fullreposet+ 0:10>,
3655 <baseset [1, 2]>>>,
3655 <baseset [1, 2]>>>,
3656 <not
3656 <not
3657 <baseset [1]>>>
3657 <baseset [1]>>>
3658 $ try 'last(1 or 2, 1) and not 2'
3658 $ try 'last(1 or 2, 1) and not 2'
3659 (and
3659 (and
3660 (func
3660 (func
3661 ('symbol', 'last')
3661 ('symbol', 'last')
3662 (list
3662 (list
3663 (or
3663 (or
3664 (list
3664 (list
3665 ('symbol', '1')
3665 ('symbol', '1')
3666 ('symbol', '2')))
3666 ('symbol', '2')))
3667 ('symbol', '1')))
3667 ('symbol', '1')))
3668 (not
3668 (not
3669 ('symbol', '2')))
3669 ('symbol', '2')))
3670 * set:
3670 * set:
3671 <filteredset
3671 <filteredset
3672 <baseset
3672 <baseset
3673 <last n=1,
3673 <last n=1,
3674 <baseset [2, 1]>>>,
3674 <baseset [2, 1]>>>,
3675 <not
3675 <not
3676 <baseset [2]>>>
3676 <baseset [2]>>>
3677
3677
3678 issue4289 - ordering of built-ins
3678 issue4289 - ordering of built-ins
3679 $ hg log -M -q -r 3:2
3679 $ hg log -M -q -r 3:2
3680 3:8528aa5637f2
3680 3:8528aa5637f2
3681 2:5ed5505e9f1c
3681 2:5ed5505e9f1c
3682
3682
3683 test revsets started with 40-chars hash (issue3669)
3683 test revsets started with 40-chars hash (issue3669)
3684
3684
3685 $ ISSUE3669_TIP=`hg tip --template '{node}'`
3685 $ ISSUE3669_TIP=`hg tip --template '{node}'`
3686 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
3686 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
3687 9
3687 9
3688 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
3688 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
3689 8
3689 8
3690
3690
3691 test or-ed indirect predicates (issue3775)
3691 test or-ed indirect predicates (issue3775)
3692
3692
3693 $ log '6 or 6^1' | sort
3693 $ log '6 or 6^1' | sort
3694 5
3694 5
3695 6
3695 6
3696 $ log '6^1 or 6' | sort
3696 $ log '6^1 or 6' | sort
3697 5
3697 5
3698 6
3698 6
3699 $ log '4 or 4~1' | sort
3699 $ log '4 or 4~1' | sort
3700 2
3700 2
3701 4
3701 4
3702 $ log '4~1 or 4' | sort
3702 $ log '4~1 or 4' | sort
3703 2
3703 2
3704 4
3704 4
3705 $ log '(0 or 2):(4 or 6) or 0 or 6' | sort
3705 $ log '(0 or 2):(4 or 6) or 0 or 6' | sort
3706 0
3706 0
3707 1
3707 1
3708 2
3708 2
3709 3
3709 3
3710 4
3710 4
3711 5
3711 5
3712 6
3712 6
3713 $ log '0 or 6 or (0 or 2):(4 or 6)' | sort
3713 $ log '0 or 6 or (0 or 2):(4 or 6)' | sort
3714 0
3714 0
3715 1
3715 1
3716 2
3716 2
3717 3
3717 3
3718 4
3718 4
3719 5
3719 5
3720 6
3720 6
3721
3721
3722 tests for 'remote()' predicate:
3722 tests for 'remote()' predicate:
3723 #. (csets in remote) (id) (remote)
3723 #. (csets in remote) (id) (remote)
3724 1. less than local current branch "default"
3724 1. less than local current branch "default"
3725 2. same with local specified "default"
3725 2. same with local specified "default"
3726 3. more than local specified specified
3726 3. more than local specified specified
3727
3727
3728 $ hg clone --quiet -U . ../remote3
3728 $ hg clone --quiet -U . ../remote3
3729 $ cd ../remote3
3729 $ cd ../remote3
3730 $ hg update -q 7
3730 $ hg update -q 7
3731 $ echo r > r
3731 $ echo r > r
3732 $ hg ci -Aqm 10
3732 $ hg ci -Aqm 10
3733 $ log 'remote()'
3733 $ log 'remote()'
3734 7
3734 7
3735 $ log 'remote("a-b-c-")'
3735 $ log 'remote("a-b-c-")'
3736 2
3736 2
3737 $ cd ../repo
3737 $ cd ../repo
3738 $ log 'remote(".a.b.c.", "../remote3")'
3738 $ log 'remote(".a.b.c.", "../remote3")'
3739
3739
3740 tests for concatenation of strings/symbols by "##"
3740 tests for concatenation of strings/symbols by "##"
3741
3741
3742 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
3742 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
3743 (_concat
3743 (_concat
3744 (_concat
3744 (_concat
3745 (_concat
3745 (_concat
3746 ('symbol', '278')
3746 ('symbol', '278')
3747 ('string', '5f5'))
3747 ('string', '5f5'))
3748 ('symbol', '1ee'))
3748 ('symbol', '1ee'))
3749 ('string', 'ce5'))
3749 ('string', 'ce5'))
3750 * concatenated:
3750 * concatenated:
3751 ('string', '2785f51eece5')
3751 ('string', '2785f51eece5')
3752 * set:
3752 * set:
3753 <baseset [0]>
3753 <baseset [0]>
3754 0
3754 0
3755
3755
3756 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
3756 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
3757 $ try "cat4(278, '5f5', 1ee, 'ce5')"
3757 $ try "cat4(278, '5f5', 1ee, 'ce5')"
3758 (func
3758 (func
3759 ('symbol', 'cat4')
3759 ('symbol', 'cat4')
3760 (list
3760 (list
3761 ('symbol', '278')
3761 ('symbol', '278')
3762 ('string', '5f5')
3762 ('string', '5f5')
3763 ('symbol', '1ee')
3763 ('symbol', '1ee')
3764 ('string', 'ce5')))
3764 ('string', 'ce5')))
3765 * expanded:
3765 * expanded:
3766 (_concat
3766 (_concat
3767 (_concat
3767 (_concat
3768 (_concat
3768 (_concat
3769 ('symbol', '278')
3769 ('symbol', '278')
3770 ('string', '5f5'))
3770 ('string', '5f5'))
3771 ('symbol', '1ee'))
3771 ('symbol', '1ee'))
3772 ('string', 'ce5'))
3772 ('string', 'ce5'))
3773 * concatenated:
3773 * concatenated:
3774 ('string', '2785f51eece5')
3774 ('string', '2785f51eece5')
3775 * set:
3775 * set:
3776 <baseset [0]>
3776 <baseset [0]>
3777 0
3777 0
3778
3778
3779 (check concatenation in alias nesting)
3779 (check concatenation in alias nesting)
3780
3780
3781 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
3781 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
3782 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
3782 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
3783 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
3783 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
3784 0
3784 0
3785
3785
3786 (check operator priority)
3786 (check operator priority)
3787
3787
3788 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
3788 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
3789 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
3789 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
3790 0
3790 0
3791 4
3791 4
3792
3792
3793 $ cd ..
3793 $ cd ..
3794
3794
3795 prepare repository that has "default" branches of multiple roots
3795 prepare repository that has "default" branches of multiple roots
3796
3796
3797 $ hg init namedbranch
3797 $ hg init namedbranch
3798 $ cd namedbranch
3798 $ cd namedbranch
3799
3799
3800 $ echo default0 >> a
3800 $ echo default0 >> a
3801 $ hg ci -Aqm0
3801 $ hg ci -Aqm0
3802 $ echo default1 >> a
3802 $ echo default1 >> a
3803 $ hg ci -m1
3803 $ hg ci -m1
3804
3804
3805 $ hg branch -q stable
3805 $ hg branch -q stable
3806 $ echo stable2 >> a
3806 $ echo stable2 >> a
3807 $ hg ci -m2
3807 $ hg ci -m2
3808 $ echo stable3 >> a
3808 $ echo stable3 >> a
3809 $ hg ci -m3
3809 $ hg ci -m3
3810
3810
3811 $ hg update -q null
3811 $ hg update -q null
3812 $ echo default4 >> a
3812 $ echo default4 >> a
3813 $ hg ci -Aqm4
3813 $ hg ci -Aqm4
3814 $ echo default5 >> a
3814 $ echo default5 >> a
3815 $ hg ci -m5
3815 $ hg ci -m5
3816
3816
3817 "null" revision belongs to "default" branch (issue4683)
3817 "null" revision belongs to "default" branch (issue4683)
3818
3818
3819 $ log 'branch(null)'
3819 $ log 'branch(null)'
3820 0
3820 0
3821 1
3821 1
3822 4
3822 4
3823 5
3823 5
3824
3824
3825 "null" revision belongs to "default" branch, but it shouldn't appear in set
3825 "null" revision belongs to "default" branch, but it shouldn't appear in set
3826 unless explicitly specified (issue4682)
3826 unless explicitly specified (issue4682)
3827
3827
3828 $ log 'children(branch(default))'
3828 $ log 'children(branch(default))'
3829 1
3829 1
3830 2
3830 2
3831 5
3831 5
3832
3832
3833 $ cd ..
3833 $ cd ..
3834
3834
3835 test author/desc/keyword in problematic encoding
3835 test author/desc/keyword in problematic encoding
3836 # unicode: cp932:
3836 # unicode: cp932:
3837 # u30A2 0x83 0x41(= 'A')
3837 # u30A2 0x83 0x41(= 'A')
3838 # u30C2 0x83 0x61(= 'a')
3838 # u30C2 0x83 0x61(= 'a')
3839
3839
3840 $ hg init problematicencoding
3840 $ hg init problematicencoding
3841 $ cd problematicencoding
3841 $ cd problematicencoding
3842
3842
3843 $ python > setup.sh <<EOF
3843 $ python > setup.sh <<EOF
3844 > print u'''
3844 > print u'''
3845 > echo a > text
3845 > echo a > text
3846 > hg add text
3846 > hg add text
3847 > hg --encoding utf-8 commit -u '\u30A2' -m none
3847 > hg --encoding utf-8 commit -u '\u30A2' -m none
3848 > echo b > text
3848 > echo b > text
3849 > hg --encoding utf-8 commit -u '\u30C2' -m none
3849 > hg --encoding utf-8 commit -u '\u30C2' -m none
3850 > echo c > text
3850 > echo c > text
3851 > hg --encoding utf-8 commit -u none -m '\u30A2'
3851 > hg --encoding utf-8 commit -u none -m '\u30A2'
3852 > echo d > text
3852 > echo d > text
3853 > hg --encoding utf-8 commit -u none -m '\u30C2'
3853 > hg --encoding utf-8 commit -u none -m '\u30C2'
3854 > '''.encode('utf-8')
3854 > '''.encode('utf-8')
3855 > EOF
3855 > EOF
3856 $ sh < setup.sh
3856 $ sh < setup.sh
3857
3857
3858 test in problematic encoding
3858 test in problematic encoding
3859 $ python > test.sh <<EOF
3859 $ python > test.sh <<EOF
3860 > print u'''
3860 > print u'''
3861 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
3861 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
3862 > echo ====
3862 > echo ====
3863 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
3863 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
3864 > echo ====
3864 > echo ====
3865 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
3865 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
3866 > echo ====
3866 > echo ====
3867 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
3867 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
3868 > echo ====
3868 > echo ====
3869 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
3869 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
3870 > echo ====
3870 > echo ====
3871 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
3871 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
3872 > '''.encode('cp932')
3872 > '''.encode('cp932')
3873 > EOF
3873 > EOF
3874 $ sh < test.sh
3874 $ sh < test.sh
3875 0
3875 0
3876 ====
3876 ====
3877 1
3877 1
3878 ====
3878 ====
3879 2
3879 2
3880 ====
3880 ====
3881 3
3881 3
3882 ====
3882 ====
3883 0
3883 0
3884 2
3884 2
3885 ====
3885 ====
3886 1
3886 1
3887 3
3887 3
3888
3888
3889 test error message of bad revset
3889 test error message of bad revset
3890 $ hg log -r 'foo\\'
3890 $ hg log -r 'foo\\'
3891 hg: parse error at 3: syntax error in revset 'foo\\'
3891 hg: parse error at 3: syntax error in revset 'foo\\'
3892 [255]
3892 [255]
3893
3893
3894 $ cd ..
3894 $ cd ..
3895
3895
3896 Test that revset predicate of extension isn't loaded at failure of
3896 Test that revset predicate of extension isn't loaded at failure of
3897 loading it
3897 loading it
3898
3898
3899 $ cd repo
3899 $ cd repo
3900
3900
3901 $ cat <<EOF > $TESTTMP/custompredicate.py
3901 $ cat <<EOF > $TESTTMP/custompredicate.py
3902 > from mercurial import error, registrar, revset
3902 > from mercurial import error, registrar, revset
3903 >
3903 >
3904 > revsetpredicate = registrar.revsetpredicate()
3904 > revsetpredicate = registrar.revsetpredicate()
3905 >
3905 >
3906 > @revsetpredicate('custom1()')
3906 > @revsetpredicate('custom1()')
3907 > def custom1(repo, subset, x):
3907 > def custom1(repo, subset, x):
3908 > return revset.baseset([1])
3908 > return revset.baseset([1])
3909 >
3909 >
3910 > raise error.Abort('intentional failure of loading extension')
3910 > raise error.Abort('intentional failure of loading extension')
3911 > EOF
3911 > EOF
3912 $ cat <<EOF > .hg/hgrc
3912 $ cat <<EOF > .hg/hgrc
3913 > [extensions]
3913 > [extensions]
3914 > custompredicate = $TESTTMP/custompredicate.py
3914 > custompredicate = $TESTTMP/custompredicate.py
3915 > EOF
3915 > EOF
3916
3916
3917 $ hg debugrevspec "custom1()"
3917 $ hg debugrevspec "custom1()"
3918 *** failed to import extension custompredicate from $TESTTMP/custompredicate.py: intentional failure of loading extension
3918 *** failed to import extension custompredicate from $TESTTMP/custompredicate.py: intentional failure of loading extension
3919 hg: parse error: unknown identifier: custom1
3919 hg: parse error: unknown identifier: custom1
3920 [255]
3920 [255]
3921
3921
3922 $ cd ..
3922 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now