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