##// END OF EJS Templates
smartset: split generatorset classes to avoid cycle...
Gregory Szorc -
r35517:12a46ad6 default
parent child Browse files
Show More
@@ -1,1125 +1,1136 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 r'_set' in other.__dict__ and r'_set' in
360 if (type(other) is baseset and r'_set' in other.__dict__ and r'_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
769
770 >>> xs = generatorset([0, 1, 4], iterasc=True)
770 >>> xs = generatorset([0, 1, 4], iterasc=True)
771 >>> assert xs.last() == xs.last()
771 >>> assert xs.last() == xs.last()
772 >>> xs.last() # cached
772 >>> xs.last() # cached
773 4
773 4
774 """
774 """
775 def __new__(cls, gen, iterasc=None):
776 if iterasc is None:
777 typ = cls
778 elif iterasc:
779 typ = _generatorsetasc
780 else:
781 typ = _generatorsetdesc
782
783 return super(generatorset, cls).__new__(typ)
784
775 def __init__(self, gen, iterasc=None):
785 def __init__(self, gen, iterasc=None):
776 """
786 """
777 gen: a generator producing the values for the generatorset.
787 gen: a generator producing the values for the generatorset.
778 """
788 """
779 self._gen = gen
789 self._gen = gen
780 self._asclist = None
790 self._asclist = None
781 self._cache = {}
791 self._cache = {}
782 self._genlist = []
792 self._genlist = []
783 self._finished = False
793 self._finished = False
784 self._ascending = True
794 self._ascending = True
785 if iterasc is not None:
786 if iterasc:
787 self.fastasc = self._iterator
788 self.__contains__ = self._asccontains
789 else:
790 self.fastdesc = self._iterator
791 self.__contains__ = self._desccontains
792
795
793 def __nonzero__(self):
796 def __nonzero__(self):
794 # Do not use 'for r in self' because it will enforce the iteration
797 # Do not use 'for r in self' because it will enforce the iteration
795 # order (default ascending), possibly unrolling a whole descending
798 # order (default ascending), possibly unrolling a whole descending
796 # iterator.
799 # iterator.
797 if self._genlist:
800 if self._genlist:
798 return True
801 return True
799 for r in self._consumegen():
802 for r in self._consumegen():
800 return True
803 return True
801 return False
804 return False
802
805
803 __bool__ = __nonzero__
806 __bool__ = __nonzero__
804
807
805 def __contains__(self, x):
808 def __contains__(self, x):
806 if x in self._cache:
809 if x in self._cache:
807 return self._cache[x]
810 return self._cache[x]
808
811
809 # Use new values only, as existing values would be cached.
812 # Use new values only, as existing values would be cached.
810 for l in self._consumegen():
813 for l in self._consumegen():
811 if l == x:
814 if l == x:
812 return True
815 return True
813
816
814 self._cache[x] = False
817 self._cache[x] = False
815 return False
818 return False
816
819
817 def _asccontains(self, x):
818 """version of contains optimised for ascending generator"""
819 if x in self._cache:
820 return self._cache[x]
821
822 # Use new values only, as existing values would be cached.
823 for l in self._consumegen():
824 if l == x:
825 return True
826 if l > x:
827 break
828
829 self._cache[x] = False
830 return False
831
832 def _desccontains(self, x):
833 """version of contains optimised for descending generator"""
834 if x in self._cache:
835 return self._cache[x]
836
837 # Use new values only, as existing values would be cached.
838 for l in self._consumegen():
839 if l == x:
840 return True
841 if l < x:
842 break
843
844 self._cache[x] = False
845 return False
846
847 def __iter__(self):
820 def __iter__(self):
848 if self._ascending:
821 if self._ascending:
849 it = self.fastasc
822 it = self.fastasc
850 else:
823 else:
851 it = self.fastdesc
824 it = self.fastdesc
852 if it is not None:
825 if it is not None:
853 return it()
826 return it()
854 # we need to consume the iterator
827 # we need to consume the iterator
855 for x in self._consumegen():
828 for x in self._consumegen():
856 pass
829 pass
857 # recall the same code
830 # recall the same code
858 return iter(self)
831 return iter(self)
859
832
860 def _iterator(self):
833 def _iterator(self):
861 if self._finished:
834 if self._finished:
862 return iter(self._genlist)
835 return iter(self._genlist)
863
836
864 # We have to use this complex iteration strategy to allow multiple
837 # We have to use this complex iteration strategy to allow multiple
865 # iterations at the same time. We need to be able to catch revision
838 # iterations at the same time. We need to be able to catch revision
866 # removed from _consumegen and added to genlist in another instance.
839 # removed from _consumegen and added to genlist in another instance.
867 #
840 #
868 # Getting rid of it would provide an about 15% speed up on this
841 # Getting rid of it would provide an about 15% speed up on this
869 # iteration.
842 # iteration.
870 genlist = self._genlist
843 genlist = self._genlist
871 nextgen = self._consumegen()
844 nextgen = self._consumegen()
872 _len, _next = len, next # cache global lookup
845 _len, _next = len, next # cache global lookup
873 def gen():
846 def gen():
874 i = 0
847 i = 0
875 while True:
848 while True:
876 if i < _len(genlist):
849 if i < _len(genlist):
877 yield genlist[i]
850 yield genlist[i]
878 else:
851 else:
879 try:
852 try:
880 yield _next(nextgen)
853 yield _next(nextgen)
881 except StopIteration:
854 except StopIteration:
882 return
855 return
883 i += 1
856 i += 1
884 return gen()
857 return gen()
885
858
886 def _consumegen(self):
859 def _consumegen(self):
887 cache = self._cache
860 cache = self._cache
888 genlist = self._genlist.append
861 genlist = self._genlist.append
889 for item in self._gen:
862 for item in self._gen:
890 cache[item] = True
863 cache[item] = True
891 genlist(item)
864 genlist(item)
892 yield item
865 yield item
893 if not self._finished:
866 if not self._finished:
894 self._finished = True
867 self._finished = True
895 asc = self._genlist[:]
868 asc = self._genlist[:]
896 asc.sort()
869 asc.sort()
897 self._asclist = asc
870 self._asclist = asc
898 self.fastasc = asc.__iter__
871 self.fastasc = asc.__iter__
899 self.fastdesc = asc.__reversed__
872 self.fastdesc = asc.__reversed__
900
873
901 def __len__(self):
874 def __len__(self):
902 for x in self._consumegen():
875 for x in self._consumegen():
903 pass
876 pass
904 return len(self._genlist)
877 return len(self._genlist)
905
878
906 def sort(self, reverse=False):
879 def sort(self, reverse=False):
907 self._ascending = not reverse
880 self._ascending = not reverse
908
881
909 def reverse(self):
882 def reverse(self):
910 self._ascending = not self._ascending
883 self._ascending = not self._ascending
911
884
912 def isascending(self):
885 def isascending(self):
913 return self._ascending
886 return self._ascending
914
887
915 def isdescending(self):
888 def isdescending(self):
916 return not self._ascending
889 return not self._ascending
917
890
918 def istopo(self):
891 def istopo(self):
919 # not worth the trouble asserting if the two sets combined are still
892 # not worth the trouble asserting if the two sets combined are still
920 # in topographical order. Use the sort() predicate to explicitly sort
893 # in topographical order. Use the sort() predicate to explicitly sort
921 # again instead.
894 # again instead.
922 return False
895 return False
923
896
924 def first(self):
897 def first(self):
925 if self._ascending:
898 if self._ascending:
926 it = self.fastasc
899 it = self.fastasc
927 else:
900 else:
928 it = self.fastdesc
901 it = self.fastdesc
929 if it is None:
902 if it is None:
930 # we need to consume all and try again
903 # we need to consume all and try again
931 for x in self._consumegen():
904 for x in self._consumegen():
932 pass
905 pass
933 return self.first()
906 return self.first()
934 return next(it(), None)
907 return next(it(), None)
935
908
936 def last(self):
909 def last(self):
937 if self._ascending:
910 if self._ascending:
938 it = self.fastdesc
911 it = self.fastdesc
939 else:
912 else:
940 it = self.fastasc
913 it = self.fastasc
941 if it is None:
914 if it is None:
942 # we need to consume all and try again
915 # we need to consume all and try again
943 for x in self._consumegen():
916 for x in self._consumegen():
944 pass
917 pass
945 return self.last()
918 return self.last()
946 return next(it(), None)
919 return next(it(), None)
947
920
948 def __repr__(self):
921 def __repr__(self):
949 d = {False: '-', True: '+'}[self._ascending]
922 d = {False: '-', True: '+'}[self._ascending]
950 return '<%s%s>' % (type(self).__name__, d)
923 return '<%s%s>' % (type(self).__name__.lstrip('_'), d)
924
925 class _generatorsetasc(generatorset):
926 """Special case of generatorset optimized for ascending generators."""
927
928 fastasc = generatorset._iterator
929
930 def __contains__(self, x):
931 if x in self._cache:
932 return self._cache[x]
933
934 # Use new values only, as existing values would be cached.
935 for l in self._consumegen():
936 if l == x:
937 return True
938 if l > x:
939 break
940
941 self._cache[x] = False
942 return False
943
944 class _generatorsetdesc(generatorset):
945 """Special case of generatorset optimized for descending generators."""
946
947 fastdesc = generatorset._iterator
948
949 def __contains__(self, x):
950 if x in self._cache:
951 return self._cache[x]
952
953 # Use new values only, as existing values would be cached.
954 for l in self._consumegen():
955 if l == x:
956 return True
957 if l < x:
958 break
959
960 self._cache[x] = False
961 return False
951
962
952 def spanset(repo, start=0, end=None):
963 def spanset(repo, start=0, end=None):
953 """Create a spanset that represents a range of repository revisions
964 """Create a spanset that represents a range of repository revisions
954
965
955 start: first revision included the set (default to 0)
966 start: first revision included the set (default to 0)
956 end: first revision excluded (last+1) (default to len(repo))
967 end: first revision excluded (last+1) (default to len(repo))
957
968
958 Spanset will be descending if `end` < `start`.
969 Spanset will be descending if `end` < `start`.
959 """
970 """
960 if end is None:
971 if end is None:
961 end = len(repo)
972 end = len(repo)
962 ascending = start <= end
973 ascending = start <= end
963 if not ascending:
974 if not ascending:
964 start, end = end + 1, start + 1
975 start, end = end + 1, start + 1
965 return _spanset(start, end, ascending, repo.changelog.filteredrevs)
976 return _spanset(start, end, ascending, repo.changelog.filteredrevs)
966
977
967 class _spanset(abstractsmartset):
978 class _spanset(abstractsmartset):
968 """Duck type for baseset class which represents a range of revisions and
979 """Duck type for baseset class which represents a range of revisions and
969 can work lazily and without having all the range in memory
980 can work lazily and without having all the range in memory
970
981
971 Note that spanset(x, y) behave almost like xrange(x, y) except for two
982 Note that spanset(x, y) behave almost like xrange(x, y) except for two
972 notable points:
983 notable points:
973 - when x < y it will be automatically descending,
984 - when x < y it will be automatically descending,
974 - revision filtered with this repoview will be skipped.
985 - revision filtered with this repoview will be skipped.
975
986
976 """
987 """
977 def __init__(self, start, end, ascending, hiddenrevs):
988 def __init__(self, start, end, ascending, hiddenrevs):
978 self._start = start
989 self._start = start
979 self._end = end
990 self._end = end
980 self._ascending = ascending
991 self._ascending = ascending
981 self._hiddenrevs = hiddenrevs
992 self._hiddenrevs = hiddenrevs
982
993
983 def sort(self, reverse=False):
994 def sort(self, reverse=False):
984 self._ascending = not reverse
995 self._ascending = not reverse
985
996
986 def reverse(self):
997 def reverse(self):
987 self._ascending = not self._ascending
998 self._ascending = not self._ascending
988
999
989 def istopo(self):
1000 def istopo(self):
990 # not worth the trouble asserting if the two sets combined are still
1001 # not worth the trouble asserting if the two sets combined are still
991 # in topographical order. Use the sort() predicate to explicitly sort
1002 # in topographical order. Use the sort() predicate to explicitly sort
992 # again instead.
1003 # again instead.
993 return False
1004 return False
994
1005
995 def _iterfilter(self, iterrange):
1006 def _iterfilter(self, iterrange):
996 s = self._hiddenrevs
1007 s = self._hiddenrevs
997 for r in iterrange:
1008 for r in iterrange:
998 if r not in s:
1009 if r not in s:
999 yield r
1010 yield r
1000
1011
1001 def __iter__(self):
1012 def __iter__(self):
1002 if self._ascending:
1013 if self._ascending:
1003 return self.fastasc()
1014 return self.fastasc()
1004 else:
1015 else:
1005 return self.fastdesc()
1016 return self.fastdesc()
1006
1017
1007 def fastasc(self):
1018 def fastasc(self):
1008 iterrange = xrange(self._start, self._end)
1019 iterrange = xrange(self._start, self._end)
1009 if self._hiddenrevs:
1020 if self._hiddenrevs:
1010 return self._iterfilter(iterrange)
1021 return self._iterfilter(iterrange)
1011 return iter(iterrange)
1022 return iter(iterrange)
1012
1023
1013 def fastdesc(self):
1024 def fastdesc(self):
1014 iterrange = xrange(self._end - 1, self._start - 1, -1)
1025 iterrange = xrange(self._end - 1, self._start - 1, -1)
1015 if self._hiddenrevs:
1026 if self._hiddenrevs:
1016 return self._iterfilter(iterrange)
1027 return self._iterfilter(iterrange)
1017 return iter(iterrange)
1028 return iter(iterrange)
1018
1029
1019 def __contains__(self, rev):
1030 def __contains__(self, rev):
1020 hidden = self._hiddenrevs
1031 hidden = self._hiddenrevs
1021 return ((self._start <= rev < self._end)
1032 return ((self._start <= rev < self._end)
1022 and not (hidden and rev in hidden))
1033 and not (hidden and rev in hidden))
1023
1034
1024 def __nonzero__(self):
1035 def __nonzero__(self):
1025 for r in self:
1036 for r in self:
1026 return True
1037 return True
1027 return False
1038 return False
1028
1039
1029 __bool__ = __nonzero__
1040 __bool__ = __nonzero__
1030
1041
1031 def __len__(self):
1042 def __len__(self):
1032 if not self._hiddenrevs:
1043 if not self._hiddenrevs:
1033 return abs(self._end - self._start)
1044 return abs(self._end - self._start)
1034 else:
1045 else:
1035 count = 0
1046 count = 0
1036 start = self._start
1047 start = self._start
1037 end = self._end
1048 end = self._end
1038 for rev in self._hiddenrevs:
1049 for rev in self._hiddenrevs:
1039 if (end < rev <= start) or (start <= rev < end):
1050 if (end < rev <= start) or (start <= rev < end):
1040 count += 1
1051 count += 1
1041 return abs(self._end - self._start) - count
1052 return abs(self._end - self._start) - count
1042
1053
1043 def isascending(self):
1054 def isascending(self):
1044 return self._ascending
1055 return self._ascending
1045
1056
1046 def isdescending(self):
1057 def isdescending(self):
1047 return not self._ascending
1058 return not self._ascending
1048
1059
1049 def first(self):
1060 def first(self):
1050 if self._ascending:
1061 if self._ascending:
1051 it = self.fastasc
1062 it = self.fastasc
1052 else:
1063 else:
1053 it = self.fastdesc
1064 it = self.fastdesc
1054 for x in it():
1065 for x in it():
1055 return x
1066 return x
1056 return None
1067 return None
1057
1068
1058 def last(self):
1069 def last(self):
1059 if self._ascending:
1070 if self._ascending:
1060 it = self.fastdesc
1071 it = self.fastdesc
1061 else:
1072 else:
1062 it = self.fastasc
1073 it = self.fastasc
1063 for x in it():
1074 for x in it():
1064 return x
1075 return x
1065 return None
1076 return None
1066
1077
1067 def _slice(self, start, stop):
1078 def _slice(self, start, stop):
1068 if self._hiddenrevs:
1079 if self._hiddenrevs:
1069 # unoptimized since all hidden revisions in range has to be scanned
1080 # unoptimized since all hidden revisions in range has to be scanned
1070 return super(_spanset, self)._slice(start, stop)
1081 return super(_spanset, self)._slice(start, stop)
1071 if self._ascending:
1082 if self._ascending:
1072 x = min(self._start + start, self._end)
1083 x = min(self._start + start, self._end)
1073 y = min(self._start + stop, self._end)
1084 y = min(self._start + stop, self._end)
1074 else:
1085 else:
1075 x = max(self._end - stop, self._start)
1086 x = max(self._end - stop, self._start)
1076 y = max(self._end - start, self._start)
1087 y = max(self._end - start, self._start)
1077 return _spanset(x, y, self._ascending, self._hiddenrevs)
1088 return _spanset(x, y, self._ascending, self._hiddenrevs)
1078
1089
1079 def __repr__(self):
1090 def __repr__(self):
1080 d = {False: '-', True: '+'}[self._ascending]
1091 d = {False: '-', True: '+'}[self._ascending]
1081 return '<%s%s %d:%d>' % (type(self).__name__.lstrip('_'), d,
1092 return '<%s%s %d:%d>' % (type(self).__name__.lstrip('_'), d,
1082 self._start, self._end)
1093 self._start, self._end)
1083
1094
1084 class fullreposet(_spanset):
1095 class fullreposet(_spanset):
1085 """a set containing all revisions in the repo
1096 """a set containing all revisions in the repo
1086
1097
1087 This class exists to host special optimization and magic to handle virtual
1098 This class exists to host special optimization and magic to handle virtual
1088 revisions such as "null".
1099 revisions such as "null".
1089 """
1100 """
1090
1101
1091 def __init__(self, repo):
1102 def __init__(self, repo):
1092 super(fullreposet, self).__init__(0, len(repo), True,
1103 super(fullreposet, self).__init__(0, len(repo), True,
1093 repo.changelog.filteredrevs)
1104 repo.changelog.filteredrevs)
1094
1105
1095 def __and__(self, other):
1106 def __and__(self, other):
1096 """As self contains the whole repo, all of the other set should also be
1107 """As self contains the whole repo, all of the other set should also be
1097 in self. Therefore `self & other = other`.
1108 in self. Therefore `self & other = other`.
1098
1109
1099 This boldly assumes the other contains valid revs only.
1110 This boldly assumes the other contains valid revs only.
1100 """
1111 """
1101 # other not a smartset, make is so
1112 # other not a smartset, make is so
1102 if not util.safehasattr(other, 'isascending'):
1113 if not util.safehasattr(other, 'isascending'):
1103 # filter out hidden revision
1114 # filter out hidden revision
1104 # (this boldly assumes all smartset are pure)
1115 # (this boldly assumes all smartset are pure)
1105 #
1116 #
1106 # `other` was used with "&", let's assume this is a set like
1117 # `other` was used with "&", let's assume this is a set like
1107 # object.
1118 # object.
1108 other = baseset(other - self._hiddenrevs)
1119 other = baseset(other - self._hiddenrevs)
1109
1120
1110 other.sort(reverse=self.isdescending())
1121 other.sort(reverse=self.isdescending())
1111 return other
1122 return other
1112
1123
1113 def prettyformat(revs):
1124 def prettyformat(revs):
1114 lines = []
1125 lines = []
1115 rs = repr(revs)
1126 rs = repr(revs)
1116 p = 0
1127 p = 0
1117 while p < len(rs):
1128 while p < len(rs):
1118 q = rs.find('<', p + 1)
1129 q = rs.find('<', p + 1)
1119 if q < 0:
1130 if q < 0:
1120 q = len(rs)
1131 q = len(rs)
1121 l = rs.count('<', 0, p) - rs.count('>', 0, p)
1132 l = rs.count('<', 0, p) - rs.count('>', 0, p)
1122 assert l >= 0
1133 assert l >= 0
1123 lines.append((l, rs[p:q].rstrip()))
1134 lines.append((l, rs[p:q].rstrip()))
1124 p = q
1135 p = q
1125 return '\n'.join(' ' * l + s for l, s in lines)
1136 return '\n'.join(' ' * l + s for l, s in lines)
@@ -1,2739 +1,2739 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 > drawdag=$TESTDIR/drawdag.py
23 > drawdag=$TESTDIR/drawdag.py
24 > testrevset=$TESTTMP/testrevset.py
24 > testrevset=$TESTTMP/testrevset.py
25 > EOF
25 > EOF
26
26
27 $ try() {
27 $ try() {
28 > hg debugrevspec --debug "$@"
28 > hg debugrevspec --debug "$@"
29 > }
29 > }
30
30
31 $ log() {
31 $ log() {
32 > hg log --template '{rev}\n' -r "$1"
32 > hg log --template '{rev}\n' -r "$1"
33 > }
33 > }
34
34
35 extension to build '_intlist()' and '_hexlist()', which is necessary because
35 extension to build '_intlist()' and '_hexlist()', which is necessary because
36 these predicates use '\0' as a separator:
36 these predicates use '\0' as a separator:
37
37
38 $ cat <<EOF > debugrevlistspec.py
38 $ cat <<EOF > debugrevlistspec.py
39 > from __future__ import absolute_import
39 > from __future__ import absolute_import
40 > from mercurial import (
40 > from mercurial import (
41 > node as nodemod,
41 > node as nodemod,
42 > registrar,
42 > registrar,
43 > revset,
43 > revset,
44 > revsetlang,
44 > revsetlang,
45 > smartset,
45 > smartset,
46 > )
46 > )
47 > cmdtable = {}
47 > cmdtable = {}
48 > command = registrar.command(cmdtable)
48 > command = registrar.command(cmdtable)
49 > @command(b'debugrevlistspec',
49 > @command(b'debugrevlistspec',
50 > [('', 'optimize', None, 'print parsed tree after optimizing'),
50 > [('', 'optimize', None, 'print parsed tree after optimizing'),
51 > ('', 'bin', None, 'unhexlify arguments')])
51 > ('', 'bin', None, 'unhexlify arguments')])
52 > def debugrevlistspec(ui, repo, fmt, *args, **opts):
52 > def debugrevlistspec(ui, repo, fmt, *args, **opts):
53 > if opts['bin']:
53 > if opts['bin']:
54 > args = map(nodemod.bin, args)
54 > args = map(nodemod.bin, args)
55 > expr = revsetlang.formatspec(fmt, list(args))
55 > expr = revsetlang.formatspec(fmt, list(args))
56 > if ui.verbose:
56 > if ui.verbose:
57 > tree = revsetlang.parse(expr, lookup=repo.__contains__)
57 > tree = revsetlang.parse(expr, lookup=repo.__contains__)
58 > ui.note(revsetlang.prettyformat(tree), "\n")
58 > ui.note(revsetlang.prettyformat(tree), "\n")
59 > if opts["optimize"]:
59 > if opts["optimize"]:
60 > opttree = revsetlang.optimize(revsetlang.analyze(tree))
60 > opttree = revsetlang.optimize(revsetlang.analyze(tree))
61 > ui.note("* optimized:\n", revsetlang.prettyformat(opttree),
61 > ui.note("* optimized:\n", revsetlang.prettyformat(opttree),
62 > "\n")
62 > "\n")
63 > func = revset.match(ui, expr, repo)
63 > func = revset.match(ui, expr, repo)
64 > revs = func(repo)
64 > revs = func(repo)
65 > if ui.verbose:
65 > if ui.verbose:
66 > ui.note("* set:\n", smartset.prettyformat(revs), "\n")
66 > ui.note("* set:\n", smartset.prettyformat(revs), "\n")
67 > for c in revs:
67 > for c in revs:
68 > ui.write("%s\n" % c)
68 > ui.write("%s\n" % c)
69 > EOF
69 > EOF
70 $ cat <<EOF >> $HGRCPATH
70 $ cat <<EOF >> $HGRCPATH
71 > [extensions]
71 > [extensions]
72 > debugrevlistspec = $TESTTMP/debugrevlistspec.py
72 > debugrevlistspec = $TESTTMP/debugrevlistspec.py
73 > EOF
73 > EOF
74 $ trylist() {
74 $ trylist() {
75 > hg debugrevlistspec --debug "$@"
75 > hg debugrevlistspec --debug "$@"
76 > }
76 > }
77
77
78 $ hg init repo
78 $ hg init repo
79 $ cd repo
79 $ cd repo
80
80
81 $ echo a > a
81 $ echo a > a
82 $ hg branch a
82 $ hg branch a
83 marked working directory as branch a
83 marked working directory as branch a
84 (branches are permanent and global, did you want a bookmark?)
84 (branches are permanent and global, did you want a bookmark?)
85 $ hg ci -Aqm0
85 $ hg ci -Aqm0
86
86
87 $ echo b > b
87 $ echo b > b
88 $ hg branch b
88 $ hg branch b
89 marked working directory as branch b
89 marked working directory as branch b
90 $ hg ci -Aqm1
90 $ hg ci -Aqm1
91
91
92 $ rm a
92 $ rm a
93 $ hg branch a-b-c-
93 $ hg branch a-b-c-
94 marked working directory as branch a-b-c-
94 marked working directory as branch a-b-c-
95 $ hg ci -Aqm2 -u Bob
95 $ hg ci -Aqm2 -u Bob
96
96
97 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
97 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
98 2
98 2
99 $ hg log -r "extra('branch')" --template '{rev}\n'
99 $ hg log -r "extra('branch')" --template '{rev}\n'
100 0
100 0
101 1
101 1
102 2
102 2
103 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
103 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
104 0 a
104 0 a
105 2 a-b-c-
105 2 a-b-c-
106
106
107 $ hg co 1
107 $ hg co 1
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
108 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 $ hg branch +a+b+c+
109 $ hg branch +a+b+c+
110 marked working directory as branch +a+b+c+
110 marked working directory as branch +a+b+c+
111 $ hg ci -Aqm3
111 $ hg ci -Aqm3
112
112
113 $ hg co 2 # interleave
113 $ hg co 2 # interleave
114 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
114 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
115 $ echo bb > b
115 $ echo bb > b
116 $ hg branch -- -a-b-c-
116 $ hg branch -- -a-b-c-
117 marked working directory as branch -a-b-c-
117 marked working directory as branch -a-b-c-
118 $ hg ci -Aqm4 -d "May 12 2005"
118 $ hg ci -Aqm4 -d "May 12 2005"
119
119
120 $ hg co 3
120 $ hg co 3
121 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
121 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 $ hg branch !a/b/c/
122 $ hg branch !a/b/c/
123 marked working directory as branch !a/b/c/
123 marked working directory as branch !a/b/c/
124 $ hg ci -Aqm"5 bug"
124 $ hg ci -Aqm"5 bug"
125
125
126 $ hg merge 4
126 $ hg merge 4
127 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
127 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
128 (branch merge, don't forget to commit)
128 (branch merge, don't forget to commit)
129 $ hg branch _a_b_c_
129 $ hg branch _a_b_c_
130 marked working directory as branch _a_b_c_
130 marked working directory as branch _a_b_c_
131 $ hg ci -Aqm"6 issue619"
131 $ hg ci -Aqm"6 issue619"
132
132
133 $ hg branch .a.b.c.
133 $ hg branch .a.b.c.
134 marked working directory as branch .a.b.c.
134 marked working directory as branch .a.b.c.
135 $ hg ci -Aqm7
135 $ hg ci -Aqm7
136
136
137 $ hg branch all
137 $ hg branch all
138 marked working directory as branch all
138 marked working directory as branch all
139
139
140 $ hg co 4
140 $ hg co 4
141 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
141 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
142 $ hg branch Γ©
142 $ hg branch Γ©
143 marked working directory as branch \xc3\xa9 (esc)
143 marked working directory as branch \xc3\xa9 (esc)
144 $ hg ci -Aqm9
144 $ hg ci -Aqm9
145
145
146 $ hg tag -r6 1.0
146 $ hg tag -r6 1.0
147 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
147 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
148
148
149 $ hg clone --quiet -U -r 7 . ../remote1
149 $ hg clone --quiet -U -r 7 . ../remote1
150 $ hg clone --quiet -U -r 8 . ../remote2
150 $ hg clone --quiet -U -r 8 . ../remote2
151 $ echo "[paths]" >> .hg/hgrc
151 $ echo "[paths]" >> .hg/hgrc
152 $ echo "default = ../remote1" >> .hg/hgrc
152 $ echo "default = ../remote1" >> .hg/hgrc
153
153
154 trivial
154 trivial
155
155
156 $ try 0:1
156 $ try 0:1
157 (range
157 (range
158 (symbol '0')
158 (symbol '0')
159 (symbol '1'))
159 (symbol '1'))
160 * set:
160 * set:
161 <spanset+ 0:2>
161 <spanset+ 0:2>
162 0
162 0
163 1
163 1
164 $ try --optimize :
164 $ try --optimize :
165 (rangeall
165 (rangeall
166 None)
166 None)
167 * optimized:
167 * optimized:
168 (rangeall
168 (rangeall
169 None)
169 None)
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 hg: parse error: can't use a key-value pair in this context
498 hg: parse error: can't use a key-value pair in this context
499 [255]
499 [255]
500
500
501 relation-subscript operator has the highest binding strength (as function call):
501 relation-subscript operator has the highest binding strength (as function call):
502
502
503 $ hg debugrevspec -p parsed 'tip:tip^#generations[-1]'
503 $ hg debugrevspec -p parsed 'tip:tip^#generations[-1]'
504 * parsed:
504 * parsed:
505 (range
505 (range
506 (symbol 'tip')
506 (symbol 'tip')
507 (relsubscript
507 (relsubscript
508 (parentpost
508 (parentpost
509 (symbol 'tip'))
509 (symbol 'tip'))
510 (symbol 'generations')
510 (symbol 'generations')
511 (negate
511 (negate
512 (symbol '1'))))
512 (symbol '1'))))
513 9
513 9
514 8
514 8
515 7
515 7
516 6
516 6
517 5
517 5
518 4
518 4
519
519
520 $ hg debugrevspec -p parsed --no-show-revs 'not public()#generations[0]'
520 $ hg debugrevspec -p parsed --no-show-revs 'not public()#generations[0]'
521 * parsed:
521 * parsed:
522 (not
522 (not
523 (relsubscript
523 (relsubscript
524 (func
524 (func
525 (symbol 'public')
525 (symbol 'public')
526 None)
526 None)
527 (symbol 'generations')
527 (symbol 'generations')
528 (symbol '0')))
528 (symbol '0')))
529
529
530 left-hand side of relation-subscript operator should be optimized recursively:
530 left-hand side of relation-subscript operator should be optimized recursively:
531
531
532 $ hg debugrevspec -p analyzed -p optimized --no-show-revs \
532 $ hg debugrevspec -p analyzed -p optimized --no-show-revs \
533 > '(not public())#generations[0]'
533 > '(not public())#generations[0]'
534 * analyzed:
534 * analyzed:
535 (relsubscript
535 (relsubscript
536 (not
536 (not
537 (func
537 (func
538 (symbol 'public')
538 (symbol 'public')
539 None))
539 None))
540 (symbol 'generations')
540 (symbol 'generations')
541 (symbol '0'))
541 (symbol '0'))
542 * optimized:
542 * optimized:
543 (relsubscript
543 (relsubscript
544 (func
544 (func
545 (symbol '_notpublic')
545 (symbol '_notpublic')
546 None)
546 None)
547 (symbol 'generations')
547 (symbol 'generations')
548 (symbol '0'))
548 (symbol '0'))
549
549
550 resolution of subscript and relation-subscript ternary operators:
550 resolution of subscript and relation-subscript ternary operators:
551
551
552 $ hg debugrevspec -p analyzed 'tip[0]'
552 $ hg debugrevspec -p analyzed 'tip[0]'
553 * analyzed:
553 * analyzed:
554 (subscript
554 (subscript
555 (symbol 'tip')
555 (symbol 'tip')
556 (symbol '0'))
556 (symbol '0'))
557 hg: parse error: can't use a subscript in this context
557 hg: parse error: can't use a subscript in this context
558 [255]
558 [255]
559
559
560 $ hg debugrevspec -p analyzed 'tip#rel[0]'
560 $ hg debugrevspec -p analyzed 'tip#rel[0]'
561 * analyzed:
561 * analyzed:
562 (relsubscript
562 (relsubscript
563 (symbol 'tip')
563 (symbol 'tip')
564 (symbol 'rel')
564 (symbol 'rel')
565 (symbol '0'))
565 (symbol '0'))
566 hg: parse error: unknown identifier: rel
566 hg: parse error: unknown identifier: rel
567 [255]
567 [255]
568
568
569 $ hg debugrevspec -p analyzed '(tip#rel)[0]'
569 $ hg debugrevspec -p analyzed '(tip#rel)[0]'
570 * analyzed:
570 * analyzed:
571 (subscript
571 (subscript
572 (relation
572 (relation
573 (symbol 'tip')
573 (symbol 'tip')
574 (symbol 'rel'))
574 (symbol 'rel'))
575 (symbol '0'))
575 (symbol '0'))
576 hg: parse error: can't use a subscript in this context
576 hg: parse error: can't use a subscript in this context
577 [255]
577 [255]
578
578
579 $ hg debugrevspec -p analyzed 'tip#rel[0][1]'
579 $ hg debugrevspec -p analyzed 'tip#rel[0][1]'
580 * analyzed:
580 * analyzed:
581 (subscript
581 (subscript
582 (relsubscript
582 (relsubscript
583 (symbol 'tip')
583 (symbol 'tip')
584 (symbol 'rel')
584 (symbol 'rel')
585 (symbol '0'))
585 (symbol '0'))
586 (symbol '1'))
586 (symbol '1'))
587 hg: parse error: can't use a subscript in this context
587 hg: parse error: can't use a subscript in this context
588 [255]
588 [255]
589
589
590 $ hg debugrevspec -p analyzed 'tip#rel0#rel1[1]'
590 $ hg debugrevspec -p analyzed 'tip#rel0#rel1[1]'
591 * analyzed:
591 * analyzed:
592 (relsubscript
592 (relsubscript
593 (relation
593 (relation
594 (symbol 'tip')
594 (symbol 'tip')
595 (symbol 'rel0'))
595 (symbol 'rel0'))
596 (symbol 'rel1')
596 (symbol 'rel1')
597 (symbol '1'))
597 (symbol '1'))
598 hg: parse error: unknown identifier: rel1
598 hg: parse error: unknown identifier: rel1
599 [255]
599 [255]
600
600
601 $ hg debugrevspec -p analyzed 'tip#rel0[0]#rel1[1]'
601 $ hg debugrevspec -p analyzed 'tip#rel0[0]#rel1[1]'
602 * analyzed:
602 * analyzed:
603 (relsubscript
603 (relsubscript
604 (relsubscript
604 (relsubscript
605 (symbol 'tip')
605 (symbol 'tip')
606 (symbol 'rel0')
606 (symbol 'rel0')
607 (symbol '0'))
607 (symbol '0'))
608 (symbol 'rel1')
608 (symbol 'rel1')
609 (symbol '1'))
609 (symbol '1'))
610 hg: parse error: unknown identifier: rel1
610 hg: parse error: unknown identifier: rel1
611 [255]
611 [255]
612
612
613 parse errors of relation, subscript and relation-subscript operators:
613 parse errors of relation, subscript and relation-subscript operators:
614
614
615 $ hg debugrevspec '[0]'
615 $ hg debugrevspec '[0]'
616 hg: parse error at 0: not a prefix: [
616 hg: parse error at 0: not a prefix: [
617 [255]
617 [255]
618 $ hg debugrevspec '.#'
618 $ hg debugrevspec '.#'
619 hg: parse error at 2: not a prefix: end
619 hg: parse error at 2: not a prefix: end
620 [255]
620 [255]
621 $ hg debugrevspec '#rel'
621 $ hg debugrevspec '#rel'
622 hg: parse error at 0: not a prefix: #
622 hg: parse error at 0: not a prefix: #
623 [255]
623 [255]
624 $ hg debugrevspec '.#rel[0'
624 $ hg debugrevspec '.#rel[0'
625 hg: parse error at 7: unexpected token: end
625 hg: parse error at 7: unexpected token: end
626 [255]
626 [255]
627 $ hg debugrevspec '.]'
627 $ hg debugrevspec '.]'
628 hg: parse error at 1: invalid token
628 hg: parse error at 1: invalid token
629 [255]
629 [255]
630
630
631 $ hg debugrevspec '.#generations[a]'
631 $ hg debugrevspec '.#generations[a]'
632 hg: parse error: relation subscript must be an integer
632 hg: parse error: relation subscript must be an integer
633 [255]
633 [255]
634 $ hg debugrevspec '.#generations[1-2]'
634 $ hg debugrevspec '.#generations[1-2]'
635 hg: parse error: relation subscript must be an integer
635 hg: parse error: relation subscript must be an integer
636 [255]
636 [255]
637
637
638 parsed tree at stages:
638 parsed tree at stages:
639
639
640 $ hg debugrevspec -p all '()'
640 $ hg debugrevspec -p all '()'
641 * parsed:
641 * parsed:
642 (group
642 (group
643 None)
643 None)
644 * expanded:
644 * expanded:
645 (group
645 (group
646 None)
646 None)
647 * concatenated:
647 * concatenated:
648 (group
648 (group
649 None)
649 None)
650 * analyzed:
650 * analyzed:
651 None
651 None
652 * optimized:
652 * optimized:
653 None
653 None
654 hg: parse error: missing argument
654 hg: parse error: missing argument
655 [255]
655 [255]
656
656
657 $ hg debugrevspec --no-optimized -p all '()'
657 $ hg debugrevspec --no-optimized -p all '()'
658 * parsed:
658 * parsed:
659 (group
659 (group
660 None)
660 None)
661 * expanded:
661 * expanded:
662 (group
662 (group
663 None)
663 None)
664 * concatenated:
664 * concatenated:
665 (group
665 (group
666 None)
666 None)
667 * analyzed:
667 * analyzed:
668 None
668 None
669 hg: parse error: missing argument
669 hg: parse error: missing argument
670 [255]
670 [255]
671
671
672 $ hg debugrevspec -p parsed -p analyzed -p optimized '(0|1)-1'
672 $ hg debugrevspec -p parsed -p analyzed -p optimized '(0|1)-1'
673 * parsed:
673 * parsed:
674 (minus
674 (minus
675 (group
675 (group
676 (or
676 (or
677 (list
677 (list
678 (symbol '0')
678 (symbol '0')
679 (symbol '1'))))
679 (symbol '1'))))
680 (symbol '1'))
680 (symbol '1'))
681 * analyzed:
681 * analyzed:
682 (and
682 (and
683 (or
683 (or
684 (list
684 (list
685 (symbol '0')
685 (symbol '0')
686 (symbol '1')))
686 (symbol '1')))
687 (not
687 (not
688 (symbol '1')))
688 (symbol '1')))
689 * optimized:
689 * optimized:
690 (difference
690 (difference
691 (func
691 (func
692 (symbol '_list')
692 (symbol '_list')
693 (string '0\x001'))
693 (string '0\x001'))
694 (symbol '1'))
694 (symbol '1'))
695 0
695 0
696
696
697 $ hg debugrevspec -p unknown '0'
697 $ hg debugrevspec -p unknown '0'
698 abort: invalid stage name: unknown
698 abort: invalid stage name: unknown
699 [255]
699 [255]
700
700
701 $ hg debugrevspec -p all --optimize '0'
701 $ hg debugrevspec -p all --optimize '0'
702 abort: cannot use --optimize with --show-stage
702 abort: cannot use --optimize with --show-stage
703 [255]
703 [255]
704
704
705 verify optimized tree:
705 verify optimized tree:
706
706
707 $ hg debugrevspec --verify '0|1'
707 $ hg debugrevspec --verify '0|1'
708
708
709 $ hg debugrevspec --verify -v -p analyzed -p optimized 'r3232() & 2'
709 $ hg debugrevspec --verify -v -p analyzed -p optimized 'r3232() & 2'
710 * analyzed:
710 * analyzed:
711 (and
711 (and
712 (func
712 (func
713 (symbol 'r3232')
713 (symbol 'r3232')
714 None)
714 None)
715 (symbol '2'))
715 (symbol '2'))
716 * optimized:
716 * optimized:
717 (andsmally
717 (andsmally
718 (func
718 (func
719 (symbol 'r3232')
719 (symbol 'r3232')
720 None)
720 None)
721 (symbol '2'))
721 (symbol '2'))
722 * analyzed set:
722 * analyzed set:
723 <baseset [2]>
723 <baseset [2]>
724 * optimized set:
724 * optimized set:
725 <baseset [2, 2]>
725 <baseset [2, 2]>
726 --- analyzed
726 --- analyzed
727 +++ optimized
727 +++ optimized
728 2
728 2
729 +2
729 +2
730 [1]
730 [1]
731
731
732 $ hg debugrevspec --no-optimized --verify-optimized '0'
732 $ hg debugrevspec --no-optimized --verify-optimized '0'
733 abort: cannot use --verify-optimized with --no-optimized
733 abort: cannot use --verify-optimized with --no-optimized
734 [255]
734 [255]
735
735
736 Test that symbols only get parsed as functions if there's an opening
736 Test that symbols only get parsed as functions if there's an opening
737 parenthesis.
737 parenthesis.
738
738
739 $ hg book only -r 9
739 $ hg book only -r 9
740 $ log 'only(only)' # Outer "only" is a function, inner "only" is the bookmark
740 $ log 'only(only)' # Outer "only" is a function, inner "only" is the bookmark
741 8
741 8
742 9
742 9
743
743
744 ':y' behaves like '0:y', but can't be rewritten as such since the revision '0'
744 ':y' behaves like '0:y', but can't be rewritten as such since the revision '0'
745 may be hidden (issue5385)
745 may be hidden (issue5385)
746
746
747 $ try -p parsed -p analyzed ':'
747 $ try -p parsed -p analyzed ':'
748 * parsed:
748 * parsed:
749 (rangeall
749 (rangeall
750 None)
750 None)
751 * analyzed:
751 * analyzed:
752 (rangeall
752 (rangeall
753 None)
753 None)
754 * set:
754 * set:
755 <spanset+ 0:10>
755 <spanset+ 0:10>
756 0
756 0
757 1
757 1
758 2
758 2
759 3
759 3
760 4
760 4
761 5
761 5
762 6
762 6
763 7
763 7
764 8
764 8
765 9
765 9
766 $ try -p analyzed ':1'
766 $ try -p analyzed ':1'
767 * analyzed:
767 * analyzed:
768 (rangepre
768 (rangepre
769 (symbol '1'))
769 (symbol '1'))
770 * set:
770 * set:
771 <spanset+ 0:2>
771 <spanset+ 0:2>
772 0
772 0
773 1
773 1
774 $ try -p analyzed ':(1|2)'
774 $ try -p analyzed ':(1|2)'
775 * analyzed:
775 * analyzed:
776 (rangepre
776 (rangepre
777 (or
777 (or
778 (list
778 (list
779 (symbol '1')
779 (symbol '1')
780 (symbol '2'))))
780 (symbol '2'))))
781 * set:
781 * set:
782 <spanset+ 0:3>
782 <spanset+ 0:3>
783 0
783 0
784 1
784 1
785 2
785 2
786 $ try -p analyzed ':(1&2)'
786 $ try -p analyzed ':(1&2)'
787 * analyzed:
787 * analyzed:
788 (rangepre
788 (rangepre
789 (and
789 (and
790 (symbol '1')
790 (symbol '1')
791 (symbol '2')))
791 (symbol '2')))
792 * set:
792 * set:
793 <baseset []>
793 <baseset []>
794
794
795 infix/suffix resolution of ^ operator (issue2884):
795 infix/suffix resolution of ^ operator (issue2884):
796
796
797 x^:y means (x^):y
797 x^:y means (x^):y
798
798
799 $ try '1^:2'
799 $ try '1^:2'
800 (range
800 (range
801 (parentpost
801 (parentpost
802 (symbol '1'))
802 (symbol '1'))
803 (symbol '2'))
803 (symbol '2'))
804 * set:
804 * set:
805 <spanset+ 0:3>
805 <spanset+ 0:3>
806 0
806 0
807 1
807 1
808 2
808 2
809
809
810 $ try '1^::2'
810 $ try '1^::2'
811 (dagrange
811 (dagrange
812 (parentpost
812 (parentpost
813 (symbol '1'))
813 (symbol '1'))
814 (symbol '2'))
814 (symbol '2'))
815 * set:
815 * set:
816 <baseset+ [0, 1, 2]>
816 <baseset+ [0, 1, 2]>
817 0
817 0
818 1
818 1
819 2
819 2
820
820
821 $ try '9^:'
821 $ try '9^:'
822 (rangepost
822 (rangepost
823 (parentpost
823 (parentpost
824 (symbol '9')))
824 (symbol '9')))
825 * set:
825 * set:
826 <spanset+ 8:10>
826 <spanset+ 8:10>
827 8
827 8
828 9
828 9
829
829
830 x^:y should be resolved before omitting group operators
830 x^:y should be resolved before omitting group operators
831
831
832 $ try '1^(:2)'
832 $ try '1^(:2)'
833 (parent
833 (parent
834 (symbol '1')
834 (symbol '1')
835 (group
835 (group
836 (rangepre
836 (rangepre
837 (symbol '2'))))
837 (symbol '2'))))
838 hg: parse error: ^ expects a number 0, 1, or 2
838 hg: parse error: ^ expects a number 0, 1, or 2
839 [255]
839 [255]
840
840
841 x^:y should be resolved recursively
841 x^:y should be resolved recursively
842
842
843 $ try 'sort(1^:2)'
843 $ try 'sort(1^:2)'
844 (func
844 (func
845 (symbol 'sort')
845 (symbol 'sort')
846 (range
846 (range
847 (parentpost
847 (parentpost
848 (symbol '1'))
848 (symbol '1'))
849 (symbol '2')))
849 (symbol '2')))
850 * set:
850 * set:
851 <spanset+ 0:3>
851 <spanset+ 0:3>
852 0
852 0
853 1
853 1
854 2
854 2
855
855
856 $ try '(3^:4)^:2'
856 $ try '(3^:4)^:2'
857 (range
857 (range
858 (parentpost
858 (parentpost
859 (group
859 (group
860 (range
860 (range
861 (parentpost
861 (parentpost
862 (symbol '3'))
862 (symbol '3'))
863 (symbol '4'))))
863 (symbol '4'))))
864 (symbol '2'))
864 (symbol '2'))
865 * set:
865 * set:
866 <spanset+ 0:3>
866 <spanset+ 0:3>
867 0
867 0
868 1
868 1
869 2
869 2
870
870
871 $ try '(3^::4)^::2'
871 $ try '(3^::4)^::2'
872 (dagrange
872 (dagrange
873 (parentpost
873 (parentpost
874 (group
874 (group
875 (dagrange
875 (dagrange
876 (parentpost
876 (parentpost
877 (symbol '3'))
877 (symbol '3'))
878 (symbol '4'))))
878 (symbol '4'))))
879 (symbol '2'))
879 (symbol '2'))
880 * set:
880 * set:
881 <baseset+ [0, 1, 2]>
881 <baseset+ [0, 1, 2]>
882 0
882 0
883 1
883 1
884 2
884 2
885
885
886 $ try '(9^:)^:'
886 $ try '(9^:)^:'
887 (rangepost
887 (rangepost
888 (parentpost
888 (parentpost
889 (group
889 (group
890 (rangepost
890 (rangepost
891 (parentpost
891 (parentpost
892 (symbol '9'))))))
892 (symbol '9'))))))
893 * set:
893 * set:
894 <spanset+ 4:10>
894 <spanset+ 4:10>
895 4
895 4
896 5
896 5
897 6
897 6
898 7
898 7
899 8
899 8
900 9
900 9
901
901
902 x^ in alias should also be resolved
902 x^ in alias should also be resolved
903
903
904 $ try 'A' --config 'revsetalias.A=1^:2'
904 $ try 'A' --config 'revsetalias.A=1^:2'
905 (symbol 'A')
905 (symbol 'A')
906 * expanded:
906 * expanded:
907 (range
907 (range
908 (parentpost
908 (parentpost
909 (symbol '1'))
909 (symbol '1'))
910 (symbol '2'))
910 (symbol '2'))
911 * set:
911 * set:
912 <spanset+ 0:3>
912 <spanset+ 0:3>
913 0
913 0
914 1
914 1
915 2
915 2
916
916
917 $ try 'A:2' --config 'revsetalias.A=1^'
917 $ try 'A:2' --config 'revsetalias.A=1^'
918 (range
918 (range
919 (symbol 'A')
919 (symbol 'A')
920 (symbol '2'))
920 (symbol '2'))
921 * expanded:
921 * expanded:
922 (range
922 (range
923 (parentpost
923 (parentpost
924 (symbol '1'))
924 (symbol '1'))
925 (symbol '2'))
925 (symbol '2'))
926 * set:
926 * set:
927 <spanset+ 0:3>
927 <spanset+ 0:3>
928 0
928 0
929 1
929 1
930 2
930 2
931
931
932 but not beyond the boundary of alias expansion, because the resolution should
932 but not beyond the boundary of alias expansion, because the resolution should
933 be made at the parsing stage
933 be made at the parsing stage
934
934
935 $ try '1^A' --config 'revsetalias.A=:2'
935 $ try '1^A' --config 'revsetalias.A=:2'
936 (parent
936 (parent
937 (symbol '1')
937 (symbol '1')
938 (symbol 'A'))
938 (symbol 'A'))
939 * expanded:
939 * expanded:
940 (parent
940 (parent
941 (symbol '1')
941 (symbol '1')
942 (rangepre
942 (rangepre
943 (symbol '2')))
943 (symbol '2')))
944 hg: parse error: ^ expects a number 0, 1, or 2
944 hg: parse error: ^ expects a number 0, 1, or 2
945 [255]
945 [255]
946
946
947 ancestor can accept 0 or more arguments
947 ancestor can accept 0 or more arguments
948
948
949 $ log 'ancestor()'
949 $ log 'ancestor()'
950 $ log 'ancestor(1)'
950 $ log 'ancestor(1)'
951 1
951 1
952 $ log 'ancestor(4,5)'
952 $ log 'ancestor(4,5)'
953 1
953 1
954 $ log 'ancestor(4,5) and 4'
954 $ log 'ancestor(4,5) and 4'
955 $ log 'ancestor(0,0,1,3)'
955 $ log 'ancestor(0,0,1,3)'
956 0
956 0
957 $ log 'ancestor(3,1,5,3,5,1)'
957 $ log 'ancestor(3,1,5,3,5,1)'
958 1
958 1
959 $ log 'ancestor(0,1,3,5)'
959 $ log 'ancestor(0,1,3,5)'
960 0
960 0
961 $ log 'ancestor(1,2,3,4,5)'
961 $ log 'ancestor(1,2,3,4,5)'
962 1
962 1
963
963
964 test ancestors
964 test ancestors
965
965
966 $ hg log -G -T '{rev}\n' --config experimental.graphshorten=True
966 $ hg log -G -T '{rev}\n' --config experimental.graphshorten=True
967 @ 9
967 @ 9
968 o 8
968 o 8
969 | o 7
969 | o 7
970 | o 6
970 | o 6
971 |/|
971 |/|
972 | o 5
972 | o 5
973 o | 4
973 o | 4
974 | o 3
974 | o 3
975 o | 2
975 o | 2
976 |/
976 |/
977 o 1
977 o 1
978 o 0
978 o 0
979
979
980 $ log 'ancestors(5)'
980 $ log 'ancestors(5)'
981 0
981 0
982 1
982 1
983 3
983 3
984 5
984 5
985 $ log 'ancestor(ancestors(5))'
985 $ log 'ancestor(ancestors(5))'
986 0
986 0
987 $ log '::r3232()'
987 $ log '::r3232()'
988 0
988 0
989 1
989 1
990 2
990 2
991 3
991 3
992
992
993 test ancestors with depth limit
993 test ancestors with depth limit
994
994
995 (depth=0 selects the node itself)
995 (depth=0 selects the node itself)
996
996
997 $ log 'reverse(ancestors(9, depth=0))'
997 $ log 'reverse(ancestors(9, depth=0))'
998 9
998 9
999
999
1000 (interleaved: '4' would be missing if heap queue were higher depth first)
1000 (interleaved: '4' would be missing if heap queue were higher depth first)
1001
1001
1002 $ log 'reverse(ancestors(8:9, depth=1))'
1002 $ log 'reverse(ancestors(8:9, depth=1))'
1003 9
1003 9
1004 8
1004 8
1005 4
1005 4
1006
1006
1007 (interleaved: '2' would be missing if heap queue were higher depth first)
1007 (interleaved: '2' would be missing if heap queue were higher depth first)
1008
1008
1009 $ log 'reverse(ancestors(7+8, depth=2))'
1009 $ log 'reverse(ancestors(7+8, depth=2))'
1010 8
1010 8
1011 7
1011 7
1012 6
1012 6
1013 5
1013 5
1014 4
1014 4
1015 2
1015 2
1016
1016
1017 (walk example above by separate queries)
1017 (walk example above by separate queries)
1018
1018
1019 $ log 'reverse(ancestors(8, depth=2)) + reverse(ancestors(7, depth=2))'
1019 $ log 'reverse(ancestors(8, depth=2)) + reverse(ancestors(7, depth=2))'
1020 8
1020 8
1021 4
1021 4
1022 2
1022 2
1023 7
1023 7
1024 6
1024 6
1025 5
1025 5
1026
1026
1027 (walk 2nd and 3rd ancestors)
1027 (walk 2nd and 3rd ancestors)
1028
1028
1029 $ log 'reverse(ancestors(7, depth=3, startdepth=2))'
1029 $ log 'reverse(ancestors(7, depth=3, startdepth=2))'
1030 5
1030 5
1031 4
1031 4
1032 3
1032 3
1033 2
1033 2
1034
1034
1035 (interleaved: '4' would be missing if higher-depth ancestors weren't scanned)
1035 (interleaved: '4' would be missing if higher-depth ancestors weren't scanned)
1036
1036
1037 $ log 'reverse(ancestors(7+8, depth=2, startdepth=2))'
1037 $ log 'reverse(ancestors(7+8, depth=2, startdepth=2))'
1038 5
1038 5
1039 4
1039 4
1040 2
1040 2
1041
1041
1042 (note that 'ancestors(x, depth=y, startdepth=z)' does not identical to
1042 (note that 'ancestors(x, depth=y, startdepth=z)' does not identical to
1043 'ancestors(x, depth=y) - ancestors(x, depth=z-1)' because a node may have
1043 'ancestors(x, depth=y) - ancestors(x, depth=z-1)' because a node may have
1044 multiple depths)
1044 multiple depths)
1045
1045
1046 $ log 'reverse(ancestors(7+8, depth=2) - ancestors(7+8, depth=1))'
1046 $ log 'reverse(ancestors(7+8, depth=2) - ancestors(7+8, depth=1))'
1047 5
1047 5
1048 2
1048 2
1049
1049
1050 test bad arguments passed to ancestors()
1050 test bad arguments passed to ancestors()
1051
1051
1052 $ log 'ancestors(., depth=-1)'
1052 $ log 'ancestors(., depth=-1)'
1053 hg: parse error: negative depth
1053 hg: parse error: negative depth
1054 [255]
1054 [255]
1055 $ log 'ancestors(., depth=foo)'
1055 $ log 'ancestors(., depth=foo)'
1056 hg: parse error: ancestors expects an integer depth
1056 hg: parse error: ancestors expects an integer depth
1057 [255]
1057 [255]
1058
1058
1059 test descendants
1059 test descendants
1060
1060
1061 $ hg log -G -T '{rev}\n' --config experimental.graphshorten=True
1061 $ hg log -G -T '{rev}\n' --config experimental.graphshorten=True
1062 @ 9
1062 @ 9
1063 o 8
1063 o 8
1064 | o 7
1064 | o 7
1065 | o 6
1065 | o 6
1066 |/|
1066 |/|
1067 | o 5
1067 | o 5
1068 o | 4
1068 o | 4
1069 | o 3
1069 | o 3
1070 o | 2
1070 o | 2
1071 |/
1071 |/
1072 o 1
1072 o 1
1073 o 0
1073 o 0
1074
1074
1075 (null is ultimate root and has optimized path)
1075 (null is ultimate root and has optimized path)
1076
1076
1077 $ log 'null:4 & descendants(null)'
1077 $ log 'null:4 & descendants(null)'
1078 -1
1078 -1
1079 0
1079 0
1080 1
1080 1
1081 2
1081 2
1082 3
1082 3
1083 4
1083 4
1084
1084
1085 (including merge)
1085 (including merge)
1086
1086
1087 $ log ':8 & descendants(2)'
1087 $ log ':8 & descendants(2)'
1088 2
1088 2
1089 4
1089 4
1090 6
1090 6
1091 7
1091 7
1092 8
1092 8
1093
1093
1094 (multiple roots)
1094 (multiple roots)
1095
1095
1096 $ log ':8 & descendants(2+5)'
1096 $ log ':8 & descendants(2+5)'
1097 2
1097 2
1098 4
1098 4
1099 5
1099 5
1100 6
1100 6
1101 7
1101 7
1102 8
1102 8
1103
1103
1104 test descendants with depth limit
1104 test descendants with depth limit
1105
1105
1106 (depth=0 selects the node itself)
1106 (depth=0 selects the node itself)
1107
1107
1108 $ log 'descendants(0, depth=0)'
1108 $ log 'descendants(0, depth=0)'
1109 0
1109 0
1110 $ log 'null: & descendants(null, depth=0)'
1110 $ log 'null: & descendants(null, depth=0)'
1111 -1
1111 -1
1112
1112
1113 (p2 = null should be ignored)
1113 (p2 = null should be ignored)
1114
1114
1115 $ log 'null: & descendants(null, depth=2)'
1115 $ log 'null: & descendants(null, depth=2)'
1116 -1
1116 -1
1117 0
1117 0
1118 1
1118 1
1119
1119
1120 (multiple paths: depth(6) = (2, 3))
1120 (multiple paths: depth(6) = (2, 3))
1121
1121
1122 $ log 'descendants(1+3, depth=2)'
1122 $ log 'descendants(1+3, depth=2)'
1123 1
1123 1
1124 2
1124 2
1125 3
1125 3
1126 4
1126 4
1127 5
1127 5
1128 6
1128 6
1129
1129
1130 (multiple paths: depth(5) = (1, 2), depth(6) = (2, 3))
1130 (multiple paths: depth(5) = (1, 2), depth(6) = (2, 3))
1131
1131
1132 $ log 'descendants(3+1, depth=2, startdepth=2)'
1132 $ log 'descendants(3+1, depth=2, startdepth=2)'
1133 4
1133 4
1134 5
1134 5
1135 6
1135 6
1136
1136
1137 (multiple depths: depth(6) = (0, 2, 4), search for depth=2)
1137 (multiple depths: depth(6) = (0, 2, 4), search for depth=2)
1138
1138
1139 $ log 'descendants(0+3+6, depth=3, startdepth=1)'
1139 $ log 'descendants(0+3+6, depth=3, startdepth=1)'
1140 1
1140 1
1141 2
1141 2
1142 3
1142 3
1143 4
1143 4
1144 5
1144 5
1145 6
1145 6
1146 7
1146 7
1147
1147
1148 (multiple depths: depth(6) = (0, 4), no match)
1148 (multiple depths: depth(6) = (0, 4), no match)
1149
1149
1150 $ log 'descendants(0+6, depth=3, startdepth=1)'
1150 $ log 'descendants(0+6, depth=3, startdepth=1)'
1151 1
1151 1
1152 2
1152 2
1153 3
1153 3
1154 4
1154 4
1155 5
1155 5
1156 7
1156 7
1157
1157
1158 test ancestors/descendants relation subscript:
1158 test ancestors/descendants relation subscript:
1159
1159
1160 $ log 'tip#generations[0]'
1160 $ log 'tip#generations[0]'
1161 9
1161 9
1162 $ log '.#generations[-1]'
1162 $ log '.#generations[-1]'
1163 8
1163 8
1164 $ log '.#g[(-1)]'
1164 $ log '.#g[(-1)]'
1165 8
1165 8
1166
1166
1167 $ hg debugrevspec -p parsed 'roots(:)#g[2]'
1167 $ hg debugrevspec -p parsed 'roots(:)#g[2]'
1168 * parsed:
1168 * parsed:
1169 (relsubscript
1169 (relsubscript
1170 (func
1170 (func
1171 (symbol 'roots')
1171 (symbol 'roots')
1172 (rangeall
1172 (rangeall
1173 None))
1173 None))
1174 (symbol 'g')
1174 (symbol 'g')
1175 (symbol '2'))
1175 (symbol '2'))
1176 2
1176 2
1177 3
1177 3
1178
1178
1179 test author
1179 test author
1180
1180
1181 $ log 'author(bob)'
1181 $ log 'author(bob)'
1182 2
1182 2
1183 $ log 'author("re:bob|test")'
1183 $ log 'author("re:bob|test")'
1184 0
1184 0
1185 1
1185 1
1186 2
1186 2
1187 3
1187 3
1188 4
1188 4
1189 5
1189 5
1190 6
1190 6
1191 7
1191 7
1192 8
1192 8
1193 9
1193 9
1194 $ log 'author(r"re:\S")'
1194 $ log 'author(r"re:\S")'
1195 0
1195 0
1196 1
1196 1
1197 2
1197 2
1198 3
1198 3
1199 4
1199 4
1200 5
1200 5
1201 6
1201 6
1202 7
1202 7
1203 8
1203 8
1204 9
1204 9
1205 $ log 'branch(Γ©)'
1205 $ log 'branch(Γ©)'
1206 8
1206 8
1207 9
1207 9
1208 $ log 'branch(a)'
1208 $ log 'branch(a)'
1209 0
1209 0
1210 $ hg log -r 'branch("re:a")' --template '{rev} {branch}\n'
1210 $ hg log -r 'branch("re:a")' --template '{rev} {branch}\n'
1211 0 a
1211 0 a
1212 2 a-b-c-
1212 2 a-b-c-
1213 3 +a+b+c+
1213 3 +a+b+c+
1214 4 -a-b-c-
1214 4 -a-b-c-
1215 5 !a/b/c/
1215 5 !a/b/c/
1216 6 _a_b_c_
1216 6 _a_b_c_
1217 7 .a.b.c.
1217 7 .a.b.c.
1218 $ log 'children(ancestor(4,5))'
1218 $ log 'children(ancestor(4,5))'
1219 2
1219 2
1220 3
1220 3
1221
1221
1222 $ log 'children(4)'
1222 $ log 'children(4)'
1223 6
1223 6
1224 8
1224 8
1225 $ log 'children(null)'
1225 $ log 'children(null)'
1226 0
1226 0
1227
1227
1228 $ log 'closed()'
1228 $ log 'closed()'
1229 $ log 'contains(a)'
1229 $ log 'contains(a)'
1230 0
1230 0
1231 1
1231 1
1232 3
1232 3
1233 5
1233 5
1234 $ log 'contains("../repo/a")'
1234 $ log 'contains("../repo/a")'
1235 0
1235 0
1236 1
1236 1
1237 3
1237 3
1238 5
1238 5
1239 $ log 'desc(B)'
1239 $ log 'desc(B)'
1240 5
1240 5
1241 $ hg log -r 'desc(r"re:S?u")' --template "{rev} {desc|firstline}\n"
1241 $ hg log -r 'desc(r"re:S?u")' --template "{rev} {desc|firstline}\n"
1242 5 5 bug
1242 5 5 bug
1243 6 6 issue619
1243 6 6 issue619
1244 $ log 'descendants(2 or 3)'
1244 $ log 'descendants(2 or 3)'
1245 2
1245 2
1246 3
1246 3
1247 4
1247 4
1248 5
1248 5
1249 6
1249 6
1250 7
1250 7
1251 8
1251 8
1252 9
1252 9
1253 $ log 'file("b*")'
1253 $ log 'file("b*")'
1254 1
1254 1
1255 4
1255 4
1256 $ log 'filelog("b")'
1256 $ log 'filelog("b")'
1257 1
1257 1
1258 4
1258 4
1259 $ log 'filelog("../repo/b")'
1259 $ log 'filelog("../repo/b")'
1260 1
1260 1
1261 4
1261 4
1262 $ log 'follow()'
1262 $ log 'follow()'
1263 0
1263 0
1264 1
1264 1
1265 2
1265 2
1266 4
1266 4
1267 8
1267 8
1268 9
1268 9
1269 $ log 'grep("issue\d+")'
1269 $ log 'grep("issue\d+")'
1270 6
1270 6
1271 $ try 'grep("(")' # invalid regular expression
1271 $ try 'grep("(")' # invalid regular expression
1272 (func
1272 (func
1273 (symbol 'grep')
1273 (symbol 'grep')
1274 (string '('))
1274 (string '('))
1275 hg: parse error: invalid match pattern: unbalanced parenthesis
1275 hg: parse error: invalid match pattern: unbalanced parenthesis
1276 [255]
1276 [255]
1277 $ try 'grep("\bissue\d+")'
1277 $ try 'grep("\bissue\d+")'
1278 (func
1278 (func
1279 (symbol 'grep')
1279 (symbol 'grep')
1280 (string '\x08issue\\d+'))
1280 (string '\x08issue\\d+'))
1281 * set:
1281 * set:
1282 <filteredset
1282 <filteredset
1283 <fullreposet+ 0:10>,
1283 <fullreposet+ 0:10>,
1284 <grep '\x08issue\\d+'>>
1284 <grep '\x08issue\\d+'>>
1285 $ try 'grep(r"\bissue\d+")'
1285 $ try 'grep(r"\bissue\d+")'
1286 (func
1286 (func
1287 (symbol 'grep')
1287 (symbol 'grep')
1288 (string '\\bissue\\d+'))
1288 (string '\\bissue\\d+'))
1289 * set:
1289 * set:
1290 <filteredset
1290 <filteredset
1291 <fullreposet+ 0:10>,
1291 <fullreposet+ 0:10>,
1292 <grep '\\bissue\\d+'>>
1292 <grep '\\bissue\\d+'>>
1293 6
1293 6
1294 $ try 'grep(r"\")'
1294 $ try 'grep(r"\")'
1295 hg: parse error at 7: unterminated string
1295 hg: parse error at 7: unterminated string
1296 [255]
1296 [255]
1297 $ log 'head()'
1297 $ log 'head()'
1298 0
1298 0
1299 1
1299 1
1300 2
1300 2
1301 3
1301 3
1302 4
1302 4
1303 5
1303 5
1304 6
1304 6
1305 7
1305 7
1306 9
1306 9
1307 $ log 'heads(6::)'
1307 $ log 'heads(6::)'
1308 7
1308 7
1309 $ log 'keyword(issue)'
1309 $ log 'keyword(issue)'
1310 6
1310 6
1311 $ log 'keyword("test a")'
1311 $ log 'keyword("test a")'
1312
1312
1313 Test first (=limit) and last
1313 Test first (=limit) and last
1314
1314
1315 $ log 'limit(head(), 1)'
1315 $ log 'limit(head(), 1)'
1316 0
1316 0
1317 $ log 'limit(author("re:bob|test"), 3, 5)'
1317 $ log 'limit(author("re:bob|test"), 3, 5)'
1318 5
1318 5
1319 6
1319 6
1320 7
1320 7
1321 $ log 'limit(author("re:bob|test"), offset=6)'
1321 $ log 'limit(author("re:bob|test"), offset=6)'
1322 6
1322 6
1323 $ log 'limit(author("re:bob|test"), offset=10)'
1323 $ log 'limit(author("re:bob|test"), offset=10)'
1324 $ log 'limit(all(), 1, -1)'
1324 $ log 'limit(all(), 1, -1)'
1325 hg: parse error: negative offset
1325 hg: parse error: negative offset
1326 [255]
1326 [255]
1327 $ log 'limit(all(), -1)'
1327 $ log 'limit(all(), -1)'
1328 hg: parse error: negative number to select
1328 hg: parse error: negative number to select
1329 [255]
1329 [255]
1330 $ log 'limit(all(), 0)'
1330 $ log 'limit(all(), 0)'
1331
1331
1332 $ log 'last(all(), -1)'
1332 $ log 'last(all(), -1)'
1333 hg: parse error: negative number to select
1333 hg: parse error: negative number to select
1334 [255]
1334 [255]
1335 $ log 'last(all(), 0)'
1335 $ log 'last(all(), 0)'
1336 $ log 'last(all(), 1)'
1336 $ log 'last(all(), 1)'
1337 9
1337 9
1338 $ log 'last(all(), 2)'
1338 $ log 'last(all(), 2)'
1339 8
1339 8
1340 9
1340 9
1341
1341
1342 Test smartset.slice() by first/last()
1342 Test smartset.slice() by first/last()
1343
1343
1344 (using unoptimized set, filteredset as example)
1344 (using unoptimized set, filteredset as example)
1345
1345
1346 $ hg debugrevspec --no-show-revs -s '0:7 & branch("re:")'
1346 $ hg debugrevspec --no-show-revs -s '0:7 & branch("re:")'
1347 * set:
1347 * set:
1348 <filteredset
1348 <filteredset
1349 <spanset+ 0:8>,
1349 <spanset+ 0:8>,
1350 <branch 're:'>>
1350 <branch 're:'>>
1351 $ log 'limit(0:7 & branch("re:"), 3, 4)'
1351 $ log 'limit(0:7 & branch("re:"), 3, 4)'
1352 4
1352 4
1353 5
1353 5
1354 6
1354 6
1355 $ log 'limit(7:0 & branch("re:"), 3, 4)'
1355 $ log 'limit(7:0 & branch("re:"), 3, 4)'
1356 3
1356 3
1357 2
1357 2
1358 1
1358 1
1359 $ log 'last(0:7 & branch("re:"), 2)'
1359 $ log 'last(0:7 & branch("re:"), 2)'
1360 6
1360 6
1361 7
1361 7
1362
1362
1363 (using baseset)
1363 (using baseset)
1364
1364
1365 $ hg debugrevspec --no-show-revs -s 0+1+2+3+4+5+6+7
1365 $ hg debugrevspec --no-show-revs -s 0+1+2+3+4+5+6+7
1366 * set:
1366 * set:
1367 <baseset [0, 1, 2, 3, 4, 5, 6, 7]>
1367 <baseset [0, 1, 2, 3, 4, 5, 6, 7]>
1368 $ hg debugrevspec --no-show-revs -s 0::7
1368 $ hg debugrevspec --no-show-revs -s 0::7
1369 * set:
1369 * set:
1370 <baseset+ [0, 1, 2, 3, 4, 5, 6, 7]>
1370 <baseset+ [0, 1, 2, 3, 4, 5, 6, 7]>
1371 $ log 'limit(0+1+2+3+4+5+6+7, 3, 4)'
1371 $ log 'limit(0+1+2+3+4+5+6+7, 3, 4)'
1372 4
1372 4
1373 5
1373 5
1374 6
1374 6
1375 $ log 'limit(sort(0::7, rev), 3, 4)'
1375 $ log 'limit(sort(0::7, rev), 3, 4)'
1376 4
1376 4
1377 5
1377 5
1378 6
1378 6
1379 $ log 'limit(sort(0::7, -rev), 3, 4)'
1379 $ log 'limit(sort(0::7, -rev), 3, 4)'
1380 3
1380 3
1381 2
1381 2
1382 1
1382 1
1383 $ log 'last(sort(0::7, rev), 2)'
1383 $ log 'last(sort(0::7, rev), 2)'
1384 6
1384 6
1385 7
1385 7
1386 $ hg debugrevspec -s 'limit(sort(0::7, rev), 3, 6)'
1386 $ hg debugrevspec -s 'limit(sort(0::7, rev), 3, 6)'
1387 * set:
1387 * set:
1388 <baseset+ [6, 7]>
1388 <baseset+ [6, 7]>
1389 6
1389 6
1390 7
1390 7
1391 $ hg debugrevspec -s 'limit(sort(0::7, rev), 3, 9)'
1391 $ hg debugrevspec -s 'limit(sort(0::7, rev), 3, 9)'
1392 * set:
1392 * set:
1393 <baseset+ []>
1393 <baseset+ []>
1394 $ hg debugrevspec -s 'limit(sort(0::7, -rev), 3, 6)'
1394 $ hg debugrevspec -s 'limit(sort(0::7, -rev), 3, 6)'
1395 * set:
1395 * set:
1396 <baseset- [0, 1]>
1396 <baseset- [0, 1]>
1397 1
1397 1
1398 0
1398 0
1399 $ hg debugrevspec -s 'limit(sort(0::7, -rev), 3, 9)'
1399 $ hg debugrevspec -s 'limit(sort(0::7, -rev), 3, 9)'
1400 * set:
1400 * set:
1401 <baseset- []>
1401 <baseset- []>
1402 $ hg debugrevspec -s 'limit(0::7, 0)'
1402 $ hg debugrevspec -s 'limit(0::7, 0)'
1403 * set:
1403 * set:
1404 <baseset+ []>
1404 <baseset+ []>
1405
1405
1406 (using spanset)
1406 (using spanset)
1407
1407
1408 $ hg debugrevspec --no-show-revs -s 0:7
1408 $ hg debugrevspec --no-show-revs -s 0:7
1409 * set:
1409 * set:
1410 <spanset+ 0:8>
1410 <spanset+ 0:8>
1411 $ log 'limit(0:7, 3, 4)'
1411 $ log 'limit(0:7, 3, 4)'
1412 4
1412 4
1413 5
1413 5
1414 6
1414 6
1415 $ log 'limit(7:0, 3, 4)'
1415 $ log 'limit(7:0, 3, 4)'
1416 3
1416 3
1417 2
1417 2
1418 1
1418 1
1419 $ log 'limit(0:7, 3, 6)'
1419 $ log 'limit(0:7, 3, 6)'
1420 6
1420 6
1421 7
1421 7
1422 $ log 'limit(7:0, 3, 6)'
1422 $ log 'limit(7:0, 3, 6)'
1423 1
1423 1
1424 0
1424 0
1425 $ log 'last(0:7, 2)'
1425 $ log 'last(0:7, 2)'
1426 6
1426 6
1427 7
1427 7
1428 $ hg debugrevspec -s 'limit(0:7, 3, 6)'
1428 $ hg debugrevspec -s 'limit(0:7, 3, 6)'
1429 * set:
1429 * set:
1430 <spanset+ 6:8>
1430 <spanset+ 6:8>
1431 6
1431 6
1432 7
1432 7
1433 $ hg debugrevspec -s 'limit(0:7, 3, 9)'
1433 $ hg debugrevspec -s 'limit(0:7, 3, 9)'
1434 * set:
1434 * set:
1435 <spanset+ 8:8>
1435 <spanset+ 8:8>
1436 $ hg debugrevspec -s 'limit(7:0, 3, 6)'
1436 $ hg debugrevspec -s 'limit(7:0, 3, 6)'
1437 * set:
1437 * set:
1438 <spanset- 0:2>
1438 <spanset- 0:2>
1439 1
1439 1
1440 0
1440 0
1441 $ hg debugrevspec -s 'limit(7:0, 3, 9)'
1441 $ hg debugrevspec -s 'limit(7:0, 3, 9)'
1442 * set:
1442 * set:
1443 <spanset- 0:0>
1443 <spanset- 0:0>
1444 $ hg debugrevspec -s 'limit(0:7, 0)'
1444 $ hg debugrevspec -s 'limit(0:7, 0)'
1445 * set:
1445 * set:
1446 <spanset+ 0:0>
1446 <spanset+ 0:0>
1447
1447
1448 Test order of first/last revisions
1448 Test order of first/last revisions
1449
1449
1450 $ hg debugrevspec -s 'first(4:0, 3) & 3:'
1450 $ hg debugrevspec -s 'first(4:0, 3) & 3:'
1451 * set:
1451 * set:
1452 <filteredset
1452 <filteredset
1453 <spanset- 2:5>,
1453 <spanset- 2:5>,
1454 <spanset+ 3:10>>
1454 <spanset+ 3:10>>
1455 4
1455 4
1456 3
1456 3
1457
1457
1458 $ hg debugrevspec -s '3: & first(4:0, 3)'
1458 $ hg debugrevspec -s '3: & first(4:0, 3)'
1459 * set:
1459 * set:
1460 <filteredset
1460 <filteredset
1461 <spanset+ 3:10>,
1461 <spanset+ 3:10>,
1462 <spanset- 2:5>>
1462 <spanset- 2:5>>
1463 3
1463 3
1464 4
1464 4
1465
1465
1466 $ hg debugrevspec -s 'last(4:0, 3) & :1'
1466 $ hg debugrevspec -s 'last(4:0, 3) & :1'
1467 * set:
1467 * set:
1468 <filteredset
1468 <filteredset
1469 <spanset- 0:3>,
1469 <spanset- 0:3>,
1470 <spanset+ 0:2>>
1470 <spanset+ 0:2>>
1471 1
1471 1
1472 0
1472 0
1473
1473
1474 $ hg debugrevspec -s ':1 & last(4:0, 3)'
1474 $ hg debugrevspec -s ':1 & last(4:0, 3)'
1475 * set:
1475 * set:
1476 <filteredset
1476 <filteredset
1477 <spanset+ 0:2>,
1477 <spanset+ 0:2>,
1478 <spanset+ 0:3>>
1478 <spanset+ 0:3>>
1479 0
1479 0
1480 1
1480 1
1481
1481
1482 Test scmutil.revsingle() should return the last revision
1482 Test scmutil.revsingle() should return the last revision
1483
1483
1484 $ hg debugrevspec -s 'last(0::)'
1484 $ hg debugrevspec -s 'last(0::)'
1485 * set:
1485 * set:
1486 <baseset slice=0:1
1486 <baseset slice=0:1
1487 <generatorset->>
1487 <generatorsetasc->>
1488 9
1488 9
1489 $ hg identify -r '0::' --num
1489 $ hg identify -r '0::' --num
1490 9
1490 9
1491
1491
1492 Test matching
1492 Test matching
1493
1493
1494 $ log 'matching(6)'
1494 $ log 'matching(6)'
1495 6
1495 6
1496 $ log 'matching(6:7, "phase parents user date branch summary files description substate")'
1496 $ log 'matching(6:7, "phase parents user date branch summary files description substate")'
1497 6
1497 6
1498 7
1498 7
1499
1499
1500 Testing min and max
1500 Testing min and max
1501
1501
1502 max: simple
1502 max: simple
1503
1503
1504 $ log 'max(contains(a))'
1504 $ log 'max(contains(a))'
1505 5
1505 5
1506
1506
1507 max: simple on unordered set)
1507 max: simple on unordered set)
1508
1508
1509 $ log 'max((4+0+2+5+7) and contains(a))'
1509 $ log 'max((4+0+2+5+7) and contains(a))'
1510 5
1510 5
1511
1511
1512 max: no result
1512 max: no result
1513
1513
1514 $ log 'max(contains(stringthatdoesnotappearanywhere))'
1514 $ log 'max(contains(stringthatdoesnotappearanywhere))'
1515
1515
1516 max: no result on unordered set
1516 max: no result on unordered set
1517
1517
1518 $ log 'max((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1518 $ log 'max((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1519
1519
1520 min: simple
1520 min: simple
1521
1521
1522 $ log 'min(contains(a))'
1522 $ log 'min(contains(a))'
1523 0
1523 0
1524
1524
1525 min: simple on unordered set
1525 min: simple on unordered set
1526
1526
1527 $ log 'min((4+0+2+5+7) and contains(a))'
1527 $ log 'min((4+0+2+5+7) and contains(a))'
1528 0
1528 0
1529
1529
1530 min: empty
1530 min: empty
1531
1531
1532 $ log 'min(contains(stringthatdoesnotappearanywhere))'
1532 $ log 'min(contains(stringthatdoesnotappearanywhere))'
1533
1533
1534 min: empty on unordered set
1534 min: empty on unordered set
1535
1535
1536 $ log 'min((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1536 $ log 'min((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
1537
1537
1538
1538
1539 $ log 'merge()'
1539 $ log 'merge()'
1540 6
1540 6
1541 $ log 'branchpoint()'
1541 $ log 'branchpoint()'
1542 1
1542 1
1543 4
1543 4
1544 $ log 'modifies(b)'
1544 $ log 'modifies(b)'
1545 4
1545 4
1546 $ log 'modifies("path:b")'
1546 $ log 'modifies("path:b")'
1547 4
1547 4
1548 $ log 'modifies("*")'
1548 $ log 'modifies("*")'
1549 4
1549 4
1550 6
1550 6
1551 $ log 'modifies("set:modified()")'
1551 $ log 'modifies("set:modified()")'
1552 4
1552 4
1553 $ log 'id(5)'
1553 $ log 'id(5)'
1554 2
1554 2
1555 $ log 'only(9)'
1555 $ log 'only(9)'
1556 8
1556 8
1557 9
1557 9
1558 $ log 'only(8)'
1558 $ log 'only(8)'
1559 8
1559 8
1560 $ log 'only(9, 5)'
1560 $ log 'only(9, 5)'
1561 2
1561 2
1562 4
1562 4
1563 8
1563 8
1564 9
1564 9
1565 $ log 'only(7 + 9, 5 + 2)'
1565 $ log 'only(7 + 9, 5 + 2)'
1566 4
1566 4
1567 6
1567 6
1568 7
1568 7
1569 8
1569 8
1570 9
1570 9
1571
1571
1572 Test empty set input
1572 Test empty set input
1573 $ log 'only(p2())'
1573 $ log 'only(p2())'
1574 $ log 'only(p1(), p2())'
1574 $ log 'only(p1(), p2())'
1575 0
1575 0
1576 1
1576 1
1577 2
1577 2
1578 4
1578 4
1579 8
1579 8
1580 9
1580 9
1581
1581
1582 Test '%' operator
1582 Test '%' operator
1583
1583
1584 $ log '9%'
1584 $ log '9%'
1585 8
1585 8
1586 9
1586 9
1587 $ log '9%5'
1587 $ log '9%5'
1588 2
1588 2
1589 4
1589 4
1590 8
1590 8
1591 9
1591 9
1592 $ log '(7 + 9)%(5 + 2)'
1592 $ log '(7 + 9)%(5 + 2)'
1593 4
1593 4
1594 6
1594 6
1595 7
1595 7
1596 8
1596 8
1597 9
1597 9
1598
1598
1599 Test operand of '%' is optimized recursively (issue4670)
1599 Test operand of '%' is optimized recursively (issue4670)
1600
1600
1601 $ try --optimize '8:9-8%'
1601 $ try --optimize '8:9-8%'
1602 (onlypost
1602 (onlypost
1603 (minus
1603 (minus
1604 (range
1604 (range
1605 (symbol '8')
1605 (symbol '8')
1606 (symbol '9'))
1606 (symbol '9'))
1607 (symbol '8')))
1607 (symbol '8')))
1608 * optimized:
1608 * optimized:
1609 (func
1609 (func
1610 (symbol 'only')
1610 (symbol 'only')
1611 (difference
1611 (difference
1612 (range
1612 (range
1613 (symbol '8')
1613 (symbol '8')
1614 (symbol '9'))
1614 (symbol '9'))
1615 (symbol '8')))
1615 (symbol '8')))
1616 * set:
1616 * set:
1617 <baseset+ [8, 9]>
1617 <baseset+ [8, 9]>
1618 8
1618 8
1619 9
1619 9
1620 $ try --optimize '(9)%(5)'
1620 $ try --optimize '(9)%(5)'
1621 (only
1621 (only
1622 (group
1622 (group
1623 (symbol '9'))
1623 (symbol '9'))
1624 (group
1624 (group
1625 (symbol '5')))
1625 (symbol '5')))
1626 * optimized:
1626 * optimized:
1627 (func
1627 (func
1628 (symbol 'only')
1628 (symbol 'only')
1629 (list
1629 (list
1630 (symbol '9')
1630 (symbol '9')
1631 (symbol '5')))
1631 (symbol '5')))
1632 * set:
1632 * set:
1633 <baseset+ [2, 4, 8, 9]>
1633 <baseset+ [2, 4, 8, 9]>
1634 2
1634 2
1635 4
1635 4
1636 8
1636 8
1637 9
1637 9
1638
1638
1639 Test the order of operations
1639 Test the order of operations
1640
1640
1641 $ log '7 + 9%5 + 2'
1641 $ log '7 + 9%5 + 2'
1642 7
1642 7
1643 2
1643 2
1644 4
1644 4
1645 8
1645 8
1646 9
1646 9
1647
1647
1648 Test explicit numeric revision
1648 Test explicit numeric revision
1649 $ log 'rev(-2)'
1649 $ log 'rev(-2)'
1650 $ log 'rev(-1)'
1650 $ log 'rev(-1)'
1651 -1
1651 -1
1652 $ log 'rev(0)'
1652 $ log 'rev(0)'
1653 0
1653 0
1654 $ log 'rev(9)'
1654 $ log 'rev(9)'
1655 9
1655 9
1656 $ log 'rev(10)'
1656 $ log 'rev(10)'
1657 $ log 'rev(tip)'
1657 $ log 'rev(tip)'
1658 hg: parse error: rev expects a number
1658 hg: parse error: rev expects a number
1659 [255]
1659 [255]
1660
1660
1661 Test hexadecimal revision
1661 Test hexadecimal revision
1662 $ log 'id(2)'
1662 $ log 'id(2)'
1663 abort: 00changelog.i@2: ambiguous identifier!
1663 abort: 00changelog.i@2: ambiguous identifier!
1664 [255]
1664 [255]
1665 $ log 'id(23268)'
1665 $ log 'id(23268)'
1666 4
1666 4
1667 $ log 'id(2785f51eece)'
1667 $ log 'id(2785f51eece)'
1668 0
1668 0
1669 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532c)'
1669 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532c)'
1670 8
1670 8
1671 $ log 'id(d5d0dcbdc4a)'
1671 $ log 'id(d5d0dcbdc4a)'
1672 $ log 'id(d5d0dcbdc4w)'
1672 $ log 'id(d5d0dcbdc4w)'
1673 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532d)'
1673 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532d)'
1674 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532q)'
1674 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532q)'
1675 $ log 'id(1.0)'
1675 $ log 'id(1.0)'
1676 $ log 'id(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)'
1676 $ log 'id(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)'
1677
1677
1678 Test null revision
1678 Test null revision
1679 $ log '(null)'
1679 $ log '(null)'
1680 -1
1680 -1
1681 $ log '(null:0)'
1681 $ log '(null:0)'
1682 -1
1682 -1
1683 0
1683 0
1684 $ log '(0:null)'
1684 $ log '(0:null)'
1685 0
1685 0
1686 -1
1686 -1
1687 $ log 'null::0'
1687 $ log 'null::0'
1688 -1
1688 -1
1689 0
1689 0
1690 $ log 'null:tip - 0:'
1690 $ log 'null:tip - 0:'
1691 -1
1691 -1
1692 $ log 'null: and null::' | head -1
1692 $ log 'null: and null::' | head -1
1693 -1
1693 -1
1694 $ log 'null: or 0:' | head -2
1694 $ log 'null: or 0:' | head -2
1695 -1
1695 -1
1696 0
1696 0
1697 $ log 'ancestors(null)'
1697 $ log 'ancestors(null)'
1698 -1
1698 -1
1699 $ log 'reverse(null:)' | tail -2
1699 $ log 'reverse(null:)' | tail -2
1700 0
1700 0
1701 -1
1701 -1
1702 $ log 'first(null:)'
1702 $ log 'first(null:)'
1703 -1
1703 -1
1704 $ log 'min(null:)'
1704 $ log 'min(null:)'
1705 BROKEN: should be '-1'
1705 BROKEN: should be '-1'
1706 $ log 'tip:null and all()' | tail -2
1706 $ log 'tip:null and all()' | tail -2
1707 1
1707 1
1708 0
1708 0
1709
1709
1710 Test working-directory revision
1710 Test working-directory revision
1711 $ hg debugrevspec 'wdir()'
1711 $ hg debugrevspec 'wdir()'
1712 2147483647
1712 2147483647
1713 $ hg debugrevspec 'wdir()^'
1713 $ hg debugrevspec 'wdir()^'
1714 9
1714 9
1715 $ hg up 7
1715 $ hg up 7
1716 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1716 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1717 $ hg debugrevspec 'wdir()^'
1717 $ hg debugrevspec 'wdir()^'
1718 7
1718 7
1719 $ hg debugrevspec 'wdir()^0'
1719 $ hg debugrevspec 'wdir()^0'
1720 2147483647
1720 2147483647
1721 $ hg debugrevspec 'wdir()~3'
1721 $ hg debugrevspec 'wdir()~3'
1722 5
1722 5
1723 $ hg debugrevspec 'ancestors(wdir())'
1723 $ hg debugrevspec 'ancestors(wdir())'
1724 0
1724 0
1725 1
1725 1
1726 2
1726 2
1727 3
1727 3
1728 4
1728 4
1729 5
1729 5
1730 6
1730 6
1731 7
1731 7
1732 2147483647
1732 2147483647
1733 $ hg debugrevspec 'wdir()~0'
1733 $ hg debugrevspec 'wdir()~0'
1734 2147483647
1734 2147483647
1735 $ hg debugrevspec 'p1(wdir())'
1735 $ hg debugrevspec 'p1(wdir())'
1736 7
1736 7
1737 $ hg debugrevspec 'p2(wdir())'
1737 $ hg debugrevspec 'p2(wdir())'
1738 $ hg debugrevspec 'parents(wdir())'
1738 $ hg debugrevspec 'parents(wdir())'
1739 7
1739 7
1740 $ hg debugrevspec 'wdir()^1'
1740 $ hg debugrevspec 'wdir()^1'
1741 7
1741 7
1742 $ hg debugrevspec 'wdir()^2'
1742 $ hg debugrevspec 'wdir()^2'
1743 $ hg debugrevspec 'wdir()^3'
1743 $ hg debugrevspec 'wdir()^3'
1744 hg: parse error: ^ expects a number 0, 1, or 2
1744 hg: parse error: ^ expects a number 0, 1, or 2
1745 [255]
1745 [255]
1746 For tests consistency
1746 For tests consistency
1747 $ hg up 9
1747 $ hg up 9
1748 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1748 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1749 $ hg debugrevspec 'tip or wdir()'
1749 $ hg debugrevspec 'tip or wdir()'
1750 9
1750 9
1751 2147483647
1751 2147483647
1752 $ hg debugrevspec '0:tip and wdir()'
1752 $ hg debugrevspec '0:tip and wdir()'
1753 $ log '0:wdir()' | tail -3
1753 $ log '0:wdir()' | tail -3
1754 8
1754 8
1755 9
1755 9
1756 2147483647
1756 2147483647
1757 $ log 'wdir():0' | head -3
1757 $ log 'wdir():0' | head -3
1758 2147483647
1758 2147483647
1759 9
1759 9
1760 8
1760 8
1761 $ log 'wdir():wdir()'
1761 $ log 'wdir():wdir()'
1762 2147483647
1762 2147483647
1763 $ log '(all() + wdir()) & min(. + wdir())'
1763 $ log '(all() + wdir()) & min(. + wdir())'
1764 9
1764 9
1765 $ log '(all() + wdir()) & max(. + wdir())'
1765 $ log '(all() + wdir()) & max(. + wdir())'
1766 2147483647
1766 2147483647
1767 $ log 'first(wdir() + .)'
1767 $ log 'first(wdir() + .)'
1768 2147483647
1768 2147483647
1769 $ log 'last(. + wdir())'
1769 $ log 'last(. + wdir())'
1770 2147483647
1770 2147483647
1771
1771
1772 Test working-directory integer revision and node id
1772 Test working-directory integer revision and node id
1773 (BUG: '0:wdir()' is still needed to populate wdir revision)
1773 (BUG: '0:wdir()' is still needed to populate wdir revision)
1774
1774
1775 $ hg debugrevspec '0:wdir() & 2147483647'
1775 $ hg debugrevspec '0:wdir() & 2147483647'
1776 2147483647
1776 2147483647
1777 $ hg debugrevspec '0:wdir() & rev(2147483647)'
1777 $ hg debugrevspec '0:wdir() & rev(2147483647)'
1778 2147483647
1778 2147483647
1779 $ hg debugrevspec '0:wdir() & ffffffffffffffffffffffffffffffffffffffff'
1779 $ hg debugrevspec '0:wdir() & ffffffffffffffffffffffffffffffffffffffff'
1780 2147483647
1780 2147483647
1781 $ hg debugrevspec '0:wdir() & ffffffffffff'
1781 $ hg debugrevspec '0:wdir() & ffffffffffff'
1782 2147483647
1782 2147483647
1783 $ hg debugrevspec '0:wdir() & id(ffffffffffffffffffffffffffffffffffffffff)'
1783 $ hg debugrevspec '0:wdir() & id(ffffffffffffffffffffffffffffffffffffffff)'
1784 2147483647
1784 2147483647
1785 $ hg debugrevspec '0:wdir() & id(ffffffffffff)'
1785 $ hg debugrevspec '0:wdir() & id(ffffffffffff)'
1786 2147483647
1786 2147483647
1787
1787
1788 $ cd ..
1788 $ cd ..
1789
1789
1790 Test short 'ff...' hash collision
1790 Test short 'ff...' hash collision
1791 (BUG: '0:wdir()' is still needed to populate wdir revision)
1791 (BUG: '0:wdir()' is still needed to populate wdir revision)
1792
1792
1793 $ hg init wdir-hashcollision
1793 $ hg init wdir-hashcollision
1794 $ cd wdir-hashcollision
1794 $ cd wdir-hashcollision
1795 $ cat <<EOF >> .hg/hgrc
1795 $ cat <<EOF >> .hg/hgrc
1796 > [experimental]
1796 > [experimental]
1797 > evolution.createmarkers=True
1797 > evolution.createmarkers=True
1798 > EOF
1798 > EOF
1799 $ echo 0 > a
1799 $ echo 0 > a
1800 $ hg ci -qAm 0
1800 $ hg ci -qAm 0
1801 $ for i in 2463 2961 6726 78127; do
1801 $ for i in 2463 2961 6726 78127; do
1802 > hg up -q 0
1802 > hg up -q 0
1803 > echo $i > a
1803 > echo $i > a
1804 > hg ci -qm $i
1804 > hg ci -qm $i
1805 > done
1805 > done
1806 $ hg up -q null
1806 $ hg up -q null
1807 $ hg log -r '0:wdir()' -T '{rev}:{node} {shortest(node, 3)}\n'
1807 $ hg log -r '0:wdir()' -T '{rev}:{node} {shortest(node, 3)}\n'
1808 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a b4e
1808 0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a b4e
1809 1:fffbae3886c8fbb2114296380d276fd37715d571 fffba
1809 1:fffbae3886c8fbb2114296380d276fd37715d571 fffba
1810 2:fffb6093b00943f91034b9bdad069402c834e572 fffb6
1810 2:fffb6093b00943f91034b9bdad069402c834e572 fffb6
1811 3:fff48a9b9de34a4d64120c29548214c67980ade3 fff4
1811 3:fff48a9b9de34a4d64120c29548214c67980ade3 fff4
1812 4:ffff85cff0ff78504fcdc3c0bc10de0c65379249 ffff8
1812 4:ffff85cff0ff78504fcdc3c0bc10de0c65379249 ffff8
1813 2147483647:ffffffffffffffffffffffffffffffffffffffff fffff
1813 2147483647:ffffffffffffffffffffffffffffffffffffffff fffff
1814 $ hg debugobsolete fffbae3886c8fbb2114296380d276fd37715d571
1814 $ hg debugobsolete fffbae3886c8fbb2114296380d276fd37715d571
1815 obsoleted 1 changesets
1815 obsoleted 1 changesets
1816
1816
1817 $ hg debugrevspec '0:wdir() & fff'
1817 $ hg debugrevspec '0:wdir() & fff'
1818 abort: 00changelog.i@fff: ambiguous identifier!
1818 abort: 00changelog.i@fff: ambiguous identifier!
1819 [255]
1819 [255]
1820 $ hg debugrevspec '0:wdir() & ffff'
1820 $ hg debugrevspec '0:wdir() & ffff'
1821 abort: 00changelog.i@ffff: ambiguous identifier!
1821 abort: 00changelog.i@ffff: ambiguous identifier!
1822 [255]
1822 [255]
1823 $ hg debugrevspec '0:wdir() & fffb'
1823 $ hg debugrevspec '0:wdir() & fffb'
1824 abort: 00changelog.i@fffb: ambiguous identifier!
1824 abort: 00changelog.i@fffb: ambiguous identifier!
1825 [255]
1825 [255]
1826 BROKEN should be '2' (node lookup uses unfiltered repo since dc25ed84bee8)
1826 BROKEN should be '2' (node lookup uses unfiltered repo since dc25ed84bee8)
1827 $ hg debugrevspec '0:wdir() & id(fffb)'
1827 $ hg debugrevspec '0:wdir() & id(fffb)'
1828 2
1828 2
1829 $ hg debugrevspec '0:wdir() & ffff8'
1829 $ hg debugrevspec '0:wdir() & ffff8'
1830 4
1830 4
1831 $ hg debugrevspec '0:wdir() & fffff'
1831 $ hg debugrevspec '0:wdir() & fffff'
1832 2147483647
1832 2147483647
1833
1833
1834 $ cd ..
1834 $ cd ..
1835
1835
1836 Test branch() with wdir()
1836 Test branch() with wdir()
1837
1837
1838 $ cd repo
1838 $ cd repo
1839
1839
1840 $ log '0:wdir() & branch("literal:Γ©")'
1840 $ log '0:wdir() & branch("literal:Γ©")'
1841 8
1841 8
1842 9
1842 9
1843 2147483647
1843 2147483647
1844 $ log '0:wdir() & branch("re:Γ©")'
1844 $ log '0:wdir() & branch("re:Γ©")'
1845 8
1845 8
1846 9
1846 9
1847 2147483647
1847 2147483647
1848 $ log '0:wdir() & branch("re:^a")'
1848 $ log '0:wdir() & branch("re:^a")'
1849 0
1849 0
1850 2
1850 2
1851 $ log '0:wdir() & branch(8)'
1851 $ log '0:wdir() & branch(8)'
1852 8
1852 8
1853 9
1853 9
1854 2147483647
1854 2147483647
1855
1855
1856 branch(wdir()) returns all revisions belonging to the working branch. The wdir
1856 branch(wdir()) returns all revisions belonging to the working branch. The wdir
1857 itself isn't returned unless it is explicitly populated.
1857 itself isn't returned unless it is explicitly populated.
1858
1858
1859 $ log 'branch(wdir())'
1859 $ log 'branch(wdir())'
1860 8
1860 8
1861 9
1861 9
1862 $ log '0:wdir() & branch(wdir())'
1862 $ log '0:wdir() & branch(wdir())'
1863 8
1863 8
1864 9
1864 9
1865 2147483647
1865 2147483647
1866
1866
1867 $ log 'outgoing()'
1867 $ log 'outgoing()'
1868 8
1868 8
1869 9
1869 9
1870 $ log 'outgoing("../remote1")'
1870 $ log 'outgoing("../remote1")'
1871 8
1871 8
1872 9
1872 9
1873 $ log 'outgoing("../remote2")'
1873 $ log 'outgoing("../remote2")'
1874 3
1874 3
1875 5
1875 5
1876 6
1876 6
1877 7
1877 7
1878 9
1878 9
1879 $ log 'p1(merge())'
1879 $ log 'p1(merge())'
1880 5
1880 5
1881 $ log 'p2(merge())'
1881 $ log 'p2(merge())'
1882 4
1882 4
1883 $ log 'parents(merge())'
1883 $ log 'parents(merge())'
1884 4
1884 4
1885 5
1885 5
1886 $ log 'p1(branchpoint())'
1886 $ log 'p1(branchpoint())'
1887 0
1887 0
1888 2
1888 2
1889 $ log 'p2(branchpoint())'
1889 $ log 'p2(branchpoint())'
1890 $ log 'parents(branchpoint())'
1890 $ log 'parents(branchpoint())'
1891 0
1891 0
1892 2
1892 2
1893 $ log 'removes(a)'
1893 $ log 'removes(a)'
1894 2
1894 2
1895 6
1895 6
1896 $ log 'roots(all())'
1896 $ log 'roots(all())'
1897 0
1897 0
1898 $ log 'reverse(2 or 3 or 4 or 5)'
1898 $ log 'reverse(2 or 3 or 4 or 5)'
1899 5
1899 5
1900 4
1900 4
1901 3
1901 3
1902 2
1902 2
1903 $ log 'reverse(all())'
1903 $ log 'reverse(all())'
1904 9
1904 9
1905 8
1905 8
1906 7
1906 7
1907 6
1907 6
1908 5
1908 5
1909 4
1909 4
1910 3
1910 3
1911 2
1911 2
1912 1
1912 1
1913 0
1913 0
1914 $ log 'reverse(all()) & filelog(b)'
1914 $ log 'reverse(all()) & filelog(b)'
1915 4
1915 4
1916 1
1916 1
1917 $ log 'rev(5)'
1917 $ log 'rev(5)'
1918 5
1918 5
1919 $ log 'sort(limit(reverse(all()), 3))'
1919 $ log 'sort(limit(reverse(all()), 3))'
1920 7
1920 7
1921 8
1921 8
1922 9
1922 9
1923 $ log 'sort(2 or 3 or 4 or 5, date)'
1923 $ log 'sort(2 or 3 or 4 or 5, date)'
1924 2
1924 2
1925 3
1925 3
1926 5
1926 5
1927 4
1927 4
1928 $ log 'tagged()'
1928 $ log 'tagged()'
1929 6
1929 6
1930 $ log 'tag()'
1930 $ log 'tag()'
1931 6
1931 6
1932 $ log 'tag(1.0)'
1932 $ log 'tag(1.0)'
1933 6
1933 6
1934 $ log 'tag(tip)'
1934 $ log 'tag(tip)'
1935 9
1935 9
1936
1936
1937 Test order of revisions in compound expression
1937 Test order of revisions in compound expression
1938 ----------------------------------------------
1938 ----------------------------------------------
1939
1939
1940 The general rule is that only the outermost (= leftmost) predicate can
1940 The general rule is that only the outermost (= leftmost) predicate can
1941 enforce its ordering requirement. The other predicates should take the
1941 enforce its ordering requirement. The other predicates should take the
1942 ordering defined by it.
1942 ordering defined by it.
1943
1943
1944 'A & B' should follow the order of 'A':
1944 'A & B' should follow the order of 'A':
1945
1945
1946 $ log '2:0 & 0::2'
1946 $ log '2:0 & 0::2'
1947 2
1947 2
1948 1
1948 1
1949 0
1949 0
1950
1950
1951 'head()' combines sets in right order:
1951 'head()' combines sets in right order:
1952
1952
1953 $ log '2:0 & head()'
1953 $ log '2:0 & head()'
1954 2
1954 2
1955 1
1955 1
1956 0
1956 0
1957
1957
1958 'x:y' takes ordering parameter into account:
1958 'x:y' takes ordering parameter into account:
1959
1959
1960 $ try -p optimized '3:0 & 0:3 & not 2:1'
1960 $ try -p optimized '3:0 & 0:3 & not 2:1'
1961 * optimized:
1961 * optimized:
1962 (difference
1962 (difference
1963 (and
1963 (and
1964 (range
1964 (range
1965 (symbol '3')
1965 (symbol '3')
1966 (symbol '0'))
1966 (symbol '0'))
1967 (range
1967 (range
1968 (symbol '0')
1968 (symbol '0')
1969 (symbol '3')))
1969 (symbol '3')))
1970 (range
1970 (range
1971 (symbol '2')
1971 (symbol '2')
1972 (symbol '1')))
1972 (symbol '1')))
1973 * set:
1973 * set:
1974 <filteredset
1974 <filteredset
1975 <filteredset
1975 <filteredset
1976 <spanset- 0:4>,
1976 <spanset- 0:4>,
1977 <spanset+ 0:4>>,
1977 <spanset+ 0:4>>,
1978 <not
1978 <not
1979 <spanset+ 1:3>>>
1979 <spanset+ 1:3>>>
1980 3
1980 3
1981 0
1981 0
1982
1982
1983 'a + b', which is optimized to '_list(a b)', should take the ordering of
1983 'a + b', which is optimized to '_list(a b)', should take the ordering of
1984 the left expression:
1984 the left expression:
1985
1985
1986 $ try --optimize '2:0 & (0 + 1 + 2)'
1986 $ try --optimize '2:0 & (0 + 1 + 2)'
1987 (and
1987 (and
1988 (range
1988 (range
1989 (symbol '2')
1989 (symbol '2')
1990 (symbol '0'))
1990 (symbol '0'))
1991 (group
1991 (group
1992 (or
1992 (or
1993 (list
1993 (list
1994 (symbol '0')
1994 (symbol '0')
1995 (symbol '1')
1995 (symbol '1')
1996 (symbol '2')))))
1996 (symbol '2')))))
1997 * optimized:
1997 * optimized:
1998 (and
1998 (and
1999 (range
1999 (range
2000 (symbol '2')
2000 (symbol '2')
2001 (symbol '0'))
2001 (symbol '0'))
2002 (func
2002 (func
2003 (symbol '_list')
2003 (symbol '_list')
2004 (string '0\x001\x002')))
2004 (string '0\x001\x002')))
2005 * set:
2005 * set:
2006 <filteredset
2006 <filteredset
2007 <spanset- 0:3>,
2007 <spanset- 0:3>,
2008 <baseset [0, 1, 2]>>
2008 <baseset [0, 1, 2]>>
2009 2
2009 2
2010 1
2010 1
2011 0
2011 0
2012
2012
2013 'A + B' should take the ordering of the left expression:
2013 'A + B' should take the ordering of the left expression:
2014
2014
2015 $ try --optimize '2:0 & (0:1 + 2)'
2015 $ try --optimize '2:0 & (0:1 + 2)'
2016 (and
2016 (and
2017 (range
2017 (range
2018 (symbol '2')
2018 (symbol '2')
2019 (symbol '0'))
2019 (symbol '0'))
2020 (group
2020 (group
2021 (or
2021 (or
2022 (list
2022 (list
2023 (range
2023 (range
2024 (symbol '0')
2024 (symbol '0')
2025 (symbol '1'))
2025 (symbol '1'))
2026 (symbol '2')))))
2026 (symbol '2')))))
2027 * optimized:
2027 * optimized:
2028 (and
2028 (and
2029 (range
2029 (range
2030 (symbol '2')
2030 (symbol '2')
2031 (symbol '0'))
2031 (symbol '0'))
2032 (or
2032 (or
2033 (list
2033 (list
2034 (range
2034 (range
2035 (symbol '0')
2035 (symbol '0')
2036 (symbol '1'))
2036 (symbol '1'))
2037 (symbol '2'))))
2037 (symbol '2'))))
2038 * set:
2038 * set:
2039 <filteredset
2039 <filteredset
2040 <spanset- 0:3>,
2040 <spanset- 0:3>,
2041 <addset
2041 <addset
2042 <spanset+ 0:2>,
2042 <spanset+ 0:2>,
2043 <baseset [2]>>>
2043 <baseset [2]>>>
2044 2
2044 2
2045 1
2045 1
2046 0
2046 0
2047
2047
2048 '_intlist(a b)' should behave like 'a + b':
2048 '_intlist(a b)' should behave like 'a + b':
2049
2049
2050 $ trylist --optimize '2:0 & %ld' 0 1 2
2050 $ trylist --optimize '2:0 & %ld' 0 1 2
2051 (and
2051 (and
2052 (range
2052 (range
2053 (symbol '2')
2053 (symbol '2')
2054 (symbol '0'))
2054 (symbol '0'))
2055 (func
2055 (func
2056 (symbol '_intlist')
2056 (symbol '_intlist')
2057 (string '0\x001\x002')))
2057 (string '0\x001\x002')))
2058 * optimized:
2058 * optimized:
2059 (andsmally
2059 (andsmally
2060 (range
2060 (range
2061 (symbol '2')
2061 (symbol '2')
2062 (symbol '0'))
2062 (symbol '0'))
2063 (func
2063 (func
2064 (symbol '_intlist')
2064 (symbol '_intlist')
2065 (string '0\x001\x002')))
2065 (string '0\x001\x002')))
2066 * set:
2066 * set:
2067 <filteredset
2067 <filteredset
2068 <spanset- 0:3>,
2068 <spanset- 0:3>,
2069 <baseset+ [0, 1, 2]>>
2069 <baseset+ [0, 1, 2]>>
2070 2
2070 2
2071 1
2071 1
2072 0
2072 0
2073
2073
2074 $ trylist --optimize '%ld & 2:0' 0 2 1
2074 $ trylist --optimize '%ld & 2:0' 0 2 1
2075 (and
2075 (and
2076 (func
2076 (func
2077 (symbol '_intlist')
2077 (symbol '_intlist')
2078 (string '0\x002\x001'))
2078 (string '0\x002\x001'))
2079 (range
2079 (range
2080 (symbol '2')
2080 (symbol '2')
2081 (symbol '0')))
2081 (symbol '0')))
2082 * optimized:
2082 * optimized:
2083 (and
2083 (and
2084 (func
2084 (func
2085 (symbol '_intlist')
2085 (symbol '_intlist')
2086 (string '0\x002\x001'))
2086 (string '0\x002\x001'))
2087 (range
2087 (range
2088 (symbol '2')
2088 (symbol '2')
2089 (symbol '0')))
2089 (symbol '0')))
2090 * set:
2090 * set:
2091 <filteredset
2091 <filteredset
2092 <baseset [0, 2, 1]>,
2092 <baseset [0, 2, 1]>,
2093 <spanset- 0:3>>
2093 <spanset- 0:3>>
2094 0
2094 0
2095 2
2095 2
2096 1
2096 1
2097
2097
2098 '_hexlist(a b)' should behave like 'a + b':
2098 '_hexlist(a b)' should behave like 'a + b':
2099
2099
2100 $ trylist --optimize --bin '2:0 & %ln' `hg log -T '{node} ' -r0:2`
2100 $ trylist --optimize --bin '2:0 & %ln' `hg log -T '{node} ' -r0:2`
2101 (and
2101 (and
2102 (range
2102 (range
2103 (symbol '2')
2103 (symbol '2')
2104 (symbol '0'))
2104 (symbol '0'))
2105 (func
2105 (func
2106 (symbol '_hexlist')
2106 (symbol '_hexlist')
2107 (string '*'))) (glob)
2107 (string '*'))) (glob)
2108 * optimized:
2108 * optimized:
2109 (and
2109 (and
2110 (range
2110 (range
2111 (symbol '2')
2111 (symbol '2')
2112 (symbol '0'))
2112 (symbol '0'))
2113 (func
2113 (func
2114 (symbol '_hexlist')
2114 (symbol '_hexlist')
2115 (string '*'))) (glob)
2115 (string '*'))) (glob)
2116 * set:
2116 * set:
2117 <filteredset
2117 <filteredset
2118 <spanset- 0:3>,
2118 <spanset- 0:3>,
2119 <baseset [0, 1, 2]>>
2119 <baseset [0, 1, 2]>>
2120 2
2120 2
2121 1
2121 1
2122 0
2122 0
2123
2123
2124 $ trylist --optimize --bin '%ln & 2:0' `hg log -T '{node} ' -r0+2+1`
2124 $ trylist --optimize --bin '%ln & 2:0' `hg log -T '{node} ' -r0+2+1`
2125 (and
2125 (and
2126 (func
2126 (func
2127 (symbol '_hexlist')
2127 (symbol '_hexlist')
2128 (string '*')) (glob)
2128 (string '*')) (glob)
2129 (range
2129 (range
2130 (symbol '2')
2130 (symbol '2')
2131 (symbol '0')))
2131 (symbol '0')))
2132 * optimized:
2132 * optimized:
2133 (andsmally
2133 (andsmally
2134 (func
2134 (func
2135 (symbol '_hexlist')
2135 (symbol '_hexlist')
2136 (string '*')) (glob)
2136 (string '*')) (glob)
2137 (range
2137 (range
2138 (symbol '2')
2138 (symbol '2')
2139 (symbol '0')))
2139 (symbol '0')))
2140 * set:
2140 * set:
2141 <baseset [0, 2, 1]>
2141 <baseset [0, 2, 1]>
2142 0
2142 0
2143 2
2143 2
2144 1
2144 1
2145
2145
2146 '_list' should not go through the slow follow-order path if order doesn't
2146 '_list' should not go through the slow follow-order path if order doesn't
2147 matter:
2147 matter:
2148
2148
2149 $ try -p optimized '2:0 & not (0 + 1)'
2149 $ try -p optimized '2:0 & not (0 + 1)'
2150 * optimized:
2150 * optimized:
2151 (difference
2151 (difference
2152 (range
2152 (range
2153 (symbol '2')
2153 (symbol '2')
2154 (symbol '0'))
2154 (symbol '0'))
2155 (func
2155 (func
2156 (symbol '_list')
2156 (symbol '_list')
2157 (string '0\x001')))
2157 (string '0\x001')))
2158 * set:
2158 * set:
2159 <filteredset
2159 <filteredset
2160 <spanset- 0:3>,
2160 <spanset- 0:3>,
2161 <not
2161 <not
2162 <baseset [0, 1]>>>
2162 <baseset [0, 1]>>>
2163 2
2163 2
2164
2164
2165 $ try -p optimized '2:0 & not (0:2 & (0 + 1))'
2165 $ try -p optimized '2:0 & not (0:2 & (0 + 1))'
2166 * optimized:
2166 * optimized:
2167 (difference
2167 (difference
2168 (range
2168 (range
2169 (symbol '2')
2169 (symbol '2')
2170 (symbol '0'))
2170 (symbol '0'))
2171 (and
2171 (and
2172 (range
2172 (range
2173 (symbol '0')
2173 (symbol '0')
2174 (symbol '2'))
2174 (symbol '2'))
2175 (func
2175 (func
2176 (symbol '_list')
2176 (symbol '_list')
2177 (string '0\x001'))))
2177 (string '0\x001'))))
2178 * set:
2178 * set:
2179 <filteredset
2179 <filteredset
2180 <spanset- 0:3>,
2180 <spanset- 0:3>,
2181 <not
2181 <not
2182 <baseset [0, 1]>>>
2182 <baseset [0, 1]>>>
2183 2
2183 2
2184
2184
2185 because 'present()' does nothing other than suppressing an error, the
2185 because 'present()' does nothing other than suppressing an error, the
2186 ordering requirement should be forwarded to the nested expression
2186 ordering requirement should be forwarded to the nested expression
2187
2187
2188 $ try -p optimized 'present(2 + 0 + 1)'
2188 $ try -p optimized 'present(2 + 0 + 1)'
2189 * optimized:
2189 * optimized:
2190 (func
2190 (func
2191 (symbol 'present')
2191 (symbol 'present')
2192 (func
2192 (func
2193 (symbol '_list')
2193 (symbol '_list')
2194 (string '2\x000\x001')))
2194 (string '2\x000\x001')))
2195 * set:
2195 * set:
2196 <baseset [2, 0, 1]>
2196 <baseset [2, 0, 1]>
2197 2
2197 2
2198 0
2198 0
2199 1
2199 1
2200
2200
2201 $ try --optimize '2:0 & present(0 + 1 + 2)'
2201 $ try --optimize '2:0 & present(0 + 1 + 2)'
2202 (and
2202 (and
2203 (range
2203 (range
2204 (symbol '2')
2204 (symbol '2')
2205 (symbol '0'))
2205 (symbol '0'))
2206 (func
2206 (func
2207 (symbol 'present')
2207 (symbol 'present')
2208 (or
2208 (or
2209 (list
2209 (list
2210 (symbol '0')
2210 (symbol '0')
2211 (symbol '1')
2211 (symbol '1')
2212 (symbol '2')))))
2212 (symbol '2')))))
2213 * optimized:
2213 * optimized:
2214 (and
2214 (and
2215 (range
2215 (range
2216 (symbol '2')
2216 (symbol '2')
2217 (symbol '0'))
2217 (symbol '0'))
2218 (func
2218 (func
2219 (symbol 'present')
2219 (symbol 'present')
2220 (func
2220 (func
2221 (symbol '_list')
2221 (symbol '_list')
2222 (string '0\x001\x002'))))
2222 (string '0\x001\x002'))))
2223 * set:
2223 * set:
2224 <filteredset
2224 <filteredset
2225 <spanset- 0:3>,
2225 <spanset- 0:3>,
2226 <baseset [0, 1, 2]>>
2226 <baseset [0, 1, 2]>>
2227 2
2227 2
2228 1
2228 1
2229 0
2229 0
2230
2230
2231 'reverse()' should take effect only if it is the outermost expression:
2231 'reverse()' should take effect only if it is the outermost expression:
2232
2232
2233 $ try --optimize '0:2 & reverse(all())'
2233 $ try --optimize '0:2 & reverse(all())'
2234 (and
2234 (and
2235 (range
2235 (range
2236 (symbol '0')
2236 (symbol '0')
2237 (symbol '2'))
2237 (symbol '2'))
2238 (func
2238 (func
2239 (symbol 'reverse')
2239 (symbol 'reverse')
2240 (func
2240 (func
2241 (symbol 'all')
2241 (symbol 'all')
2242 None)))
2242 None)))
2243 * optimized:
2243 * optimized:
2244 (and
2244 (and
2245 (range
2245 (range
2246 (symbol '0')
2246 (symbol '0')
2247 (symbol '2'))
2247 (symbol '2'))
2248 (func
2248 (func
2249 (symbol 'reverse')
2249 (symbol 'reverse')
2250 (func
2250 (func
2251 (symbol 'all')
2251 (symbol 'all')
2252 None)))
2252 None)))
2253 * set:
2253 * set:
2254 <filteredset
2254 <filteredset
2255 <spanset+ 0:3>,
2255 <spanset+ 0:3>,
2256 <spanset+ 0:10>>
2256 <spanset+ 0:10>>
2257 0
2257 0
2258 1
2258 1
2259 2
2259 2
2260
2260
2261 'sort()' should take effect only if it is the outermost expression:
2261 'sort()' should take effect only if it is the outermost expression:
2262
2262
2263 $ try --optimize '0:2 & sort(all(), -rev)'
2263 $ try --optimize '0:2 & sort(all(), -rev)'
2264 (and
2264 (and
2265 (range
2265 (range
2266 (symbol '0')
2266 (symbol '0')
2267 (symbol '2'))
2267 (symbol '2'))
2268 (func
2268 (func
2269 (symbol 'sort')
2269 (symbol 'sort')
2270 (list
2270 (list
2271 (func
2271 (func
2272 (symbol 'all')
2272 (symbol 'all')
2273 None)
2273 None)
2274 (negate
2274 (negate
2275 (symbol 'rev')))))
2275 (symbol 'rev')))))
2276 * optimized:
2276 * optimized:
2277 (and
2277 (and
2278 (range
2278 (range
2279 (symbol '0')
2279 (symbol '0')
2280 (symbol '2'))
2280 (symbol '2'))
2281 (func
2281 (func
2282 (symbol 'sort')
2282 (symbol 'sort')
2283 (list
2283 (list
2284 (func
2284 (func
2285 (symbol 'all')
2285 (symbol 'all')
2286 None)
2286 None)
2287 (string '-rev'))))
2287 (string '-rev'))))
2288 * set:
2288 * set:
2289 <filteredset
2289 <filteredset
2290 <spanset+ 0:3>,
2290 <spanset+ 0:3>,
2291 <spanset+ 0:10>>
2291 <spanset+ 0:10>>
2292 0
2292 0
2293 1
2293 1
2294 2
2294 2
2295
2295
2296 invalid argument passed to noop sort():
2296 invalid argument passed to noop sort():
2297
2297
2298 $ log '0:2 & sort()'
2298 $ log '0:2 & sort()'
2299 hg: parse error: sort requires one or two arguments
2299 hg: parse error: sort requires one or two arguments
2300 [255]
2300 [255]
2301 $ log '0:2 & sort(all(), -invalid)'
2301 $ log '0:2 & sort(all(), -invalid)'
2302 hg: parse error: unknown sort key '-invalid'
2302 hg: parse error: unknown sort key '-invalid'
2303 [255]
2303 [255]
2304
2304
2305 for 'A & f(B)', 'B' should not be affected by the order of 'A':
2305 for 'A & f(B)', 'B' should not be affected by the order of 'A':
2306
2306
2307 $ try --optimize '2:0 & first(1 + 0 + 2)'
2307 $ try --optimize '2:0 & first(1 + 0 + 2)'
2308 (and
2308 (and
2309 (range
2309 (range
2310 (symbol '2')
2310 (symbol '2')
2311 (symbol '0'))
2311 (symbol '0'))
2312 (func
2312 (func
2313 (symbol 'first')
2313 (symbol 'first')
2314 (or
2314 (or
2315 (list
2315 (list
2316 (symbol '1')
2316 (symbol '1')
2317 (symbol '0')
2317 (symbol '0')
2318 (symbol '2')))))
2318 (symbol '2')))))
2319 * optimized:
2319 * optimized:
2320 (and
2320 (and
2321 (range
2321 (range
2322 (symbol '2')
2322 (symbol '2')
2323 (symbol '0'))
2323 (symbol '0'))
2324 (func
2324 (func
2325 (symbol 'first')
2325 (symbol 'first')
2326 (func
2326 (func
2327 (symbol '_list')
2327 (symbol '_list')
2328 (string '1\x000\x002'))))
2328 (string '1\x000\x002'))))
2329 * set:
2329 * set:
2330 <filteredset
2330 <filteredset
2331 <baseset [1]>,
2331 <baseset [1]>,
2332 <spanset- 0:3>>
2332 <spanset- 0:3>>
2333 1
2333 1
2334
2334
2335 $ try --optimize '2:0 & not last(0 + 2 + 1)'
2335 $ try --optimize '2:0 & not last(0 + 2 + 1)'
2336 (and
2336 (and
2337 (range
2337 (range
2338 (symbol '2')
2338 (symbol '2')
2339 (symbol '0'))
2339 (symbol '0'))
2340 (not
2340 (not
2341 (func
2341 (func
2342 (symbol 'last')
2342 (symbol 'last')
2343 (or
2343 (or
2344 (list
2344 (list
2345 (symbol '0')
2345 (symbol '0')
2346 (symbol '2')
2346 (symbol '2')
2347 (symbol '1'))))))
2347 (symbol '1'))))))
2348 * optimized:
2348 * optimized:
2349 (difference
2349 (difference
2350 (range
2350 (range
2351 (symbol '2')
2351 (symbol '2')
2352 (symbol '0'))
2352 (symbol '0'))
2353 (func
2353 (func
2354 (symbol 'last')
2354 (symbol 'last')
2355 (func
2355 (func
2356 (symbol '_list')
2356 (symbol '_list')
2357 (string '0\x002\x001'))))
2357 (string '0\x002\x001'))))
2358 * set:
2358 * set:
2359 <filteredset
2359 <filteredset
2360 <spanset- 0:3>,
2360 <spanset- 0:3>,
2361 <not
2361 <not
2362 <baseset [1]>>>
2362 <baseset [1]>>>
2363 2
2363 2
2364 0
2364 0
2365
2365
2366 for 'A & (op)(B)', 'B' should not be affected by the order of 'A':
2366 for 'A & (op)(B)', 'B' should not be affected by the order of 'A':
2367
2367
2368 $ try --optimize '2:0 & (1 + 0 + 2):(0 + 2 + 1)'
2368 $ try --optimize '2:0 & (1 + 0 + 2):(0 + 2 + 1)'
2369 (and
2369 (and
2370 (range
2370 (range
2371 (symbol '2')
2371 (symbol '2')
2372 (symbol '0'))
2372 (symbol '0'))
2373 (range
2373 (range
2374 (group
2374 (group
2375 (or
2375 (or
2376 (list
2376 (list
2377 (symbol '1')
2377 (symbol '1')
2378 (symbol '0')
2378 (symbol '0')
2379 (symbol '2'))))
2379 (symbol '2'))))
2380 (group
2380 (group
2381 (or
2381 (or
2382 (list
2382 (list
2383 (symbol '0')
2383 (symbol '0')
2384 (symbol '2')
2384 (symbol '2')
2385 (symbol '1'))))))
2385 (symbol '1'))))))
2386 * optimized:
2386 * optimized:
2387 (and
2387 (and
2388 (range
2388 (range
2389 (symbol '2')
2389 (symbol '2')
2390 (symbol '0'))
2390 (symbol '0'))
2391 (range
2391 (range
2392 (func
2392 (func
2393 (symbol '_list')
2393 (symbol '_list')
2394 (string '1\x000\x002'))
2394 (string '1\x000\x002'))
2395 (func
2395 (func
2396 (symbol '_list')
2396 (symbol '_list')
2397 (string '0\x002\x001'))))
2397 (string '0\x002\x001'))))
2398 * set:
2398 * set:
2399 <filteredset
2399 <filteredset
2400 <spanset- 0:3>,
2400 <spanset- 0:3>,
2401 <baseset [1]>>
2401 <baseset [1]>>
2402 1
2402 1
2403
2403
2404 'A & B' can be rewritten as 'flipand(B, A)' by weight.
2404 'A & B' can be rewritten as 'flipand(B, A)' by weight.
2405
2405
2406 $ try --optimize 'contains("glob:*") & (2 + 0 + 1)'
2406 $ try --optimize 'contains("glob:*") & (2 + 0 + 1)'
2407 (and
2407 (and
2408 (func
2408 (func
2409 (symbol 'contains')
2409 (symbol 'contains')
2410 (string 'glob:*'))
2410 (string 'glob:*'))
2411 (group
2411 (group
2412 (or
2412 (or
2413 (list
2413 (list
2414 (symbol '2')
2414 (symbol '2')
2415 (symbol '0')
2415 (symbol '0')
2416 (symbol '1')))))
2416 (symbol '1')))))
2417 * optimized:
2417 * optimized:
2418 (andsmally
2418 (andsmally
2419 (func
2419 (func
2420 (symbol 'contains')
2420 (symbol 'contains')
2421 (string 'glob:*'))
2421 (string 'glob:*'))
2422 (func
2422 (func
2423 (symbol '_list')
2423 (symbol '_list')
2424 (string '2\x000\x001')))
2424 (string '2\x000\x001')))
2425 * set:
2425 * set:
2426 <filteredset
2426 <filteredset
2427 <baseset+ [0, 1, 2]>,
2427 <baseset+ [0, 1, 2]>,
2428 <contains 'glob:*'>>
2428 <contains 'glob:*'>>
2429 0
2429 0
2430 1
2430 1
2431 2
2431 2
2432
2432
2433 and in this example, 'A & B' is rewritten as 'B & A', but 'A' overrides
2433 and in this example, 'A & B' is rewritten as 'B & A', but 'A' overrides
2434 the order appropriately:
2434 the order appropriately:
2435
2435
2436 $ try --optimize 'reverse(contains("glob:*")) & (0 + 2 + 1)'
2436 $ try --optimize 'reverse(contains("glob:*")) & (0 + 2 + 1)'
2437 (and
2437 (and
2438 (func
2438 (func
2439 (symbol 'reverse')
2439 (symbol 'reverse')
2440 (func
2440 (func
2441 (symbol 'contains')
2441 (symbol 'contains')
2442 (string 'glob:*')))
2442 (string 'glob:*')))
2443 (group
2443 (group
2444 (or
2444 (or
2445 (list
2445 (list
2446 (symbol '0')
2446 (symbol '0')
2447 (symbol '2')
2447 (symbol '2')
2448 (symbol '1')))))
2448 (symbol '1')))))
2449 * optimized:
2449 * optimized:
2450 (andsmally
2450 (andsmally
2451 (func
2451 (func
2452 (symbol 'reverse')
2452 (symbol 'reverse')
2453 (func
2453 (func
2454 (symbol 'contains')
2454 (symbol 'contains')
2455 (string 'glob:*')))
2455 (string 'glob:*')))
2456 (func
2456 (func
2457 (symbol '_list')
2457 (symbol '_list')
2458 (string '0\x002\x001')))
2458 (string '0\x002\x001')))
2459 * set:
2459 * set:
2460 <filteredset
2460 <filteredset
2461 <baseset- [0, 1, 2]>,
2461 <baseset- [0, 1, 2]>,
2462 <contains 'glob:*'>>
2462 <contains 'glob:*'>>
2463 2
2463 2
2464 1
2464 1
2465 0
2465 0
2466
2466
2467 test sort revset
2467 test sort revset
2468 --------------------------------------------
2468 --------------------------------------------
2469
2469
2470 test when adding two unordered revsets
2470 test when adding two unordered revsets
2471
2471
2472 $ log 'sort(keyword(issue) or modifies(b))'
2472 $ log 'sort(keyword(issue) or modifies(b))'
2473 4
2473 4
2474 6
2474 6
2475
2475
2476 test when sorting a reversed collection in the same way it is
2476 test when sorting a reversed collection in the same way it is
2477
2477
2478 $ log 'sort(reverse(all()), -rev)'
2478 $ log 'sort(reverse(all()), -rev)'
2479 9
2479 9
2480 8
2480 8
2481 7
2481 7
2482 6
2482 6
2483 5
2483 5
2484 4
2484 4
2485 3
2485 3
2486 2
2486 2
2487 1
2487 1
2488 0
2488 0
2489
2489
2490 test when sorting a reversed collection
2490 test when sorting a reversed collection
2491
2491
2492 $ log 'sort(reverse(all()), rev)'
2492 $ log 'sort(reverse(all()), rev)'
2493 0
2493 0
2494 1
2494 1
2495 2
2495 2
2496 3
2496 3
2497 4
2497 4
2498 5
2498 5
2499 6
2499 6
2500 7
2500 7
2501 8
2501 8
2502 9
2502 9
2503
2503
2504
2504
2505 test sorting two sorted collections in different orders
2505 test sorting two sorted collections in different orders
2506
2506
2507 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
2507 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
2508 2
2508 2
2509 6
2509 6
2510 8
2510 8
2511 9
2511 9
2512
2512
2513 test sorting two sorted collections in different orders backwards
2513 test sorting two sorted collections in different orders backwards
2514
2514
2515 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
2515 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
2516 9
2516 9
2517 8
2517 8
2518 6
2518 6
2519 2
2519 2
2520
2520
2521 test empty sort key which is noop
2521 test empty sort key which is noop
2522
2522
2523 $ log 'sort(0 + 2 + 1, "")'
2523 $ log 'sort(0 + 2 + 1, "")'
2524 0
2524 0
2525 2
2525 2
2526 1
2526 1
2527
2527
2528 test invalid sort keys
2528 test invalid sort keys
2529
2529
2530 $ log 'sort(all(), -invalid)'
2530 $ log 'sort(all(), -invalid)'
2531 hg: parse error: unknown sort key '-invalid'
2531 hg: parse error: unknown sort key '-invalid'
2532 [255]
2532 [255]
2533
2533
2534 $ cd ..
2534 $ cd ..
2535
2535
2536 test sorting by multiple keys including variable-length strings
2536 test sorting by multiple keys including variable-length strings
2537
2537
2538 $ hg init sorting
2538 $ hg init sorting
2539 $ cd sorting
2539 $ cd sorting
2540 $ cat <<EOF >> .hg/hgrc
2540 $ cat <<EOF >> .hg/hgrc
2541 > [ui]
2541 > [ui]
2542 > logtemplate = '{rev} {branch|p5}{desc|p5}{author|p5}{date|hgdate}\n'
2542 > logtemplate = '{rev} {branch|p5}{desc|p5}{author|p5}{date|hgdate}\n'
2543 > [templatealias]
2543 > [templatealias]
2544 > p5(s) = pad(s, 5)
2544 > p5(s) = pad(s, 5)
2545 > EOF
2545 > EOF
2546 $ hg branch -qf b12
2546 $ hg branch -qf b12
2547 $ hg ci -m m111 -u u112 -d '111 10800'
2547 $ hg ci -m m111 -u u112 -d '111 10800'
2548 $ hg branch -qf b11
2548 $ hg branch -qf b11
2549 $ hg ci -m m12 -u u111 -d '112 7200'
2549 $ hg ci -m m12 -u u111 -d '112 7200'
2550 $ hg branch -qf b111
2550 $ hg branch -qf b111
2551 $ hg ci -m m11 -u u12 -d '111 3600'
2551 $ hg ci -m m11 -u u12 -d '111 3600'
2552 $ hg branch -qf b112
2552 $ hg branch -qf b112
2553 $ hg ci -m m111 -u u11 -d '120 0'
2553 $ hg ci -m m111 -u u11 -d '120 0'
2554 $ hg branch -qf b111
2554 $ hg branch -qf b111
2555 $ hg ci -m m112 -u u111 -d '110 14400'
2555 $ hg ci -m m112 -u u111 -d '110 14400'
2556 created new head
2556 created new head
2557
2557
2558 compare revisions (has fast path):
2558 compare revisions (has fast path):
2559
2559
2560 $ hg log -r 'sort(all(), rev)'
2560 $ hg log -r 'sort(all(), rev)'
2561 0 b12 m111 u112 111 10800
2561 0 b12 m111 u112 111 10800
2562 1 b11 m12 u111 112 7200
2562 1 b11 m12 u111 112 7200
2563 2 b111 m11 u12 111 3600
2563 2 b111 m11 u12 111 3600
2564 3 b112 m111 u11 120 0
2564 3 b112 m111 u11 120 0
2565 4 b111 m112 u111 110 14400
2565 4 b111 m112 u111 110 14400
2566
2566
2567 $ hg log -r 'sort(all(), -rev)'
2567 $ hg log -r 'sort(all(), -rev)'
2568 4 b111 m112 u111 110 14400
2568 4 b111 m112 u111 110 14400
2569 3 b112 m111 u11 120 0
2569 3 b112 m111 u11 120 0
2570 2 b111 m11 u12 111 3600
2570 2 b111 m11 u12 111 3600
2571 1 b11 m12 u111 112 7200
2571 1 b11 m12 u111 112 7200
2572 0 b12 m111 u112 111 10800
2572 0 b12 m111 u112 111 10800
2573
2573
2574 compare variable-length strings (issue5218):
2574 compare variable-length strings (issue5218):
2575
2575
2576 $ hg log -r 'sort(all(), branch)'
2576 $ hg log -r 'sort(all(), branch)'
2577 1 b11 m12 u111 112 7200
2577 1 b11 m12 u111 112 7200
2578 2 b111 m11 u12 111 3600
2578 2 b111 m11 u12 111 3600
2579 4 b111 m112 u111 110 14400
2579 4 b111 m112 u111 110 14400
2580 3 b112 m111 u11 120 0
2580 3 b112 m111 u11 120 0
2581 0 b12 m111 u112 111 10800
2581 0 b12 m111 u112 111 10800
2582
2582
2583 $ hg log -r 'sort(all(), -branch)'
2583 $ hg log -r 'sort(all(), -branch)'
2584 0 b12 m111 u112 111 10800
2584 0 b12 m111 u112 111 10800
2585 3 b112 m111 u11 120 0
2585 3 b112 m111 u11 120 0
2586 2 b111 m11 u12 111 3600
2586 2 b111 m11 u12 111 3600
2587 4 b111 m112 u111 110 14400
2587 4 b111 m112 u111 110 14400
2588 1 b11 m12 u111 112 7200
2588 1 b11 m12 u111 112 7200
2589
2589
2590 $ hg log -r 'sort(all(), desc)'
2590 $ hg log -r 'sort(all(), desc)'
2591 2 b111 m11 u12 111 3600
2591 2 b111 m11 u12 111 3600
2592 0 b12 m111 u112 111 10800
2592 0 b12 m111 u112 111 10800
2593 3 b112 m111 u11 120 0
2593 3 b112 m111 u11 120 0
2594 4 b111 m112 u111 110 14400
2594 4 b111 m112 u111 110 14400
2595 1 b11 m12 u111 112 7200
2595 1 b11 m12 u111 112 7200
2596
2596
2597 $ hg log -r 'sort(all(), -desc)'
2597 $ hg log -r 'sort(all(), -desc)'
2598 1 b11 m12 u111 112 7200
2598 1 b11 m12 u111 112 7200
2599 4 b111 m112 u111 110 14400
2599 4 b111 m112 u111 110 14400
2600 0 b12 m111 u112 111 10800
2600 0 b12 m111 u112 111 10800
2601 3 b112 m111 u11 120 0
2601 3 b112 m111 u11 120 0
2602 2 b111 m11 u12 111 3600
2602 2 b111 m11 u12 111 3600
2603
2603
2604 $ hg log -r 'sort(all(), user)'
2604 $ hg log -r 'sort(all(), user)'
2605 3 b112 m111 u11 120 0
2605 3 b112 m111 u11 120 0
2606 1 b11 m12 u111 112 7200
2606 1 b11 m12 u111 112 7200
2607 4 b111 m112 u111 110 14400
2607 4 b111 m112 u111 110 14400
2608 0 b12 m111 u112 111 10800
2608 0 b12 m111 u112 111 10800
2609 2 b111 m11 u12 111 3600
2609 2 b111 m11 u12 111 3600
2610
2610
2611 $ hg log -r 'sort(all(), -user)'
2611 $ hg log -r 'sort(all(), -user)'
2612 2 b111 m11 u12 111 3600
2612 2 b111 m11 u12 111 3600
2613 0 b12 m111 u112 111 10800
2613 0 b12 m111 u112 111 10800
2614 1 b11 m12 u111 112 7200
2614 1 b11 m12 u111 112 7200
2615 4 b111 m112 u111 110 14400
2615 4 b111 m112 u111 110 14400
2616 3 b112 m111 u11 120 0
2616 3 b112 m111 u11 120 0
2617
2617
2618 compare dates (tz offset should have no effect):
2618 compare dates (tz offset should have no effect):
2619
2619
2620 $ hg log -r 'sort(all(), date)'
2620 $ hg log -r 'sort(all(), date)'
2621 4 b111 m112 u111 110 14400
2621 4 b111 m112 u111 110 14400
2622 0 b12 m111 u112 111 10800
2622 0 b12 m111 u112 111 10800
2623 2 b111 m11 u12 111 3600
2623 2 b111 m11 u12 111 3600
2624 1 b11 m12 u111 112 7200
2624 1 b11 m12 u111 112 7200
2625 3 b112 m111 u11 120 0
2625 3 b112 m111 u11 120 0
2626
2626
2627 $ hg log -r 'sort(all(), -date)'
2627 $ hg log -r 'sort(all(), -date)'
2628 3 b112 m111 u11 120 0
2628 3 b112 m111 u11 120 0
2629 1 b11 m12 u111 112 7200
2629 1 b11 m12 u111 112 7200
2630 0 b12 m111 u112 111 10800
2630 0 b12 m111 u112 111 10800
2631 2 b111 m11 u12 111 3600
2631 2 b111 m11 u12 111 3600
2632 4 b111 m112 u111 110 14400
2632 4 b111 m112 u111 110 14400
2633
2633
2634 be aware that 'sort(x, -k)' is not exactly the same as 'reverse(sort(x, k))'
2634 be aware that 'sort(x, -k)' is not exactly the same as 'reverse(sort(x, k))'
2635 because '-k' reverses the comparison, not the list itself:
2635 because '-k' reverses the comparison, not the list itself:
2636
2636
2637 $ hg log -r 'sort(0 + 2, date)'
2637 $ hg log -r 'sort(0 + 2, date)'
2638 0 b12 m111 u112 111 10800
2638 0 b12 m111 u112 111 10800
2639 2 b111 m11 u12 111 3600
2639 2 b111 m11 u12 111 3600
2640
2640
2641 $ hg log -r 'sort(0 + 2, -date)'
2641 $ hg log -r 'sort(0 + 2, -date)'
2642 0 b12 m111 u112 111 10800
2642 0 b12 m111 u112 111 10800
2643 2 b111 m11 u12 111 3600
2643 2 b111 m11 u12 111 3600
2644
2644
2645 $ hg log -r 'reverse(sort(0 + 2, date))'
2645 $ hg log -r 'reverse(sort(0 + 2, date))'
2646 2 b111 m11 u12 111 3600
2646 2 b111 m11 u12 111 3600
2647 0 b12 m111 u112 111 10800
2647 0 b12 m111 u112 111 10800
2648
2648
2649 sort by multiple keys:
2649 sort by multiple keys:
2650
2650
2651 $ hg log -r 'sort(all(), "branch -rev")'
2651 $ hg log -r 'sort(all(), "branch -rev")'
2652 1 b11 m12 u111 112 7200
2652 1 b11 m12 u111 112 7200
2653 4 b111 m112 u111 110 14400
2653 4 b111 m112 u111 110 14400
2654 2 b111 m11 u12 111 3600
2654 2 b111 m11 u12 111 3600
2655 3 b112 m111 u11 120 0
2655 3 b112 m111 u11 120 0
2656 0 b12 m111 u112 111 10800
2656 0 b12 m111 u112 111 10800
2657
2657
2658 $ hg log -r 'sort(all(), "-desc -date")'
2658 $ hg log -r 'sort(all(), "-desc -date")'
2659 1 b11 m12 u111 112 7200
2659 1 b11 m12 u111 112 7200
2660 4 b111 m112 u111 110 14400
2660 4 b111 m112 u111 110 14400
2661 3 b112 m111 u11 120 0
2661 3 b112 m111 u11 120 0
2662 0 b12 m111 u112 111 10800
2662 0 b12 m111 u112 111 10800
2663 2 b111 m11 u12 111 3600
2663 2 b111 m11 u12 111 3600
2664
2664
2665 $ hg log -r 'sort(all(), "user -branch date rev")'
2665 $ hg log -r 'sort(all(), "user -branch date rev")'
2666 3 b112 m111 u11 120 0
2666 3 b112 m111 u11 120 0
2667 4 b111 m112 u111 110 14400
2667 4 b111 m112 u111 110 14400
2668 1 b11 m12 u111 112 7200
2668 1 b11 m12 u111 112 7200
2669 0 b12 m111 u112 111 10800
2669 0 b12 m111 u112 111 10800
2670 2 b111 m11 u12 111 3600
2670 2 b111 m11 u12 111 3600
2671
2671
2672 toposort prioritises graph branches
2672 toposort prioritises graph branches
2673
2673
2674 $ hg up 2
2674 $ hg up 2
2675 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2675 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2676 $ touch a
2676 $ touch a
2677 $ hg addremove
2677 $ hg addremove
2678 adding a
2678 adding a
2679 $ hg ci -m 't1' -u 'tu' -d '130 0'
2679 $ hg ci -m 't1' -u 'tu' -d '130 0'
2680 created new head
2680 created new head
2681 $ echo 'a' >> a
2681 $ echo 'a' >> a
2682 $ hg ci -m 't2' -u 'tu' -d '130 0'
2682 $ hg ci -m 't2' -u 'tu' -d '130 0'
2683 $ hg book book1
2683 $ hg book book1
2684 $ hg up 4
2684 $ hg up 4
2685 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2685 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2686 (leaving bookmark book1)
2686 (leaving bookmark book1)
2687 $ touch a
2687 $ touch a
2688 $ hg addremove
2688 $ hg addremove
2689 adding a
2689 adding a
2690 $ hg ci -m 't3' -u 'tu' -d '130 0'
2690 $ hg ci -m 't3' -u 'tu' -d '130 0'
2691
2691
2692 $ hg log -r 'sort(all(), topo)'
2692 $ hg log -r 'sort(all(), topo)'
2693 7 b111 t3 tu 130 0
2693 7 b111 t3 tu 130 0
2694 4 b111 m112 u111 110 14400
2694 4 b111 m112 u111 110 14400
2695 3 b112 m111 u11 120 0
2695 3 b112 m111 u11 120 0
2696 6 b111 t2 tu 130 0
2696 6 b111 t2 tu 130 0
2697 5 b111 t1 tu 130 0
2697 5 b111 t1 tu 130 0
2698 2 b111 m11 u12 111 3600
2698 2 b111 m11 u12 111 3600
2699 1 b11 m12 u111 112 7200
2699 1 b11 m12 u111 112 7200
2700 0 b12 m111 u112 111 10800
2700 0 b12 m111 u112 111 10800
2701
2701
2702 $ hg log -r 'sort(all(), -topo)'
2702 $ hg log -r 'sort(all(), -topo)'
2703 0 b12 m111 u112 111 10800
2703 0 b12 m111 u112 111 10800
2704 1 b11 m12 u111 112 7200
2704 1 b11 m12 u111 112 7200
2705 2 b111 m11 u12 111 3600
2705 2 b111 m11 u12 111 3600
2706 5 b111 t1 tu 130 0
2706 5 b111 t1 tu 130 0
2707 6 b111 t2 tu 130 0
2707 6 b111 t2 tu 130 0
2708 3 b112 m111 u11 120 0
2708 3 b112 m111 u11 120 0
2709 4 b111 m112 u111 110 14400
2709 4 b111 m112 u111 110 14400
2710 7 b111 t3 tu 130 0
2710 7 b111 t3 tu 130 0
2711
2711
2712 $ hg log -r 'sort(all(), topo, topo.firstbranch=book1)'
2712 $ hg log -r 'sort(all(), topo, topo.firstbranch=book1)'
2713 6 b111 t2 tu 130 0
2713 6 b111 t2 tu 130 0
2714 5 b111 t1 tu 130 0
2714 5 b111 t1 tu 130 0
2715 7 b111 t3 tu 130 0
2715 7 b111 t3 tu 130 0
2716 4 b111 m112 u111 110 14400
2716 4 b111 m112 u111 110 14400
2717 3 b112 m111 u11 120 0
2717 3 b112 m111 u11 120 0
2718 2 b111 m11 u12 111 3600
2718 2 b111 m11 u12 111 3600
2719 1 b11 m12 u111 112 7200
2719 1 b11 m12 u111 112 7200
2720 0 b12 m111 u112 111 10800
2720 0 b12 m111 u112 111 10800
2721
2721
2722 topographical sorting can't be combined with other sort keys, and you can't
2722 topographical sorting can't be combined with other sort keys, and you can't
2723 use the topo.firstbranch option when topo sort is not active:
2723 use the topo.firstbranch option when topo sort is not active:
2724
2724
2725 $ hg log -r 'sort(all(), "topo user")'
2725 $ hg log -r 'sort(all(), "topo user")'
2726 hg: parse error: topo sort order cannot be combined with other sort keys
2726 hg: parse error: topo sort order cannot be combined with other sort keys
2727 [255]
2727 [255]
2728
2728
2729 $ hg log -r 'sort(all(), user, topo.firstbranch=book1)'
2729 $ hg log -r 'sort(all(), user, topo.firstbranch=book1)'
2730 hg: parse error: topo.firstbranch can only be used when using the topo sort key
2730 hg: parse error: topo.firstbranch can only be used when using the topo sort key
2731 [255]
2731 [255]
2732
2732
2733 topo.firstbranch should accept any kind of expressions:
2733 topo.firstbranch should accept any kind of expressions:
2734
2734
2735 $ hg log -r 'sort(0, topo, topo.firstbranch=(book1))'
2735 $ hg log -r 'sort(0, topo, topo.firstbranch=(book1))'
2736 0 b12 m111 u112 111 10800
2736 0 b12 m111 u112 111 10800
2737
2737
2738 $ cd ..
2738 $ cd ..
2739 $ cd repo
2739 $ cd repo
@@ -1,1818 +1,1818 b''
1 $ HGENCODING=utf-8
1 $ HGENCODING=utf-8
2 $ export HGENCODING
2 $ export HGENCODING
3 $ cat >> $HGRCPATH << EOF
3 $ cat >> $HGRCPATH << EOF
4 > [extensions]
4 > [extensions]
5 > drawdag=$TESTDIR/drawdag.py
5 > drawdag=$TESTDIR/drawdag.py
6 > EOF
6 > EOF
7
7
8 $ try() {
8 $ try() {
9 > hg debugrevspec --debug "$@"
9 > hg debugrevspec --debug "$@"
10 > }
10 > }
11
11
12 $ log() {
12 $ log() {
13 > hg log --template '{rev}\n' -r "$1"
13 > hg log --template '{rev}\n' -r "$1"
14 > }
14 > }
15
15
16 $ hg init repo
16 $ hg init repo
17 $ cd repo
17 $ cd repo
18
18
19 $ echo a > a
19 $ echo a > a
20 $ hg branch a
20 $ hg branch a
21 marked working directory as branch a
21 marked working directory as branch a
22 (branches are permanent and global, did you want a bookmark?)
22 (branches are permanent and global, did you want a bookmark?)
23 $ hg ci -Aqm0
23 $ hg ci -Aqm0
24
24
25 $ echo b > b
25 $ echo b > b
26 $ hg branch b
26 $ hg branch b
27 marked working directory as branch b
27 marked working directory as branch b
28 $ hg ci -Aqm1
28 $ hg ci -Aqm1
29
29
30 $ rm a
30 $ rm a
31 $ hg branch a-b-c-
31 $ hg branch a-b-c-
32 marked working directory as branch a-b-c-
32 marked working directory as branch a-b-c-
33 $ hg ci -Aqm2 -u Bob
33 $ hg ci -Aqm2 -u Bob
34
34
35 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
35 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
36 2
36 2
37 $ hg log -r "extra('branch')" --template '{rev}\n'
37 $ hg log -r "extra('branch')" --template '{rev}\n'
38 0
38 0
39 1
39 1
40 2
40 2
41 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
41 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
42 0 a
42 0 a
43 2 a-b-c-
43 2 a-b-c-
44
44
45 $ hg co 1
45 $ hg co 1
46 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
46 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
47 $ hg branch +a+b+c+
47 $ hg branch +a+b+c+
48 marked working directory as branch +a+b+c+
48 marked working directory as branch +a+b+c+
49 $ hg ci -Aqm3
49 $ hg ci -Aqm3
50
50
51 $ hg co 2 # interleave
51 $ hg co 2 # interleave
52 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
52 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
53 $ echo bb > b
53 $ echo bb > b
54 $ hg branch -- -a-b-c-
54 $ hg branch -- -a-b-c-
55 marked working directory as branch -a-b-c-
55 marked working directory as branch -a-b-c-
56 $ hg ci -Aqm4 -d "May 12 2005"
56 $ hg ci -Aqm4 -d "May 12 2005"
57
57
58 $ hg co 3
58 $ hg co 3
59 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
60 $ hg branch !a/b/c/
60 $ hg branch !a/b/c/
61 marked working directory as branch !a/b/c/
61 marked working directory as branch !a/b/c/
62 $ hg ci -Aqm"5 bug"
62 $ hg ci -Aqm"5 bug"
63
63
64 $ hg merge 4
64 $ hg merge 4
65 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
65 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
66 (branch merge, don't forget to commit)
66 (branch merge, don't forget to commit)
67 $ hg branch _a_b_c_
67 $ hg branch _a_b_c_
68 marked working directory as branch _a_b_c_
68 marked working directory as branch _a_b_c_
69 $ hg ci -Aqm"6 issue619"
69 $ hg ci -Aqm"6 issue619"
70
70
71 $ hg branch .a.b.c.
71 $ hg branch .a.b.c.
72 marked working directory as branch .a.b.c.
72 marked working directory as branch .a.b.c.
73 $ hg ci -Aqm7
73 $ hg ci -Aqm7
74
74
75 $ hg branch all
75 $ hg branch all
76 marked working directory as branch all
76 marked working directory as branch all
77
77
78 $ hg co 4
78 $ hg co 4
79 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 $ hg branch Γ©
80 $ hg branch Γ©
81 marked working directory as branch \xc3\xa9 (esc)
81 marked working directory as branch \xc3\xa9 (esc)
82 $ hg ci -Aqm9
82 $ hg ci -Aqm9
83
83
84 $ hg tag -r6 1.0
84 $ hg tag -r6 1.0
85 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
85 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
86
86
87 $ hg clone --quiet -U -r 7 . ../remote1
87 $ hg clone --quiet -U -r 7 . ../remote1
88 $ hg clone --quiet -U -r 8 . ../remote2
88 $ hg clone --quiet -U -r 8 . ../remote2
89 $ echo "[paths]" >> .hg/hgrc
89 $ echo "[paths]" >> .hg/hgrc
90 $ echo "default = ../remote1" >> .hg/hgrc
90 $ echo "default = ../remote1" >> .hg/hgrc
91
91
92 test subtracting something from an addset
92 test subtracting something from an addset
93
93
94 $ log '(outgoing() or removes(a)) - removes(a)'
94 $ log '(outgoing() or removes(a)) - removes(a)'
95 8
95 8
96 9
96 9
97
97
98 test intersecting something with an addset
98 test intersecting something with an addset
99
99
100 $ log 'parents(outgoing() or removes(a))'
100 $ log 'parents(outgoing() or removes(a))'
101 1
101 1
102 4
102 4
103 5
103 5
104 8
104 8
105
105
106 test that `or` operation combines elements in the right order:
106 test that `or` operation combines elements in the right order:
107
107
108 $ log '3:4 or 2:5'
108 $ log '3:4 or 2:5'
109 3
109 3
110 4
110 4
111 2
111 2
112 5
112 5
113 $ log '3:4 or 5:2'
113 $ log '3:4 or 5:2'
114 3
114 3
115 4
115 4
116 5
116 5
117 2
117 2
118 $ log 'sort(3:4 or 2:5)'
118 $ log 'sort(3:4 or 2:5)'
119 2
119 2
120 3
120 3
121 4
121 4
122 5
122 5
123 $ log 'sort(3:4 or 5:2)'
123 $ log 'sort(3:4 or 5:2)'
124 2
124 2
125 3
125 3
126 4
126 4
127 5
127 5
128
128
129 test that more than one `-r`s are combined in the right order and deduplicated:
129 test that more than one `-r`s are combined in the right order and deduplicated:
130
130
131 $ hg log -T '{rev}\n' -r 3 -r 3 -r 4 -r 5:2 -r 'ancestors(4)'
131 $ hg log -T '{rev}\n' -r 3 -r 3 -r 4 -r 5:2 -r 'ancestors(4)'
132 3
132 3
133 4
133 4
134 5
134 5
135 2
135 2
136 0
136 0
137 1
137 1
138
138
139 test that `or` operation skips duplicated revisions from right-hand side
139 test that `or` operation skips duplicated revisions from right-hand side
140
140
141 $ try 'reverse(1::5) or ancestors(4)'
141 $ try 'reverse(1::5) or ancestors(4)'
142 (or
142 (or
143 (list
143 (list
144 (func
144 (func
145 (symbol 'reverse')
145 (symbol 'reverse')
146 (dagrange
146 (dagrange
147 (symbol '1')
147 (symbol '1')
148 (symbol '5')))
148 (symbol '5')))
149 (func
149 (func
150 (symbol 'ancestors')
150 (symbol 'ancestors')
151 (symbol '4'))))
151 (symbol '4'))))
152 * set:
152 * set:
153 <addset
153 <addset
154 <baseset- [1, 3, 5]>,
154 <baseset- [1, 3, 5]>,
155 <generatorset+>>
155 <generatorsetdesc+>>
156 5
156 5
157 3
157 3
158 1
158 1
159 0
159 0
160 2
160 2
161 4
161 4
162 $ try 'sort(ancestors(4) or reverse(1::5))'
162 $ try 'sort(ancestors(4) or reverse(1::5))'
163 (func
163 (func
164 (symbol 'sort')
164 (symbol 'sort')
165 (or
165 (or
166 (list
166 (list
167 (func
167 (func
168 (symbol 'ancestors')
168 (symbol 'ancestors')
169 (symbol '4'))
169 (symbol '4'))
170 (func
170 (func
171 (symbol 'reverse')
171 (symbol 'reverse')
172 (dagrange
172 (dagrange
173 (symbol '1')
173 (symbol '1')
174 (symbol '5'))))))
174 (symbol '5'))))))
175 * set:
175 * set:
176 <addset+
176 <addset+
177 <generatorset+>,
177 <generatorsetdesc+>,
178 <baseset- [1, 3, 5]>>
178 <baseset- [1, 3, 5]>>
179 0
179 0
180 1
180 1
181 2
181 2
182 3
182 3
183 4
183 4
184 5
184 5
185
185
186 test optimization of trivial `or` operation
186 test optimization of trivial `or` operation
187
187
188 $ try --optimize '0|(1)|"2"|-2|tip|null'
188 $ try --optimize '0|(1)|"2"|-2|tip|null'
189 (or
189 (or
190 (list
190 (list
191 (symbol '0')
191 (symbol '0')
192 (group
192 (group
193 (symbol '1'))
193 (symbol '1'))
194 (string '2')
194 (string '2')
195 (negate
195 (negate
196 (symbol '2'))
196 (symbol '2'))
197 (symbol 'tip')
197 (symbol 'tip')
198 (symbol 'null')))
198 (symbol 'null')))
199 * optimized:
199 * optimized:
200 (func
200 (func
201 (symbol '_list')
201 (symbol '_list')
202 (string '0\x001\x002\x00-2\x00tip\x00null'))
202 (string '0\x001\x002\x00-2\x00tip\x00null'))
203 * set:
203 * set:
204 <baseset [0, 1, 2, 8, 9, -1]>
204 <baseset [0, 1, 2, 8, 9, -1]>
205 0
205 0
206 1
206 1
207 2
207 2
208 8
208 8
209 9
209 9
210 -1
210 -1
211
211
212 $ try --optimize '0|1|2:3'
212 $ try --optimize '0|1|2:3'
213 (or
213 (or
214 (list
214 (list
215 (symbol '0')
215 (symbol '0')
216 (symbol '1')
216 (symbol '1')
217 (range
217 (range
218 (symbol '2')
218 (symbol '2')
219 (symbol '3'))))
219 (symbol '3'))))
220 * optimized:
220 * optimized:
221 (or
221 (or
222 (list
222 (list
223 (func
223 (func
224 (symbol '_list')
224 (symbol '_list')
225 (string '0\x001'))
225 (string '0\x001'))
226 (range
226 (range
227 (symbol '2')
227 (symbol '2')
228 (symbol '3'))))
228 (symbol '3'))))
229 * set:
229 * set:
230 <addset
230 <addset
231 <baseset [0, 1]>,
231 <baseset [0, 1]>,
232 <spanset+ 2:4>>
232 <spanset+ 2:4>>
233 0
233 0
234 1
234 1
235 2
235 2
236 3
236 3
237
237
238 $ try --optimize '0:1|2|3:4|5|6'
238 $ try --optimize '0:1|2|3:4|5|6'
239 (or
239 (or
240 (list
240 (list
241 (range
241 (range
242 (symbol '0')
242 (symbol '0')
243 (symbol '1'))
243 (symbol '1'))
244 (symbol '2')
244 (symbol '2')
245 (range
245 (range
246 (symbol '3')
246 (symbol '3')
247 (symbol '4'))
247 (symbol '4'))
248 (symbol '5')
248 (symbol '5')
249 (symbol '6')))
249 (symbol '6')))
250 * optimized:
250 * optimized:
251 (or
251 (or
252 (list
252 (list
253 (range
253 (range
254 (symbol '0')
254 (symbol '0')
255 (symbol '1'))
255 (symbol '1'))
256 (symbol '2')
256 (symbol '2')
257 (range
257 (range
258 (symbol '3')
258 (symbol '3')
259 (symbol '4'))
259 (symbol '4'))
260 (func
260 (func
261 (symbol '_list')
261 (symbol '_list')
262 (string '5\x006'))))
262 (string '5\x006'))))
263 * set:
263 * set:
264 <addset
264 <addset
265 <addset
265 <addset
266 <spanset+ 0:2>,
266 <spanset+ 0:2>,
267 <baseset [2]>>,
267 <baseset [2]>>,
268 <addset
268 <addset
269 <spanset+ 3:5>,
269 <spanset+ 3:5>,
270 <baseset [5, 6]>>>
270 <baseset [5, 6]>>>
271 0
271 0
272 1
272 1
273 2
273 2
274 3
274 3
275 4
275 4
276 5
276 5
277 6
277 6
278
278
279 unoptimized `or` looks like this
279 unoptimized `or` looks like this
280
280
281 $ try --no-optimized -p analyzed '0|1|2|3|4'
281 $ try --no-optimized -p analyzed '0|1|2|3|4'
282 * analyzed:
282 * analyzed:
283 (or
283 (or
284 (list
284 (list
285 (symbol '0')
285 (symbol '0')
286 (symbol '1')
286 (symbol '1')
287 (symbol '2')
287 (symbol '2')
288 (symbol '3')
288 (symbol '3')
289 (symbol '4')))
289 (symbol '4')))
290 * set:
290 * set:
291 <addset
291 <addset
292 <addset
292 <addset
293 <baseset [0]>,
293 <baseset [0]>,
294 <baseset [1]>>,
294 <baseset [1]>>,
295 <addset
295 <addset
296 <baseset [2]>,
296 <baseset [2]>,
297 <addset
297 <addset
298 <baseset [3]>,
298 <baseset [3]>,
299 <baseset [4]>>>>
299 <baseset [4]>>>>
300 0
300 0
301 1
301 1
302 2
302 2
303 3
303 3
304 4
304 4
305
305
306 test that `_list` should be narrowed by provided `subset`
306 test that `_list` should be narrowed by provided `subset`
307
307
308 $ log '0:2 and (null|1|2|3)'
308 $ log '0:2 and (null|1|2|3)'
309 1
309 1
310 2
310 2
311
311
312 test that `_list` should remove duplicates
312 test that `_list` should remove duplicates
313
313
314 $ log '0|1|2|1|2|-1|tip'
314 $ log '0|1|2|1|2|-1|tip'
315 0
315 0
316 1
316 1
317 2
317 2
318 9
318 9
319
319
320 test unknown revision in `_list`
320 test unknown revision in `_list`
321
321
322 $ log '0|unknown'
322 $ log '0|unknown'
323 abort: unknown revision 'unknown'!
323 abort: unknown revision 'unknown'!
324 [255]
324 [255]
325
325
326 test integer range in `_list`
326 test integer range in `_list`
327
327
328 $ log '-1|-10'
328 $ log '-1|-10'
329 9
329 9
330 0
330 0
331
331
332 $ log '-10|-11'
332 $ log '-10|-11'
333 abort: unknown revision '-11'!
333 abort: unknown revision '-11'!
334 [255]
334 [255]
335
335
336 $ log '9|10'
336 $ log '9|10'
337 abort: unknown revision '10'!
337 abort: unknown revision '10'!
338 [255]
338 [255]
339
339
340 test '0000' != '0' in `_list`
340 test '0000' != '0' in `_list`
341
341
342 $ log '0|0000'
342 $ log '0|0000'
343 0
343 0
344 -1
344 -1
345
345
346 test ',' in `_list`
346 test ',' in `_list`
347 $ log '0,1'
347 $ log '0,1'
348 hg: parse error: can't use a list in this context
348 hg: parse error: can't use a list in this context
349 (see hg help "revsets.x or y")
349 (see hg help "revsets.x or y")
350 [255]
350 [255]
351 $ try '0,1,2'
351 $ try '0,1,2'
352 (list
352 (list
353 (symbol '0')
353 (symbol '0')
354 (symbol '1')
354 (symbol '1')
355 (symbol '2'))
355 (symbol '2'))
356 hg: parse error: can't use a list in this context
356 hg: parse error: can't use a list in this context
357 (see hg help "revsets.x or y")
357 (see hg help "revsets.x or y")
358 [255]
358 [255]
359
359
360 test that chained `or` operations make balanced addsets
360 test that chained `or` operations make balanced addsets
361
361
362 $ try '0:1|1:2|2:3|3:4|4:5'
362 $ try '0:1|1:2|2:3|3:4|4:5'
363 (or
363 (or
364 (list
364 (list
365 (range
365 (range
366 (symbol '0')
366 (symbol '0')
367 (symbol '1'))
367 (symbol '1'))
368 (range
368 (range
369 (symbol '1')
369 (symbol '1')
370 (symbol '2'))
370 (symbol '2'))
371 (range
371 (range
372 (symbol '2')
372 (symbol '2')
373 (symbol '3'))
373 (symbol '3'))
374 (range
374 (range
375 (symbol '3')
375 (symbol '3')
376 (symbol '4'))
376 (symbol '4'))
377 (range
377 (range
378 (symbol '4')
378 (symbol '4')
379 (symbol '5'))))
379 (symbol '5'))))
380 * set:
380 * set:
381 <addset
381 <addset
382 <addset
382 <addset
383 <spanset+ 0:2>,
383 <spanset+ 0:2>,
384 <spanset+ 1:3>>,
384 <spanset+ 1:3>>,
385 <addset
385 <addset
386 <spanset+ 2:4>,
386 <spanset+ 2:4>,
387 <addset
387 <addset
388 <spanset+ 3:5>,
388 <spanset+ 3:5>,
389 <spanset+ 4:6>>>>
389 <spanset+ 4:6>>>>
390 0
390 0
391 1
391 1
392 2
392 2
393 3
393 3
394 4
394 4
395 5
395 5
396
396
397 no crash by empty group "()" while optimizing `or` operations
397 no crash by empty group "()" while optimizing `or` operations
398
398
399 $ try --optimize '0|()'
399 $ try --optimize '0|()'
400 (or
400 (or
401 (list
401 (list
402 (symbol '0')
402 (symbol '0')
403 (group
403 (group
404 None)))
404 None)))
405 * optimized:
405 * optimized:
406 (or
406 (or
407 (list
407 (list
408 (symbol '0')
408 (symbol '0')
409 None))
409 None))
410 hg: parse error: missing argument
410 hg: parse error: missing argument
411 [255]
411 [255]
412
412
413 test that chained `or` operations never eat up stack (issue4624)
413 test that chained `or` operations never eat up stack (issue4624)
414 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
414 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
415
415
416 $ hg log -T '{rev}\n' -r `$PYTHON -c "print '+'.join(['0:1'] * 500)"`
416 $ hg log -T '{rev}\n' -r `$PYTHON -c "print '+'.join(['0:1'] * 500)"`
417 0
417 0
418 1
418 1
419
419
420 test that repeated `-r` options never eat up stack (issue4565)
420 test that repeated `-r` options never eat up stack (issue4565)
421 (uses `-r 0::1` to avoid possible optimization at old-style parser)
421 (uses `-r 0::1` to avoid possible optimization at old-style parser)
422
422
423 $ hg log -T '{rev}\n' `$PYTHON -c "for i in xrange(500): print '-r 0::1 ',"`
423 $ hg log -T '{rev}\n' `$PYTHON -c "for i in xrange(500): print '-r 0::1 ',"`
424 0
424 0
425 1
425 1
426
426
427 check that conversion to only works
427 check that conversion to only works
428 $ try --optimize '::3 - ::1'
428 $ try --optimize '::3 - ::1'
429 (minus
429 (minus
430 (dagrangepre
430 (dagrangepre
431 (symbol '3'))
431 (symbol '3'))
432 (dagrangepre
432 (dagrangepre
433 (symbol '1')))
433 (symbol '1')))
434 * optimized:
434 * optimized:
435 (func
435 (func
436 (symbol 'only')
436 (symbol 'only')
437 (list
437 (list
438 (symbol '3')
438 (symbol '3')
439 (symbol '1')))
439 (symbol '1')))
440 * set:
440 * set:
441 <baseset+ [3]>
441 <baseset+ [3]>
442 3
442 3
443 $ try --optimize 'ancestors(1) - ancestors(3)'
443 $ try --optimize 'ancestors(1) - ancestors(3)'
444 (minus
444 (minus
445 (func
445 (func
446 (symbol 'ancestors')
446 (symbol 'ancestors')
447 (symbol '1'))
447 (symbol '1'))
448 (func
448 (func
449 (symbol 'ancestors')
449 (symbol 'ancestors')
450 (symbol '3')))
450 (symbol '3')))
451 * optimized:
451 * optimized:
452 (func
452 (func
453 (symbol 'only')
453 (symbol 'only')
454 (list
454 (list
455 (symbol '1')
455 (symbol '1')
456 (symbol '3')))
456 (symbol '3')))
457 * set:
457 * set:
458 <baseset+ []>
458 <baseset+ []>
459 $ try --optimize 'not ::2 and ::6'
459 $ try --optimize 'not ::2 and ::6'
460 (and
460 (and
461 (not
461 (not
462 (dagrangepre
462 (dagrangepre
463 (symbol '2')))
463 (symbol '2')))
464 (dagrangepre
464 (dagrangepre
465 (symbol '6')))
465 (symbol '6')))
466 * optimized:
466 * optimized:
467 (func
467 (func
468 (symbol 'only')
468 (symbol 'only')
469 (list
469 (list
470 (symbol '6')
470 (symbol '6')
471 (symbol '2')))
471 (symbol '2')))
472 * set:
472 * set:
473 <baseset+ [3, 4, 5, 6]>
473 <baseset+ [3, 4, 5, 6]>
474 3
474 3
475 4
475 4
476 5
476 5
477 6
477 6
478 $ try --optimize 'ancestors(6) and not ancestors(4)'
478 $ try --optimize 'ancestors(6) and not ancestors(4)'
479 (and
479 (and
480 (func
480 (func
481 (symbol 'ancestors')
481 (symbol 'ancestors')
482 (symbol '6'))
482 (symbol '6'))
483 (not
483 (not
484 (func
484 (func
485 (symbol 'ancestors')
485 (symbol 'ancestors')
486 (symbol '4'))))
486 (symbol '4'))))
487 * optimized:
487 * optimized:
488 (func
488 (func
489 (symbol 'only')
489 (symbol 'only')
490 (list
490 (list
491 (symbol '6')
491 (symbol '6')
492 (symbol '4')))
492 (symbol '4')))
493 * set:
493 * set:
494 <baseset+ [3, 5, 6]>
494 <baseset+ [3, 5, 6]>
495 3
495 3
496 5
496 5
497 6
497 6
498
498
499 no crash by empty group "()" while optimizing to "only()"
499 no crash by empty group "()" while optimizing to "only()"
500
500
501 $ try --optimize '::1 and ()'
501 $ try --optimize '::1 and ()'
502 (and
502 (and
503 (dagrangepre
503 (dagrangepre
504 (symbol '1'))
504 (symbol '1'))
505 (group
505 (group
506 None))
506 None))
507 * optimized:
507 * optimized:
508 (andsmally
508 (andsmally
509 (func
509 (func
510 (symbol 'ancestors')
510 (symbol 'ancestors')
511 (symbol '1'))
511 (symbol '1'))
512 None)
512 None)
513 hg: parse error: missing argument
513 hg: parse error: missing argument
514 [255]
514 [255]
515
515
516 optimization to only() works only if ancestors() takes only one argument
516 optimization to only() works only if ancestors() takes only one argument
517
517
518 $ hg debugrevspec -p optimized 'ancestors(6) - ancestors(4, 1)'
518 $ hg debugrevspec -p optimized 'ancestors(6) - ancestors(4, 1)'
519 * optimized:
519 * optimized:
520 (difference
520 (difference
521 (func
521 (func
522 (symbol 'ancestors')
522 (symbol 'ancestors')
523 (symbol '6'))
523 (symbol '6'))
524 (func
524 (func
525 (symbol 'ancestors')
525 (symbol 'ancestors')
526 (list
526 (list
527 (symbol '4')
527 (symbol '4')
528 (symbol '1'))))
528 (symbol '1'))))
529 0
529 0
530 1
530 1
531 3
531 3
532 5
532 5
533 6
533 6
534 $ hg debugrevspec -p optimized 'ancestors(6, 1) - ancestors(4)'
534 $ hg debugrevspec -p optimized 'ancestors(6, 1) - ancestors(4)'
535 * optimized:
535 * optimized:
536 (difference
536 (difference
537 (func
537 (func
538 (symbol 'ancestors')
538 (symbol 'ancestors')
539 (list
539 (list
540 (symbol '6')
540 (symbol '6')
541 (symbol '1')))
541 (symbol '1')))
542 (func
542 (func
543 (symbol 'ancestors')
543 (symbol 'ancestors')
544 (symbol '4')))
544 (symbol '4')))
545 5
545 5
546 6
546 6
547
547
548 optimization disabled if keyword arguments passed (because we're too lazy
548 optimization disabled if keyword arguments passed (because we're too lazy
549 to support it)
549 to support it)
550
550
551 $ hg debugrevspec -p optimized 'ancestors(set=6) - ancestors(set=4)'
551 $ hg debugrevspec -p optimized 'ancestors(set=6) - ancestors(set=4)'
552 * optimized:
552 * optimized:
553 (difference
553 (difference
554 (func
554 (func
555 (symbol 'ancestors')
555 (symbol 'ancestors')
556 (keyvalue
556 (keyvalue
557 (symbol 'set')
557 (symbol 'set')
558 (symbol '6')))
558 (symbol '6')))
559 (func
559 (func
560 (symbol 'ancestors')
560 (symbol 'ancestors')
561 (keyvalue
561 (keyvalue
562 (symbol 'set')
562 (symbol 'set')
563 (symbol '4'))))
563 (symbol '4'))))
564 3
564 3
565 5
565 5
566 6
566 6
567
567
568 invalid function call should not be optimized to only()
568 invalid function call should not be optimized to only()
569
569
570 $ log '"ancestors"(6) and not ancestors(4)'
570 $ log '"ancestors"(6) and not ancestors(4)'
571 hg: parse error: not a symbol
571 hg: parse error: not a symbol
572 [255]
572 [255]
573
573
574 $ log 'ancestors(6) and not "ancestors"(4)'
574 $ log 'ancestors(6) and not "ancestors"(4)'
575 hg: parse error: not a symbol
575 hg: parse error: not a symbol
576 [255]
576 [255]
577
577
578 we can use patterns when searching for tags
578 we can use patterns when searching for tags
579
579
580 $ log 'tag("1..*")'
580 $ log 'tag("1..*")'
581 abort: tag '1..*' does not exist!
581 abort: tag '1..*' does not exist!
582 [255]
582 [255]
583 $ log 'tag("re:1..*")'
583 $ log 'tag("re:1..*")'
584 6
584 6
585 $ log 'tag("re:[0-9].[0-9]")'
585 $ log 'tag("re:[0-9].[0-9]")'
586 6
586 6
587 $ log 'tag("literal:1.0")'
587 $ log 'tag("literal:1.0")'
588 6
588 6
589 $ log 'tag("re:0..*")'
589 $ log 'tag("re:0..*")'
590
590
591 $ log 'tag(unknown)'
591 $ log 'tag(unknown)'
592 abort: tag 'unknown' does not exist!
592 abort: tag 'unknown' does not exist!
593 [255]
593 [255]
594 $ log 'tag("re:unknown")'
594 $ log 'tag("re:unknown")'
595 $ log 'present(tag("unknown"))'
595 $ log 'present(tag("unknown"))'
596 $ log 'present(tag("re:unknown"))'
596 $ log 'present(tag("re:unknown"))'
597 $ log 'branch(unknown)'
597 $ log 'branch(unknown)'
598 abort: unknown revision 'unknown'!
598 abort: unknown revision 'unknown'!
599 [255]
599 [255]
600 $ log 'branch("literal:unknown")'
600 $ log 'branch("literal:unknown")'
601 abort: branch 'unknown' does not exist!
601 abort: branch 'unknown' does not exist!
602 [255]
602 [255]
603 $ log 'branch("re:unknown")'
603 $ log 'branch("re:unknown")'
604 $ log 'present(branch("unknown"))'
604 $ log 'present(branch("unknown"))'
605 $ log 'present(branch("re:unknown"))'
605 $ log 'present(branch("re:unknown"))'
606 $ log 'user(bob)'
606 $ log 'user(bob)'
607 2
607 2
608
608
609 $ log '4::8'
609 $ log '4::8'
610 4
610 4
611 8
611 8
612 $ log '4:8'
612 $ log '4:8'
613 4
613 4
614 5
614 5
615 6
615 6
616 7
616 7
617 8
617 8
618
618
619 $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
619 $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
620 4
620 4
621 2
621 2
622 5
622 5
623
623
624 $ log 'not 0 and 0:2'
624 $ log 'not 0 and 0:2'
625 1
625 1
626 2
626 2
627 $ log 'not 1 and 0:2'
627 $ log 'not 1 and 0:2'
628 0
628 0
629 2
629 2
630 $ log 'not 2 and 0:2'
630 $ log 'not 2 and 0:2'
631 0
631 0
632 1
632 1
633 $ log '(1 and 2)::'
633 $ log '(1 and 2)::'
634 $ log '(1 and 2):'
634 $ log '(1 and 2):'
635 $ log '(1 and 2):3'
635 $ log '(1 and 2):3'
636 $ log 'sort(head(), -rev)'
636 $ log 'sort(head(), -rev)'
637 9
637 9
638 7
638 7
639 6
639 6
640 5
640 5
641 4
641 4
642 3
642 3
643 2
643 2
644 1
644 1
645 0
645 0
646 $ log '4::8 - 8'
646 $ log '4::8 - 8'
647 4
647 4
648
648
649 matching() should preserve the order of the input set:
649 matching() should preserve the order of the input set:
650
650
651 $ log '(2 or 3 or 1) and matching(1 or 2 or 3)'
651 $ log '(2 or 3 or 1) and matching(1 or 2 or 3)'
652 2
652 2
653 3
653 3
654 1
654 1
655
655
656 $ log 'named("unknown")'
656 $ log 'named("unknown")'
657 abort: namespace 'unknown' does not exist!
657 abort: namespace 'unknown' does not exist!
658 [255]
658 [255]
659 $ log 'named("re:unknown")'
659 $ log 'named("re:unknown")'
660 abort: no namespace exists that match 'unknown'!
660 abort: no namespace exists that match 'unknown'!
661 [255]
661 [255]
662 $ log 'present(named("unknown"))'
662 $ log 'present(named("unknown"))'
663 $ log 'present(named("re:unknown"))'
663 $ log 'present(named("re:unknown"))'
664
664
665 $ log 'tag()'
665 $ log 'tag()'
666 6
666 6
667 $ log 'named("tags")'
667 $ log 'named("tags")'
668 6
668 6
669
669
670 issue2437
670 issue2437
671
671
672 $ log '3 and p1(5)'
672 $ log '3 and p1(5)'
673 3
673 3
674 $ log '4 and p2(6)'
674 $ log '4 and p2(6)'
675 4
675 4
676 $ log '1 and parents(:2)'
676 $ log '1 and parents(:2)'
677 1
677 1
678 $ log '2 and children(1:)'
678 $ log '2 and children(1:)'
679 2
679 2
680 $ log 'roots(all()) or roots(all())'
680 $ log 'roots(all()) or roots(all())'
681 0
681 0
682 $ hg debugrevspec 'roots(all()) or roots(all())'
682 $ hg debugrevspec 'roots(all()) or roots(all())'
683 0
683 0
684 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
684 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
685 9
685 9
686 $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(Γ©)))'
686 $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(Γ©)))'
687 4
687 4
688
688
689 issue2654: report a parse error if the revset was not completely parsed
689 issue2654: report a parse error if the revset was not completely parsed
690
690
691 $ log '1 OR 2'
691 $ log '1 OR 2'
692 hg: parse error at 2: invalid token
692 hg: parse error at 2: invalid token
693 [255]
693 [255]
694
694
695 or operator should preserve ordering:
695 or operator should preserve ordering:
696 $ log 'reverse(2::4) or tip'
696 $ log 'reverse(2::4) or tip'
697 4
697 4
698 2
698 2
699 9
699 9
700
700
701 parentrevspec
701 parentrevspec
702
702
703 $ log 'merge()^0'
703 $ log 'merge()^0'
704 6
704 6
705 $ log 'merge()^'
705 $ log 'merge()^'
706 5
706 5
707 $ log 'merge()^1'
707 $ log 'merge()^1'
708 5
708 5
709 $ log 'merge()^2'
709 $ log 'merge()^2'
710 4
710 4
711 $ log '(not merge())^2'
711 $ log '(not merge())^2'
712 $ log 'merge()^^'
712 $ log 'merge()^^'
713 3
713 3
714 $ log 'merge()^1^'
714 $ log 'merge()^1^'
715 3
715 3
716 $ log 'merge()^^^'
716 $ log 'merge()^^^'
717 1
717 1
718
718
719 $ hg debugrevspec -s '(merge() | 0)~-1'
719 $ hg debugrevspec -s '(merge() | 0)~-1'
720 * set:
720 * set:
721 <baseset+ [1, 7]>
721 <baseset+ [1, 7]>
722 1
722 1
723 7
723 7
724 $ log 'merge()~-1'
724 $ log 'merge()~-1'
725 7
725 7
726 $ log 'tip~-1'
726 $ log 'tip~-1'
727 $ log '(tip | merge())~-1'
727 $ log '(tip | merge())~-1'
728 7
728 7
729 $ log 'merge()~0'
729 $ log 'merge()~0'
730 6
730 6
731 $ log 'merge()~1'
731 $ log 'merge()~1'
732 5
732 5
733 $ log 'merge()~2'
733 $ log 'merge()~2'
734 3
734 3
735 $ log 'merge()~2^1'
735 $ log 'merge()~2^1'
736 1
736 1
737 $ log 'merge()~3'
737 $ log 'merge()~3'
738 1
738 1
739
739
740 $ log '(-3:tip)^'
740 $ log '(-3:tip)^'
741 4
741 4
742 6
742 6
743 8
743 8
744
744
745 $ log 'tip^foo'
745 $ log 'tip^foo'
746 hg: parse error: ^ expects a number 0, 1, or 2
746 hg: parse error: ^ expects a number 0, 1, or 2
747 [255]
747 [255]
748
748
749 $ log 'branchpoint()~-1'
749 $ log 'branchpoint()~-1'
750 abort: revision in set has more than one child!
750 abort: revision in set has more than one child!
751 [255]
751 [255]
752
752
753 Bogus function gets suggestions
753 Bogus function gets suggestions
754 $ log 'add()'
754 $ log 'add()'
755 hg: parse error: unknown identifier: add
755 hg: parse error: unknown identifier: add
756 (did you mean adds?)
756 (did you mean adds?)
757 [255]
757 [255]
758 $ log 'added()'
758 $ log 'added()'
759 hg: parse error: unknown identifier: added
759 hg: parse error: unknown identifier: added
760 (did you mean adds?)
760 (did you mean adds?)
761 [255]
761 [255]
762 $ log 'remo()'
762 $ log 'remo()'
763 hg: parse error: unknown identifier: remo
763 hg: parse error: unknown identifier: remo
764 (did you mean one of remote, removes?)
764 (did you mean one of remote, removes?)
765 [255]
765 [255]
766 $ log 'babar()'
766 $ log 'babar()'
767 hg: parse error: unknown identifier: babar
767 hg: parse error: unknown identifier: babar
768 [255]
768 [255]
769
769
770 Bogus function with a similar internal name doesn't suggest the internal name
770 Bogus function with a similar internal name doesn't suggest the internal name
771 $ log 'matches()'
771 $ log 'matches()'
772 hg: parse error: unknown identifier: matches
772 hg: parse error: unknown identifier: matches
773 (did you mean matching?)
773 (did you mean matching?)
774 [255]
774 [255]
775
775
776 Undocumented functions aren't suggested as similar either
776 Undocumented functions aren't suggested as similar either
777 $ log 'tagged2()'
777 $ log 'tagged2()'
778 hg: parse error: unknown identifier: tagged2
778 hg: parse error: unknown identifier: tagged2
779 [255]
779 [255]
780
780
781 multiple revspecs
781 multiple revspecs
782
782
783 $ hg log -r 'tip~1:tip' -r 'tip~2:tip~1' --template '{rev}\n'
783 $ hg log -r 'tip~1:tip' -r 'tip~2:tip~1' --template '{rev}\n'
784 8
784 8
785 9
785 9
786 4
786 4
787 5
787 5
788 6
788 6
789 7
789 7
790
790
791 test usage in revpair (with "+")
791 test usage in revpair (with "+")
792
792
793 (real pair)
793 (real pair)
794
794
795 $ hg diff -r 'tip^^' -r 'tip'
795 $ hg diff -r 'tip^^' -r 'tip'
796 diff -r 2326846efdab -r 24286f4ae135 .hgtags
796 diff -r 2326846efdab -r 24286f4ae135 .hgtags
797 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
797 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
798 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
798 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
799 @@ -0,0 +1,1 @@
799 @@ -0,0 +1,1 @@
800 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
800 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
801 $ hg diff -r 'tip^^::tip'
801 $ hg diff -r 'tip^^::tip'
802 diff -r 2326846efdab -r 24286f4ae135 .hgtags
802 diff -r 2326846efdab -r 24286f4ae135 .hgtags
803 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
803 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
804 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
804 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
805 @@ -0,0 +1,1 @@
805 @@ -0,0 +1,1 @@
806 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
806 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
807
807
808 (single rev)
808 (single rev)
809
809
810 $ hg diff -r 'tip^' -r 'tip^'
810 $ hg diff -r 'tip^' -r 'tip^'
811 $ hg diff -r 'tip^:tip^'
811 $ hg diff -r 'tip^:tip^'
812
812
813 (single rev that does not looks like a range)
813 (single rev that does not looks like a range)
814
814
815 $ hg diff -r 'tip^::tip^ or tip^'
815 $ hg diff -r 'tip^::tip^ or tip^'
816 diff -r d5d0dcbdc4d9 .hgtags
816 diff -r d5d0dcbdc4d9 .hgtags
817 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
817 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
818 +++ b/.hgtags * (glob)
818 +++ b/.hgtags * (glob)
819 @@ -0,0 +1,1 @@
819 @@ -0,0 +1,1 @@
820 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
820 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
821 $ hg diff -r 'tip^ or tip^'
821 $ hg diff -r 'tip^ or tip^'
822 diff -r d5d0dcbdc4d9 .hgtags
822 diff -r d5d0dcbdc4d9 .hgtags
823 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
823 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
824 +++ b/.hgtags * (glob)
824 +++ b/.hgtags * (glob)
825 @@ -0,0 +1,1 @@
825 @@ -0,0 +1,1 @@
826 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
826 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
827
827
828 (no rev)
828 (no rev)
829
829
830 $ hg diff -r 'author("babar") or author("celeste")'
830 $ hg diff -r 'author("babar") or author("celeste")'
831 abort: empty revision range
831 abort: empty revision range
832 [255]
832 [255]
833
833
834 aliases:
834 aliases:
835
835
836 $ echo '[revsetalias]' >> .hg/hgrc
836 $ echo '[revsetalias]' >> .hg/hgrc
837 $ echo 'm = merge()' >> .hg/hgrc
837 $ echo 'm = merge()' >> .hg/hgrc
838 (revset aliases can override builtin revsets)
838 (revset aliases can override builtin revsets)
839 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
839 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
840 $ echo 'sincem = descendants(m)' >> .hg/hgrc
840 $ echo 'sincem = descendants(m)' >> .hg/hgrc
841 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
841 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
842 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
842 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
843 $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
843 $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
844
844
845 $ try m
845 $ try m
846 (symbol 'm')
846 (symbol 'm')
847 * expanded:
847 * expanded:
848 (func
848 (func
849 (symbol 'merge')
849 (symbol 'merge')
850 None)
850 None)
851 * set:
851 * set:
852 <filteredset
852 <filteredset
853 <fullreposet+ 0:10>,
853 <fullreposet+ 0:10>,
854 <merge>>
854 <merge>>
855 6
855 6
856
856
857 $ HGPLAIN=1
857 $ HGPLAIN=1
858 $ export HGPLAIN
858 $ export HGPLAIN
859 $ try m
859 $ try m
860 (symbol 'm')
860 (symbol 'm')
861 abort: unknown revision 'm'!
861 abort: unknown revision 'm'!
862 [255]
862 [255]
863
863
864 $ HGPLAINEXCEPT=revsetalias
864 $ HGPLAINEXCEPT=revsetalias
865 $ export HGPLAINEXCEPT
865 $ export HGPLAINEXCEPT
866 $ try m
866 $ try m
867 (symbol 'm')
867 (symbol 'm')
868 * expanded:
868 * expanded:
869 (func
869 (func
870 (symbol 'merge')
870 (symbol 'merge')
871 None)
871 None)
872 * set:
872 * set:
873 <filteredset
873 <filteredset
874 <fullreposet+ 0:10>,
874 <fullreposet+ 0:10>,
875 <merge>>
875 <merge>>
876 6
876 6
877
877
878 $ unset HGPLAIN
878 $ unset HGPLAIN
879 $ unset HGPLAINEXCEPT
879 $ unset HGPLAINEXCEPT
880
880
881 $ try 'p2(.)'
881 $ try 'p2(.)'
882 (func
882 (func
883 (symbol 'p2')
883 (symbol 'p2')
884 (symbol '.'))
884 (symbol '.'))
885 * expanded:
885 * expanded:
886 (func
886 (func
887 (symbol 'p1')
887 (symbol 'p1')
888 (symbol '.'))
888 (symbol '.'))
889 * set:
889 * set:
890 <baseset+ [8]>
890 <baseset+ [8]>
891 8
891 8
892
892
893 $ HGPLAIN=1
893 $ HGPLAIN=1
894 $ export HGPLAIN
894 $ export HGPLAIN
895 $ try 'p2(.)'
895 $ try 'p2(.)'
896 (func
896 (func
897 (symbol 'p2')
897 (symbol 'p2')
898 (symbol '.'))
898 (symbol '.'))
899 * set:
899 * set:
900 <baseset+ []>
900 <baseset+ []>
901
901
902 $ HGPLAINEXCEPT=revsetalias
902 $ HGPLAINEXCEPT=revsetalias
903 $ export HGPLAINEXCEPT
903 $ export HGPLAINEXCEPT
904 $ try 'p2(.)'
904 $ try 'p2(.)'
905 (func
905 (func
906 (symbol 'p2')
906 (symbol 'p2')
907 (symbol '.'))
907 (symbol '.'))
908 * expanded:
908 * expanded:
909 (func
909 (func
910 (symbol 'p1')
910 (symbol 'p1')
911 (symbol '.'))
911 (symbol '.'))
912 * set:
912 * set:
913 <baseset+ [8]>
913 <baseset+ [8]>
914 8
914 8
915
915
916 $ unset HGPLAIN
916 $ unset HGPLAIN
917 $ unset HGPLAINEXCEPT
917 $ unset HGPLAINEXCEPT
918
918
919 test alias recursion
919 test alias recursion
920
920
921 $ try sincem
921 $ try sincem
922 (symbol 'sincem')
922 (symbol 'sincem')
923 * expanded:
923 * expanded:
924 (func
924 (func
925 (symbol 'descendants')
925 (symbol 'descendants')
926 (func
926 (func
927 (symbol 'merge')
927 (symbol 'merge')
928 None))
928 None))
929 * set:
929 * set:
930 <generatorset+>
930 <generatorsetasc+>
931 6
931 6
932 7
932 7
933
933
934 test infinite recursion
934 test infinite recursion
935
935
936 $ echo 'recurse1 = recurse2' >> .hg/hgrc
936 $ echo 'recurse1 = recurse2' >> .hg/hgrc
937 $ echo 'recurse2 = recurse1' >> .hg/hgrc
937 $ echo 'recurse2 = recurse1' >> .hg/hgrc
938 $ try recurse1
938 $ try recurse1
939 (symbol 'recurse1')
939 (symbol 'recurse1')
940 hg: parse error: infinite expansion of revset alias "recurse1" detected
940 hg: parse error: infinite expansion of revset alias "recurse1" detected
941 [255]
941 [255]
942
942
943 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
943 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
944 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
944 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
945 $ try "level2(level1(1, 2), 3)"
945 $ try "level2(level1(1, 2), 3)"
946 (func
946 (func
947 (symbol 'level2')
947 (symbol 'level2')
948 (list
948 (list
949 (func
949 (func
950 (symbol 'level1')
950 (symbol 'level1')
951 (list
951 (list
952 (symbol '1')
952 (symbol '1')
953 (symbol '2')))
953 (symbol '2')))
954 (symbol '3')))
954 (symbol '3')))
955 * expanded:
955 * expanded:
956 (or
956 (or
957 (list
957 (list
958 (symbol '3')
958 (symbol '3')
959 (or
959 (or
960 (list
960 (list
961 (symbol '1')
961 (symbol '1')
962 (symbol '2')))))
962 (symbol '2')))))
963 * set:
963 * set:
964 <addset
964 <addset
965 <baseset [3]>,
965 <baseset [3]>,
966 <baseset [1, 2]>>
966 <baseset [1, 2]>>
967 3
967 3
968 1
968 1
969 2
969 2
970
970
971 test nesting and variable passing
971 test nesting and variable passing
972
972
973 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
973 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
974 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
974 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
975 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
975 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
976 $ try 'nested(2:5)'
976 $ try 'nested(2:5)'
977 (func
977 (func
978 (symbol 'nested')
978 (symbol 'nested')
979 (range
979 (range
980 (symbol '2')
980 (symbol '2')
981 (symbol '5')))
981 (symbol '5')))
982 * expanded:
982 * expanded:
983 (func
983 (func
984 (symbol 'max')
984 (symbol 'max')
985 (range
985 (range
986 (symbol '2')
986 (symbol '2')
987 (symbol '5')))
987 (symbol '5')))
988 * set:
988 * set:
989 <baseset
989 <baseset
990 <max
990 <max
991 <fullreposet+ 0:10>,
991 <fullreposet+ 0:10>,
992 <spanset+ 2:6>>>
992 <spanset+ 2:6>>>
993 5
993 5
994
994
995 test chained `or` operations are flattened at parsing phase
995 test chained `or` operations are flattened at parsing phase
996
996
997 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
997 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
998 $ try 'chainedorops(0:1, 1:2, 2:3)'
998 $ try 'chainedorops(0:1, 1:2, 2:3)'
999 (func
999 (func
1000 (symbol 'chainedorops')
1000 (symbol 'chainedorops')
1001 (list
1001 (list
1002 (range
1002 (range
1003 (symbol '0')
1003 (symbol '0')
1004 (symbol '1'))
1004 (symbol '1'))
1005 (range
1005 (range
1006 (symbol '1')
1006 (symbol '1')
1007 (symbol '2'))
1007 (symbol '2'))
1008 (range
1008 (range
1009 (symbol '2')
1009 (symbol '2')
1010 (symbol '3'))))
1010 (symbol '3'))))
1011 * expanded:
1011 * expanded:
1012 (or
1012 (or
1013 (list
1013 (list
1014 (range
1014 (range
1015 (symbol '0')
1015 (symbol '0')
1016 (symbol '1'))
1016 (symbol '1'))
1017 (range
1017 (range
1018 (symbol '1')
1018 (symbol '1')
1019 (symbol '2'))
1019 (symbol '2'))
1020 (range
1020 (range
1021 (symbol '2')
1021 (symbol '2')
1022 (symbol '3'))))
1022 (symbol '3'))))
1023 * set:
1023 * set:
1024 <addset
1024 <addset
1025 <spanset+ 0:2>,
1025 <spanset+ 0:2>,
1026 <addset
1026 <addset
1027 <spanset+ 1:3>,
1027 <spanset+ 1:3>,
1028 <spanset+ 2:4>>>
1028 <spanset+ 2:4>>>
1029 0
1029 0
1030 1
1030 1
1031 2
1031 2
1032 3
1032 3
1033
1033
1034 test variable isolation, variable placeholders are rewritten as string
1034 test variable isolation, variable placeholders are rewritten as string
1035 then parsed and matched again as string. Check they do not leak too
1035 then parsed and matched again as string. Check they do not leak too
1036 far away.
1036 far away.
1037
1037
1038 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
1038 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
1039 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
1039 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
1040 $ try 'callinjection(2:5)'
1040 $ try 'callinjection(2:5)'
1041 (func
1041 (func
1042 (symbol 'callinjection')
1042 (symbol 'callinjection')
1043 (range
1043 (range
1044 (symbol '2')
1044 (symbol '2')
1045 (symbol '5')))
1045 (symbol '5')))
1046 * expanded:
1046 * expanded:
1047 (func
1047 (func
1048 (symbol 'descendants')
1048 (symbol 'descendants')
1049 (func
1049 (func
1050 (symbol 'max')
1050 (symbol 'max')
1051 (string '$1')))
1051 (string '$1')))
1052 abort: unknown revision '$1'!
1052 abort: unknown revision '$1'!
1053 [255]
1053 [255]
1054
1054
1055 test scope of alias expansion: 'universe' is expanded prior to 'shadowall(0)',
1055 test scope of alias expansion: 'universe' is expanded prior to 'shadowall(0)',
1056 but 'all()' should never be substituted to '0()'.
1056 but 'all()' should never be substituted to '0()'.
1057
1057
1058 $ echo 'universe = all()' >> .hg/hgrc
1058 $ echo 'universe = all()' >> .hg/hgrc
1059 $ echo 'shadowall(all) = all and universe' >> .hg/hgrc
1059 $ echo 'shadowall(all) = all and universe' >> .hg/hgrc
1060 $ try 'shadowall(0)'
1060 $ try 'shadowall(0)'
1061 (func
1061 (func
1062 (symbol 'shadowall')
1062 (symbol 'shadowall')
1063 (symbol '0'))
1063 (symbol '0'))
1064 * expanded:
1064 * expanded:
1065 (and
1065 (and
1066 (symbol '0')
1066 (symbol '0')
1067 (func
1067 (func
1068 (symbol 'all')
1068 (symbol 'all')
1069 None))
1069 None))
1070 * set:
1070 * set:
1071 <filteredset
1071 <filteredset
1072 <baseset [0]>,
1072 <baseset [0]>,
1073 <spanset+ 0:10>>
1073 <spanset+ 0:10>>
1074 0
1074 0
1075
1075
1076 test unknown reference:
1076 test unknown reference:
1077
1077
1078 $ try "unknownref(0)" --config 'revsetalias.unknownref($1)=$1:$2'
1078 $ try "unknownref(0)" --config 'revsetalias.unknownref($1)=$1:$2'
1079 (func
1079 (func
1080 (symbol 'unknownref')
1080 (symbol 'unknownref')
1081 (symbol '0'))
1081 (symbol '0'))
1082 abort: bad definition of revset alias "unknownref": invalid symbol '$2'
1082 abort: bad definition of revset alias "unknownref": invalid symbol '$2'
1083 [255]
1083 [255]
1084
1084
1085 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
1085 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
1086 (symbol 'tip')
1086 (symbol 'tip')
1087 warning: bad definition of revset alias "anotherbadone": at 7: not a prefix: end
1087 warning: bad definition of revset alias "anotherbadone": at 7: not a prefix: end
1088 * set:
1088 * set:
1089 <baseset [9]>
1089 <baseset [9]>
1090 9
1090 9
1091
1091
1092 $ try 'tip'
1092 $ try 'tip'
1093 (symbol 'tip')
1093 (symbol 'tip')
1094 * set:
1094 * set:
1095 <baseset [9]>
1095 <baseset [9]>
1096 9
1096 9
1097
1097
1098 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
1098 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
1099 (symbol 'tip')
1099 (symbol 'tip')
1100 warning: bad declaration of revset alias "bad name": at 4: invalid token
1100 warning: bad declaration of revset alias "bad name": at 4: invalid token
1101 * set:
1101 * set:
1102 <baseset [9]>
1102 <baseset [9]>
1103 9
1103 9
1104 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
1104 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
1105 $ try 'strictreplacing("foo", tip)'
1105 $ try 'strictreplacing("foo", tip)'
1106 (func
1106 (func
1107 (symbol 'strictreplacing')
1107 (symbol 'strictreplacing')
1108 (list
1108 (list
1109 (string 'foo')
1109 (string 'foo')
1110 (symbol 'tip')))
1110 (symbol 'tip')))
1111 * expanded:
1111 * expanded:
1112 (or
1112 (or
1113 (list
1113 (list
1114 (symbol 'tip')
1114 (symbol 'tip')
1115 (func
1115 (func
1116 (symbol 'desc')
1116 (symbol 'desc')
1117 (string '$1'))))
1117 (string '$1'))))
1118 * set:
1118 * set:
1119 <addset
1119 <addset
1120 <baseset [9]>,
1120 <baseset [9]>,
1121 <filteredset
1121 <filteredset
1122 <fullreposet+ 0:10>,
1122 <fullreposet+ 0:10>,
1123 <desc '$1'>>>
1123 <desc '$1'>>>
1124 9
1124 9
1125
1125
1126 $ try 'd(2:5)'
1126 $ try 'd(2:5)'
1127 (func
1127 (func
1128 (symbol 'd')
1128 (symbol 'd')
1129 (range
1129 (range
1130 (symbol '2')
1130 (symbol '2')
1131 (symbol '5')))
1131 (symbol '5')))
1132 * expanded:
1132 * expanded:
1133 (func
1133 (func
1134 (symbol 'reverse')
1134 (symbol 'reverse')
1135 (func
1135 (func
1136 (symbol 'sort')
1136 (symbol 'sort')
1137 (list
1137 (list
1138 (range
1138 (range
1139 (symbol '2')
1139 (symbol '2')
1140 (symbol '5'))
1140 (symbol '5'))
1141 (symbol 'date'))))
1141 (symbol 'date'))))
1142 * set:
1142 * set:
1143 <baseset [4, 5, 3, 2]>
1143 <baseset [4, 5, 3, 2]>
1144 4
1144 4
1145 5
1145 5
1146 3
1146 3
1147 2
1147 2
1148 $ try 'rs(2 or 3, date)'
1148 $ try 'rs(2 or 3, date)'
1149 (func
1149 (func
1150 (symbol 'rs')
1150 (symbol 'rs')
1151 (list
1151 (list
1152 (or
1152 (or
1153 (list
1153 (list
1154 (symbol '2')
1154 (symbol '2')
1155 (symbol '3')))
1155 (symbol '3')))
1156 (symbol 'date')))
1156 (symbol 'date')))
1157 * expanded:
1157 * expanded:
1158 (func
1158 (func
1159 (symbol 'reverse')
1159 (symbol 'reverse')
1160 (func
1160 (func
1161 (symbol 'sort')
1161 (symbol 'sort')
1162 (list
1162 (list
1163 (or
1163 (or
1164 (list
1164 (list
1165 (symbol '2')
1165 (symbol '2')
1166 (symbol '3')))
1166 (symbol '3')))
1167 (symbol 'date'))))
1167 (symbol 'date'))))
1168 * set:
1168 * set:
1169 <baseset [3, 2]>
1169 <baseset [3, 2]>
1170 3
1170 3
1171 2
1171 2
1172 $ try 'rs()'
1172 $ try 'rs()'
1173 (func
1173 (func
1174 (symbol 'rs')
1174 (symbol 'rs')
1175 None)
1175 None)
1176 hg: parse error: invalid number of arguments: 0
1176 hg: parse error: invalid number of arguments: 0
1177 [255]
1177 [255]
1178 $ try 'rs(2)'
1178 $ try 'rs(2)'
1179 (func
1179 (func
1180 (symbol 'rs')
1180 (symbol 'rs')
1181 (symbol '2'))
1181 (symbol '2'))
1182 hg: parse error: invalid number of arguments: 1
1182 hg: parse error: invalid number of arguments: 1
1183 [255]
1183 [255]
1184 $ try 'rs(2, data, 7)'
1184 $ try 'rs(2, data, 7)'
1185 (func
1185 (func
1186 (symbol 'rs')
1186 (symbol 'rs')
1187 (list
1187 (list
1188 (symbol '2')
1188 (symbol '2')
1189 (symbol 'data')
1189 (symbol 'data')
1190 (symbol '7')))
1190 (symbol '7')))
1191 hg: parse error: invalid number of arguments: 3
1191 hg: parse error: invalid number of arguments: 3
1192 [255]
1192 [255]
1193 $ try 'rs4(2 or 3, x, x, date)'
1193 $ try 'rs4(2 or 3, x, x, date)'
1194 (func
1194 (func
1195 (symbol 'rs4')
1195 (symbol 'rs4')
1196 (list
1196 (list
1197 (or
1197 (or
1198 (list
1198 (list
1199 (symbol '2')
1199 (symbol '2')
1200 (symbol '3')))
1200 (symbol '3')))
1201 (symbol 'x')
1201 (symbol 'x')
1202 (symbol 'x')
1202 (symbol 'x')
1203 (symbol 'date')))
1203 (symbol 'date')))
1204 * expanded:
1204 * expanded:
1205 (func
1205 (func
1206 (symbol 'reverse')
1206 (symbol 'reverse')
1207 (func
1207 (func
1208 (symbol 'sort')
1208 (symbol 'sort')
1209 (list
1209 (list
1210 (or
1210 (or
1211 (list
1211 (list
1212 (symbol '2')
1212 (symbol '2')
1213 (symbol '3')))
1213 (symbol '3')))
1214 (symbol 'date'))))
1214 (symbol 'date'))))
1215 * set:
1215 * set:
1216 <baseset [3, 2]>
1216 <baseset [3, 2]>
1217 3
1217 3
1218 2
1218 2
1219
1219
1220 issue4553: check that revset aliases override existing hash prefix
1220 issue4553: check that revset aliases override existing hash prefix
1221
1221
1222 $ hg log -qr e
1222 $ hg log -qr e
1223 6:e0cc66ef77e8
1223 6:e0cc66ef77e8
1224
1224
1225 $ hg log -qr e --config revsetalias.e="all()"
1225 $ hg log -qr e --config revsetalias.e="all()"
1226 0:2785f51eece5
1226 0:2785f51eece5
1227 1:d75937da8da0
1227 1:d75937da8da0
1228 2:5ed5505e9f1c
1228 2:5ed5505e9f1c
1229 3:8528aa5637f2
1229 3:8528aa5637f2
1230 4:2326846efdab
1230 4:2326846efdab
1231 5:904fa392b941
1231 5:904fa392b941
1232 6:e0cc66ef77e8
1232 6:e0cc66ef77e8
1233 7:013af1973af4
1233 7:013af1973af4
1234 8:d5d0dcbdc4d9
1234 8:d5d0dcbdc4d9
1235 9:24286f4ae135
1235 9:24286f4ae135
1236
1236
1237 $ hg log -qr e: --config revsetalias.e="0"
1237 $ hg log -qr e: --config revsetalias.e="0"
1238 0:2785f51eece5
1238 0:2785f51eece5
1239 1:d75937da8da0
1239 1:d75937da8da0
1240 2:5ed5505e9f1c
1240 2:5ed5505e9f1c
1241 3:8528aa5637f2
1241 3:8528aa5637f2
1242 4:2326846efdab
1242 4:2326846efdab
1243 5:904fa392b941
1243 5:904fa392b941
1244 6:e0cc66ef77e8
1244 6:e0cc66ef77e8
1245 7:013af1973af4
1245 7:013af1973af4
1246 8:d5d0dcbdc4d9
1246 8:d5d0dcbdc4d9
1247 9:24286f4ae135
1247 9:24286f4ae135
1248
1248
1249 $ hg log -qr :e --config revsetalias.e="9"
1249 $ hg log -qr :e --config revsetalias.e="9"
1250 0:2785f51eece5
1250 0:2785f51eece5
1251 1:d75937da8da0
1251 1:d75937da8da0
1252 2:5ed5505e9f1c
1252 2:5ed5505e9f1c
1253 3:8528aa5637f2
1253 3:8528aa5637f2
1254 4:2326846efdab
1254 4:2326846efdab
1255 5:904fa392b941
1255 5:904fa392b941
1256 6:e0cc66ef77e8
1256 6:e0cc66ef77e8
1257 7:013af1973af4
1257 7:013af1973af4
1258 8:d5d0dcbdc4d9
1258 8:d5d0dcbdc4d9
1259 9:24286f4ae135
1259 9:24286f4ae135
1260
1260
1261 $ hg log -qr e:
1261 $ hg log -qr e:
1262 6:e0cc66ef77e8
1262 6:e0cc66ef77e8
1263 7:013af1973af4
1263 7:013af1973af4
1264 8:d5d0dcbdc4d9
1264 8:d5d0dcbdc4d9
1265 9:24286f4ae135
1265 9:24286f4ae135
1266
1266
1267 $ hg log -qr :e
1267 $ hg log -qr :e
1268 0:2785f51eece5
1268 0:2785f51eece5
1269 1:d75937da8da0
1269 1:d75937da8da0
1270 2:5ed5505e9f1c
1270 2:5ed5505e9f1c
1271 3:8528aa5637f2
1271 3:8528aa5637f2
1272 4:2326846efdab
1272 4:2326846efdab
1273 5:904fa392b941
1273 5:904fa392b941
1274 6:e0cc66ef77e8
1274 6:e0cc66ef77e8
1275
1275
1276 issue2549 - correct optimizations
1276 issue2549 - correct optimizations
1277
1277
1278 $ try 'limit(1 or 2 or 3, 2) and not 2'
1278 $ try 'limit(1 or 2 or 3, 2) and not 2'
1279 (and
1279 (and
1280 (func
1280 (func
1281 (symbol 'limit')
1281 (symbol 'limit')
1282 (list
1282 (list
1283 (or
1283 (or
1284 (list
1284 (list
1285 (symbol '1')
1285 (symbol '1')
1286 (symbol '2')
1286 (symbol '2')
1287 (symbol '3')))
1287 (symbol '3')))
1288 (symbol '2')))
1288 (symbol '2')))
1289 (not
1289 (not
1290 (symbol '2')))
1290 (symbol '2')))
1291 * set:
1291 * set:
1292 <filteredset
1292 <filteredset
1293 <baseset [1, 2]>,
1293 <baseset [1, 2]>,
1294 <not
1294 <not
1295 <baseset [2]>>>
1295 <baseset [2]>>>
1296 1
1296 1
1297 $ try 'max(1 or 2) and not 2'
1297 $ try 'max(1 or 2) and not 2'
1298 (and
1298 (and
1299 (func
1299 (func
1300 (symbol 'max')
1300 (symbol 'max')
1301 (or
1301 (or
1302 (list
1302 (list
1303 (symbol '1')
1303 (symbol '1')
1304 (symbol '2'))))
1304 (symbol '2'))))
1305 (not
1305 (not
1306 (symbol '2')))
1306 (symbol '2')))
1307 * set:
1307 * set:
1308 <filteredset
1308 <filteredset
1309 <baseset
1309 <baseset
1310 <max
1310 <max
1311 <fullreposet+ 0:10>,
1311 <fullreposet+ 0:10>,
1312 <baseset [1, 2]>>>,
1312 <baseset [1, 2]>>>,
1313 <not
1313 <not
1314 <baseset [2]>>>
1314 <baseset [2]>>>
1315 $ try 'min(1 or 2) and not 1'
1315 $ try 'min(1 or 2) and not 1'
1316 (and
1316 (and
1317 (func
1317 (func
1318 (symbol 'min')
1318 (symbol 'min')
1319 (or
1319 (or
1320 (list
1320 (list
1321 (symbol '1')
1321 (symbol '1')
1322 (symbol '2'))))
1322 (symbol '2'))))
1323 (not
1323 (not
1324 (symbol '1')))
1324 (symbol '1')))
1325 * set:
1325 * set:
1326 <filteredset
1326 <filteredset
1327 <baseset
1327 <baseset
1328 <min
1328 <min
1329 <fullreposet+ 0:10>,
1329 <fullreposet+ 0:10>,
1330 <baseset [1, 2]>>>,
1330 <baseset [1, 2]>>>,
1331 <not
1331 <not
1332 <baseset [1]>>>
1332 <baseset [1]>>>
1333 $ try 'last(1 or 2, 1) and not 2'
1333 $ try 'last(1 or 2, 1) and not 2'
1334 (and
1334 (and
1335 (func
1335 (func
1336 (symbol 'last')
1336 (symbol 'last')
1337 (list
1337 (list
1338 (or
1338 (or
1339 (list
1339 (list
1340 (symbol '1')
1340 (symbol '1')
1341 (symbol '2')))
1341 (symbol '2')))
1342 (symbol '1')))
1342 (symbol '1')))
1343 (not
1343 (not
1344 (symbol '2')))
1344 (symbol '2')))
1345 * set:
1345 * set:
1346 <filteredset
1346 <filteredset
1347 <baseset [2]>,
1347 <baseset [2]>,
1348 <not
1348 <not
1349 <baseset [2]>>>
1349 <baseset [2]>>>
1350
1350
1351 issue4289 - ordering of built-ins
1351 issue4289 - ordering of built-ins
1352 $ hg log -M -q -r 3:2
1352 $ hg log -M -q -r 3:2
1353 3:8528aa5637f2
1353 3:8528aa5637f2
1354 2:5ed5505e9f1c
1354 2:5ed5505e9f1c
1355
1355
1356 test revsets started with 40-chars hash (issue3669)
1356 test revsets started with 40-chars hash (issue3669)
1357
1357
1358 $ ISSUE3669_TIP=`hg tip --template '{node}'`
1358 $ ISSUE3669_TIP=`hg tip --template '{node}'`
1359 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
1359 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
1360 9
1360 9
1361 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
1361 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
1362 8
1362 8
1363
1363
1364 test or-ed indirect predicates (issue3775)
1364 test or-ed indirect predicates (issue3775)
1365
1365
1366 $ log '6 or 6^1' | sort
1366 $ log '6 or 6^1' | sort
1367 5
1367 5
1368 6
1368 6
1369 $ log '6^1 or 6' | sort
1369 $ log '6^1 or 6' | sort
1370 5
1370 5
1371 6
1371 6
1372 $ log '4 or 4~1' | sort
1372 $ log '4 or 4~1' | sort
1373 2
1373 2
1374 4
1374 4
1375 $ log '4~1 or 4' | sort
1375 $ log '4~1 or 4' | sort
1376 2
1376 2
1377 4
1377 4
1378 $ log '(0 or 2):(4 or 6) or 0 or 6' | sort
1378 $ log '(0 or 2):(4 or 6) or 0 or 6' | sort
1379 0
1379 0
1380 1
1380 1
1381 2
1381 2
1382 3
1382 3
1383 4
1383 4
1384 5
1384 5
1385 6
1385 6
1386 $ log '0 or 6 or (0 or 2):(4 or 6)' | sort
1386 $ log '0 or 6 or (0 or 2):(4 or 6)' | sort
1387 0
1387 0
1388 1
1388 1
1389 2
1389 2
1390 3
1390 3
1391 4
1391 4
1392 5
1392 5
1393 6
1393 6
1394
1394
1395 tests for 'remote()' predicate:
1395 tests for 'remote()' predicate:
1396 #. (csets in remote) (id) (remote)
1396 #. (csets in remote) (id) (remote)
1397 1. less than local current branch "default"
1397 1. less than local current branch "default"
1398 2. same with local specified "default"
1398 2. same with local specified "default"
1399 3. more than local specified specified
1399 3. more than local specified specified
1400
1400
1401 $ hg clone --quiet -U . ../remote3
1401 $ hg clone --quiet -U . ../remote3
1402 $ cd ../remote3
1402 $ cd ../remote3
1403 $ hg update -q 7
1403 $ hg update -q 7
1404 $ echo r > r
1404 $ echo r > r
1405 $ hg ci -Aqm 10
1405 $ hg ci -Aqm 10
1406 $ log 'remote()'
1406 $ log 'remote()'
1407 7
1407 7
1408 $ log 'remote("a-b-c-")'
1408 $ log 'remote("a-b-c-")'
1409 2
1409 2
1410 $ cd ../repo
1410 $ cd ../repo
1411 $ log 'remote(".a.b.c.", "../remote3")'
1411 $ log 'remote(".a.b.c.", "../remote3")'
1412
1412
1413 tests for concatenation of strings/symbols by "##"
1413 tests for concatenation of strings/symbols by "##"
1414
1414
1415 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
1415 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
1416 (_concat
1416 (_concat
1417 (_concat
1417 (_concat
1418 (_concat
1418 (_concat
1419 (symbol '278')
1419 (symbol '278')
1420 (string '5f5'))
1420 (string '5f5'))
1421 (symbol '1ee'))
1421 (symbol '1ee'))
1422 (string 'ce5'))
1422 (string 'ce5'))
1423 * concatenated:
1423 * concatenated:
1424 (string '2785f51eece5')
1424 (string '2785f51eece5')
1425 * set:
1425 * set:
1426 <baseset [0]>
1426 <baseset [0]>
1427 0
1427 0
1428
1428
1429 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
1429 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
1430 $ try "cat4(278, '5f5', 1ee, 'ce5')"
1430 $ try "cat4(278, '5f5', 1ee, 'ce5')"
1431 (func
1431 (func
1432 (symbol 'cat4')
1432 (symbol 'cat4')
1433 (list
1433 (list
1434 (symbol '278')
1434 (symbol '278')
1435 (string '5f5')
1435 (string '5f5')
1436 (symbol '1ee')
1436 (symbol '1ee')
1437 (string 'ce5')))
1437 (string 'ce5')))
1438 * expanded:
1438 * expanded:
1439 (_concat
1439 (_concat
1440 (_concat
1440 (_concat
1441 (_concat
1441 (_concat
1442 (symbol '278')
1442 (symbol '278')
1443 (string '5f5'))
1443 (string '5f5'))
1444 (symbol '1ee'))
1444 (symbol '1ee'))
1445 (string 'ce5'))
1445 (string 'ce5'))
1446 * concatenated:
1446 * concatenated:
1447 (string '2785f51eece5')
1447 (string '2785f51eece5')
1448 * set:
1448 * set:
1449 <baseset [0]>
1449 <baseset [0]>
1450 0
1450 0
1451
1451
1452 (check concatenation in alias nesting)
1452 (check concatenation in alias nesting)
1453
1453
1454 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
1454 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
1455 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
1455 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
1456 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
1456 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
1457 0
1457 0
1458
1458
1459 (check operator priority)
1459 (check operator priority)
1460
1460
1461 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
1461 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
1462 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
1462 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
1463 0
1463 0
1464 4
1464 4
1465
1465
1466 $ cd ..
1466 $ cd ..
1467
1467
1468 prepare repository that has "default" branches of multiple roots
1468 prepare repository that has "default" branches of multiple roots
1469
1469
1470 $ hg init namedbranch
1470 $ hg init namedbranch
1471 $ cd namedbranch
1471 $ cd namedbranch
1472
1472
1473 $ echo default0 >> a
1473 $ echo default0 >> a
1474 $ hg ci -Aqm0
1474 $ hg ci -Aqm0
1475 $ echo default1 >> a
1475 $ echo default1 >> a
1476 $ hg ci -m1
1476 $ hg ci -m1
1477
1477
1478 $ hg branch -q stable
1478 $ hg branch -q stable
1479 $ echo stable2 >> a
1479 $ echo stable2 >> a
1480 $ hg ci -m2
1480 $ hg ci -m2
1481 $ echo stable3 >> a
1481 $ echo stable3 >> a
1482 $ hg ci -m3
1482 $ hg ci -m3
1483
1483
1484 $ hg update -q null
1484 $ hg update -q null
1485 $ echo default4 >> a
1485 $ echo default4 >> a
1486 $ hg ci -Aqm4
1486 $ hg ci -Aqm4
1487 $ echo default5 >> a
1487 $ echo default5 >> a
1488 $ hg ci -m5
1488 $ hg ci -m5
1489
1489
1490 "null" revision belongs to "default" branch (issue4683)
1490 "null" revision belongs to "default" branch (issue4683)
1491
1491
1492 $ log 'branch(null)'
1492 $ log 'branch(null)'
1493 0
1493 0
1494 1
1494 1
1495 4
1495 4
1496 5
1496 5
1497
1497
1498 "null" revision belongs to "default" branch, but it shouldn't appear in set
1498 "null" revision belongs to "default" branch, but it shouldn't appear in set
1499 unless explicitly specified (issue4682)
1499 unless explicitly specified (issue4682)
1500
1500
1501 $ log 'children(branch(default))'
1501 $ log 'children(branch(default))'
1502 1
1502 1
1503 2
1503 2
1504 5
1504 5
1505
1505
1506 $ cd ..
1506 $ cd ..
1507
1507
1508 test author/desc/keyword in problematic encoding
1508 test author/desc/keyword in problematic encoding
1509 # unicode: cp932:
1509 # unicode: cp932:
1510 # u30A2 0x83 0x41(= 'A')
1510 # u30A2 0x83 0x41(= 'A')
1511 # u30C2 0x83 0x61(= 'a')
1511 # u30C2 0x83 0x61(= 'a')
1512
1512
1513 $ hg init problematicencoding
1513 $ hg init problematicencoding
1514 $ cd problematicencoding
1514 $ cd problematicencoding
1515
1515
1516 $ $PYTHON > setup.sh <<EOF
1516 $ $PYTHON > setup.sh <<EOF
1517 > print u'''
1517 > print u'''
1518 > echo a > text
1518 > echo a > text
1519 > hg add text
1519 > hg add text
1520 > hg --encoding utf-8 commit -u '\u30A2' -m none
1520 > hg --encoding utf-8 commit -u '\u30A2' -m none
1521 > echo b > text
1521 > echo b > text
1522 > hg --encoding utf-8 commit -u '\u30C2' -m none
1522 > hg --encoding utf-8 commit -u '\u30C2' -m none
1523 > echo c > text
1523 > echo c > text
1524 > hg --encoding utf-8 commit -u none -m '\u30A2'
1524 > hg --encoding utf-8 commit -u none -m '\u30A2'
1525 > echo d > text
1525 > echo d > text
1526 > hg --encoding utf-8 commit -u none -m '\u30C2'
1526 > hg --encoding utf-8 commit -u none -m '\u30C2'
1527 > '''.encode('utf-8')
1527 > '''.encode('utf-8')
1528 > EOF
1528 > EOF
1529 $ sh < setup.sh
1529 $ sh < setup.sh
1530
1530
1531 test in problematic encoding
1531 test in problematic encoding
1532 $ $PYTHON > test.sh <<EOF
1532 $ $PYTHON > test.sh <<EOF
1533 > print u'''
1533 > print u'''
1534 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
1534 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
1535 > echo ====
1535 > echo ====
1536 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
1536 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
1537 > echo ====
1537 > echo ====
1538 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
1538 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
1539 > echo ====
1539 > echo ====
1540 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
1540 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
1541 > echo ====
1541 > echo ====
1542 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
1542 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
1543 > echo ====
1543 > echo ====
1544 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
1544 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
1545 > '''.encode('cp932')
1545 > '''.encode('cp932')
1546 > EOF
1546 > EOF
1547 $ sh < test.sh
1547 $ sh < test.sh
1548 0
1548 0
1549 ====
1549 ====
1550 1
1550 1
1551 ====
1551 ====
1552 2
1552 2
1553 ====
1553 ====
1554 3
1554 3
1555 ====
1555 ====
1556 0
1556 0
1557 2
1557 2
1558 ====
1558 ====
1559 1
1559 1
1560 3
1560 3
1561
1561
1562 test error message of bad revset
1562 test error message of bad revset
1563 $ hg log -r 'foo\\'
1563 $ hg log -r 'foo\\'
1564 hg: parse error at 3: syntax error in revset 'foo\\'
1564 hg: parse error at 3: syntax error in revset 'foo\\'
1565 [255]
1565 [255]
1566
1566
1567 $ cd ..
1567 $ cd ..
1568
1568
1569 Test that revset predicate of extension isn't loaded at failure of
1569 Test that revset predicate of extension isn't loaded at failure of
1570 loading it
1570 loading it
1571
1571
1572 $ cd repo
1572 $ cd repo
1573
1573
1574 $ cat <<EOF > $TESTTMP/custompredicate.py
1574 $ cat <<EOF > $TESTTMP/custompredicate.py
1575 > from mercurial import error, registrar, revset
1575 > from mercurial import error, registrar, revset
1576 >
1576 >
1577 > revsetpredicate = registrar.revsetpredicate()
1577 > revsetpredicate = registrar.revsetpredicate()
1578 >
1578 >
1579 > @revsetpredicate('custom1()')
1579 > @revsetpredicate('custom1()')
1580 > def custom1(repo, subset, x):
1580 > def custom1(repo, subset, x):
1581 > return revset.baseset([1])
1581 > return revset.baseset([1])
1582 >
1582 >
1583 > raise error.Abort('intentional failure of loading extension')
1583 > raise error.Abort('intentional failure of loading extension')
1584 > EOF
1584 > EOF
1585 $ cat <<EOF > .hg/hgrc
1585 $ cat <<EOF > .hg/hgrc
1586 > [extensions]
1586 > [extensions]
1587 > custompredicate = $TESTTMP/custompredicate.py
1587 > custompredicate = $TESTTMP/custompredicate.py
1588 > EOF
1588 > EOF
1589
1589
1590 $ hg debugrevspec "custom1()"
1590 $ hg debugrevspec "custom1()"
1591 *** failed to import extension custompredicate from $TESTTMP/custompredicate.py: intentional failure of loading extension
1591 *** failed to import extension custompredicate from $TESTTMP/custompredicate.py: intentional failure of loading extension
1592 hg: parse error: unknown identifier: custom1
1592 hg: parse error: unknown identifier: custom1
1593 [255]
1593 [255]
1594
1594
1595 Test repo.anyrevs with customized revset overrides
1595 Test repo.anyrevs with customized revset overrides
1596
1596
1597 $ cat > $TESTTMP/printprevset.py <<EOF
1597 $ cat > $TESTTMP/printprevset.py <<EOF
1598 > from mercurial import encoding, registrar
1598 > from mercurial import encoding, registrar
1599 > cmdtable = {}
1599 > cmdtable = {}
1600 > command = registrar.command(cmdtable)
1600 > command = registrar.command(cmdtable)
1601 > @command('printprevset')
1601 > @command('printprevset')
1602 > def printprevset(ui, repo):
1602 > def printprevset(ui, repo):
1603 > alias = {}
1603 > alias = {}
1604 > p = encoding.environ.get('P')
1604 > p = encoding.environ.get('P')
1605 > if p:
1605 > if p:
1606 > alias['P'] = p
1606 > alias['P'] = p
1607 > revs = repo.anyrevs(['P'], user=True, localalias=alias)
1607 > revs = repo.anyrevs(['P'], user=True, localalias=alias)
1608 > ui.write('P=%r\n' % list(revs))
1608 > ui.write('P=%r\n' % list(revs))
1609 > EOF
1609 > EOF
1610
1610
1611 $ cat >> .hg/hgrc <<EOF
1611 $ cat >> .hg/hgrc <<EOF
1612 > custompredicate = !
1612 > custompredicate = !
1613 > printprevset = $TESTTMP/printprevset.py
1613 > printprevset = $TESTTMP/printprevset.py
1614 > EOF
1614 > EOF
1615
1615
1616 $ hg --config revsetalias.P=1 printprevset
1616 $ hg --config revsetalias.P=1 printprevset
1617 P=[1]
1617 P=[1]
1618 $ P=3 hg --config revsetalias.P=2 printprevset
1618 $ P=3 hg --config revsetalias.P=2 printprevset
1619 P=[3]
1619 P=[3]
1620
1620
1621 $ cd ..
1621 $ cd ..
1622
1622
1623 Test obsstore related revsets
1623 Test obsstore related revsets
1624
1624
1625 $ hg init repo1
1625 $ hg init repo1
1626 $ cd repo1
1626 $ cd repo1
1627 $ cat <<EOF >> .hg/hgrc
1627 $ cat <<EOF >> .hg/hgrc
1628 > [experimental]
1628 > [experimental]
1629 > evolution.createmarkers=True
1629 > evolution.createmarkers=True
1630 > EOF
1630 > EOF
1631
1631
1632 $ hg debugdrawdag <<'EOS'
1632 $ hg debugdrawdag <<'EOS'
1633 > F G
1633 > F G
1634 > |/ # split: B -> E, F
1634 > |/ # split: B -> E, F
1635 > B C D E # amend: B -> C -> D
1635 > B C D E # amend: B -> C -> D
1636 > \|/ | # amend: F -> G
1636 > \|/ | # amend: F -> G
1637 > A A Z # amend: A -> Z
1637 > A A Z # amend: A -> Z
1638 > EOS
1638 > EOS
1639
1639
1640 $ hg log -r 'successors(Z)' -T '{desc}\n'
1640 $ hg log -r 'successors(Z)' -T '{desc}\n'
1641 Z
1641 Z
1642
1642
1643 $ hg log -r 'successors(F)' -T '{desc}\n'
1643 $ hg log -r 'successors(F)' -T '{desc}\n'
1644 F
1644 F
1645 G
1645 G
1646
1646
1647 $ hg tag --remove --local C D E F G
1647 $ hg tag --remove --local C D E F G
1648
1648
1649 $ hg log -r 'successors(B)' -T '{desc}\n'
1649 $ hg log -r 'successors(B)' -T '{desc}\n'
1650 B
1650 B
1651 D
1651 D
1652 E
1652 E
1653 G
1653 G
1654
1654
1655 $ hg log -r 'successors(B)' -T '{desc}\n' --hidden
1655 $ hg log -r 'successors(B)' -T '{desc}\n' --hidden
1656 B
1656 B
1657 C
1657 C
1658 D
1658 D
1659 E
1659 E
1660 F
1660 F
1661 G
1661 G
1662
1662
1663 $ hg log -r 'successors(B)-obsolete()' -T '{desc}\n' --hidden
1663 $ hg log -r 'successors(B)-obsolete()' -T '{desc}\n' --hidden
1664 D
1664 D
1665 E
1665 E
1666 G
1666 G
1667
1667
1668 $ hg log -r 'successors(B+A)-contentdivergent()' -T '{desc}\n'
1668 $ hg log -r 'successors(B+A)-contentdivergent()' -T '{desc}\n'
1669 A
1669 A
1670 Z
1670 Z
1671 B
1671 B
1672
1672
1673 $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n'
1673 $ hg log -r 'successors(B+A)-contentdivergent()-obsolete()' -T '{desc}\n'
1674 Z
1674 Z
1675
1675
1676 Test `draft() & ::x` optimization
1676 Test `draft() & ::x` optimization
1677
1677
1678 $ hg init $TESTTMP/repo2
1678 $ hg init $TESTTMP/repo2
1679 $ cd $TESTTMP/repo2
1679 $ cd $TESTTMP/repo2
1680 $ hg debugdrawdag <<'EOS'
1680 $ hg debugdrawdag <<'EOS'
1681 > P5 S1
1681 > P5 S1
1682 > | |
1682 > | |
1683 > S2 | D3
1683 > S2 | D3
1684 > \|/
1684 > \|/
1685 > P4
1685 > P4
1686 > |
1686 > |
1687 > P3 D2
1687 > P3 D2
1688 > | |
1688 > | |
1689 > P2 D1
1689 > P2 D1
1690 > |/
1690 > |/
1691 > P1
1691 > P1
1692 > |
1692 > |
1693 > P0
1693 > P0
1694 > EOS
1694 > EOS
1695 $ hg phase --public -r P5
1695 $ hg phase --public -r P5
1696 $ hg phase --force --secret -r S1+S2
1696 $ hg phase --force --secret -r S1+S2
1697 $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, topo.firstbranch=P5)'
1697 $ hg log -G -T '{rev} {desc} {phase}' -r 'sort(all(), topo, topo.firstbranch=P5)'
1698 o 8 P5 public
1698 o 8 P5 public
1699 |
1699 |
1700 | o 10 S1 secret
1700 | o 10 S1 secret
1701 | |
1701 | |
1702 | o 7 D3 draft
1702 | o 7 D3 draft
1703 |/
1703 |/
1704 | o 9 S2 secret
1704 | o 9 S2 secret
1705 |/
1705 |/
1706 o 6 P4 public
1706 o 6 P4 public
1707 |
1707 |
1708 o 5 P3 public
1708 o 5 P3 public
1709 |
1709 |
1710 o 3 P2 public
1710 o 3 P2 public
1711 |
1711 |
1712 | o 4 D2 draft
1712 | o 4 D2 draft
1713 | |
1713 | |
1714 | o 2 D1 draft
1714 | o 2 D1 draft
1715 |/
1715 |/
1716 o 1 P1 public
1716 o 1 P1 public
1717 |
1717 |
1718 o 0 P0 public
1718 o 0 P0 public
1719
1719
1720 $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & ::(((S1+D1+P5)-D3)+S2)'
1720 $ hg debugrevspec --verify -p analyzed -p optimized 'draft() & ::(((S1+D1+P5)-D3)+S2)'
1721 * analyzed:
1721 * analyzed:
1722 (and
1722 (and
1723 (func
1723 (func
1724 (symbol 'draft')
1724 (symbol 'draft')
1725 None)
1725 None)
1726 (func
1726 (func
1727 (symbol 'ancestors')
1727 (symbol 'ancestors')
1728 (or
1728 (or
1729 (list
1729 (list
1730 (and
1730 (and
1731 (or
1731 (or
1732 (list
1732 (list
1733 (symbol 'S1')
1733 (symbol 'S1')
1734 (symbol 'D1')
1734 (symbol 'D1')
1735 (symbol 'P5')))
1735 (symbol 'P5')))
1736 (not
1736 (not
1737 (symbol 'D3')))
1737 (symbol 'D3')))
1738 (symbol 'S2')))))
1738 (symbol 'S2')))))
1739 * optimized:
1739 * optimized:
1740 (func
1740 (func
1741 (symbol '_phaseandancestors')
1741 (symbol '_phaseandancestors')
1742 (list
1742 (list
1743 (symbol 'draft')
1743 (symbol 'draft')
1744 (or
1744 (or
1745 (list
1745 (list
1746 (difference
1746 (difference
1747 (func
1747 (func
1748 (symbol '_list')
1748 (symbol '_list')
1749 (string 'S1\x00D1\x00P5'))
1749 (string 'S1\x00D1\x00P5'))
1750 (symbol 'D3'))
1750 (symbol 'D3'))
1751 (symbol 'S2')))))
1751 (symbol 'S2')))))
1752 $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::9'
1752 $ hg debugrevspec --verify -p analyzed -p optimized 'secret() & ::9'
1753 * analyzed:
1753 * analyzed:
1754 (and
1754 (and
1755 (func
1755 (func
1756 (symbol 'secret')
1756 (symbol 'secret')
1757 None)
1757 None)
1758 (func
1758 (func
1759 (symbol 'ancestors')
1759 (symbol 'ancestors')
1760 (symbol '9')))
1760 (symbol '9')))
1761 * optimized:
1761 * optimized:
1762 (func
1762 (func
1763 (symbol '_phaseandancestors')
1763 (symbol '_phaseandancestors')
1764 (list
1764 (list
1765 (symbol 'secret')
1765 (symbol 'secret')
1766 (symbol '9')))
1766 (symbol '9')))
1767 $ hg debugrevspec --verify -p analyzed -p optimized '7 & ( (not public()) & ::(tag()) )'
1767 $ hg debugrevspec --verify -p analyzed -p optimized '7 & ( (not public()) & ::(tag()) )'
1768 * analyzed:
1768 * analyzed:
1769 (and
1769 (and
1770 (symbol '7')
1770 (symbol '7')
1771 (and
1771 (and
1772 (not
1772 (not
1773 (func
1773 (func
1774 (symbol 'public')
1774 (symbol 'public')
1775 None))
1775 None))
1776 (func
1776 (func
1777 (symbol 'ancestors')
1777 (symbol 'ancestors')
1778 (func
1778 (func
1779 (symbol 'tag')
1779 (symbol 'tag')
1780 None))))
1780 None))))
1781 * optimized:
1781 * optimized:
1782 (and
1782 (and
1783 (symbol '7')
1783 (symbol '7')
1784 (func
1784 (func
1785 (symbol '_phaseandancestors')
1785 (symbol '_phaseandancestors')
1786 (list
1786 (list
1787 (symbol '_notpublic')
1787 (symbol '_notpublic')
1788 (func
1788 (func
1789 (symbol 'tag')
1789 (symbol 'tag')
1790 None))))
1790 None))))
1791 $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, 1)'
1791 $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, 1)'
1792 * optimized:
1792 * optimized:
1793 (and
1793 (and
1794 (func
1794 (func
1795 (symbol '_notpublic')
1795 (symbol '_notpublic')
1796 None)
1796 None)
1797 (func
1797 (func
1798 (symbol 'ancestors')
1798 (symbol 'ancestors')
1799 (list
1799 (list
1800 (func
1800 (func
1801 (symbol '_list')
1801 (symbol '_list')
1802 (string 'S1\x00D2\x00P5'))
1802 (string 'S1\x00D2\x00P5'))
1803 (symbol '1'))))
1803 (symbol '1'))))
1804 $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, depth=1)'
1804 $ hg debugrevspec --verify -p optimized '(not public()) & ancestors(S1+D2+P5, depth=1)'
1805 * optimized:
1805 * optimized:
1806 (and
1806 (and
1807 (func
1807 (func
1808 (symbol '_notpublic')
1808 (symbol '_notpublic')
1809 None)
1809 None)
1810 (func
1810 (func
1811 (symbol 'ancestors')
1811 (symbol 'ancestors')
1812 (list
1812 (list
1813 (func
1813 (func
1814 (symbol '_list')
1814 (symbol '_list')
1815 (string 'S1\x00D2\x00P5'))
1815 (string 'S1\x00D2\x00P5'))
1816 (keyvalue
1816 (keyvalue
1817 (symbol 'depth')
1817 (symbol 'depth')
1818 (symbol '1')))))
1818 (symbol '1')))))
General Comments 0
You need to be logged in to leave comments. Login now