##// END OF EJS Templates
reachableroots: use baseset lazy sorting...
Pierre-Yves David -
r26061:be8a4e08 default
parent child Browse files
Show More
@@ -1,408 +1,410
1 # changelog.py - changelog class for mercurial
1 # changelog.py - changelog class for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 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 .i18n import _
10 from .i18n import _
11 from .node import (
11 from .node import (
12 bin,
12 bin,
13 hex,
13 hex,
14 nullid,
14 nullid,
15 )
15 )
16
16
17 from . import (
17 from . import (
18 encoding,
18 encoding,
19 error,
19 error,
20 revlog,
20 revlog,
21 revset,
21 revset,
22 util,
22 util,
23 )
23 )
24
24
25 _defaultextra = {'branch': 'default'}
25 _defaultextra = {'branch': 'default'}
26
26
27 def _string_escape(text):
27 def _string_escape(text):
28 """
28 """
29 >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
29 >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
30 >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
30 >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
31 >>> s
31 >>> s
32 'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
32 'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
33 >>> res = _string_escape(s)
33 >>> res = _string_escape(s)
34 >>> s == res.decode('string_escape')
34 >>> s == res.decode('string_escape')
35 True
35 True
36 """
36 """
37 # subset of the string_escape codec
37 # subset of the string_escape codec
38 text = text.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r')
38 text = text.replace('\\', '\\\\').replace('\n', '\\n').replace('\r', '\\r')
39 return text.replace('\0', '\\0')
39 return text.replace('\0', '\\0')
40
40
41 def decodeextra(text):
41 def decodeextra(text):
42 """
42 """
43 >>> sorted(decodeextra(encodeextra({'foo': 'bar', 'baz': chr(0) + '2'})
43 >>> sorted(decodeextra(encodeextra({'foo': 'bar', 'baz': chr(0) + '2'})
44 ... ).iteritems())
44 ... ).iteritems())
45 [('baz', '\\x002'), ('branch', 'default'), ('foo', 'bar')]
45 [('baz', '\\x002'), ('branch', 'default'), ('foo', 'bar')]
46 >>> sorted(decodeextra(encodeextra({'foo': 'bar',
46 >>> sorted(decodeextra(encodeextra({'foo': 'bar',
47 ... 'baz': chr(92) + chr(0) + '2'})
47 ... 'baz': chr(92) + chr(0) + '2'})
48 ... ).iteritems())
48 ... ).iteritems())
49 [('baz', '\\\\\\x002'), ('branch', 'default'), ('foo', 'bar')]
49 [('baz', '\\\\\\x002'), ('branch', 'default'), ('foo', 'bar')]
50 """
50 """
51 extra = _defaultextra.copy()
51 extra = _defaultextra.copy()
52 for l in text.split('\0'):
52 for l in text.split('\0'):
53 if l:
53 if l:
54 if '\\0' in l:
54 if '\\0' in l:
55 # fix up \0 without getting into trouble with \\0
55 # fix up \0 without getting into trouble with \\0
56 l = l.replace('\\\\', '\\\\\n')
56 l = l.replace('\\\\', '\\\\\n')
57 l = l.replace('\\0', '\0')
57 l = l.replace('\\0', '\0')
58 l = l.replace('\n', '')
58 l = l.replace('\n', '')
59 k, v = l.decode('string_escape').split(':', 1)
59 k, v = l.decode('string_escape').split(':', 1)
60 extra[k] = v
60 extra[k] = v
61 return extra
61 return extra
62
62
63 def encodeextra(d):
63 def encodeextra(d):
64 # keys must be sorted to produce a deterministic changelog entry
64 # keys must be sorted to produce a deterministic changelog entry
65 items = [_string_escape('%s:%s' % (k, d[k])) for k in sorted(d)]
65 items = [_string_escape('%s:%s' % (k, d[k])) for k in sorted(d)]
66 return "\0".join(items)
66 return "\0".join(items)
67
67
68 def stripdesc(desc):
68 def stripdesc(desc):
69 """strip trailing whitespace and leading and trailing empty lines"""
69 """strip trailing whitespace and leading and trailing empty lines"""
70 return '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n')
70 return '\n'.join([l.rstrip() for l in desc.splitlines()]).strip('\n')
71
71
72 class appender(object):
72 class appender(object):
73 '''the changelog index must be updated last on disk, so we use this class
73 '''the changelog index must be updated last on disk, so we use this class
74 to delay writes to it'''
74 to delay writes to it'''
75 def __init__(self, vfs, name, mode, buf):
75 def __init__(self, vfs, name, mode, buf):
76 self.data = buf
76 self.data = buf
77 fp = vfs(name, mode)
77 fp = vfs(name, mode)
78 self.fp = fp
78 self.fp = fp
79 self.offset = fp.tell()
79 self.offset = fp.tell()
80 self.size = vfs.fstat(fp).st_size
80 self.size = vfs.fstat(fp).st_size
81
81
82 def end(self):
82 def end(self):
83 return self.size + len("".join(self.data))
83 return self.size + len("".join(self.data))
84 def tell(self):
84 def tell(self):
85 return self.offset
85 return self.offset
86 def flush(self):
86 def flush(self):
87 pass
87 pass
88 def close(self):
88 def close(self):
89 self.fp.close()
89 self.fp.close()
90
90
91 def seek(self, offset, whence=0):
91 def seek(self, offset, whence=0):
92 '''virtual file offset spans real file and data'''
92 '''virtual file offset spans real file and data'''
93 if whence == 0:
93 if whence == 0:
94 self.offset = offset
94 self.offset = offset
95 elif whence == 1:
95 elif whence == 1:
96 self.offset += offset
96 self.offset += offset
97 elif whence == 2:
97 elif whence == 2:
98 self.offset = self.end() + offset
98 self.offset = self.end() + offset
99 if self.offset < self.size:
99 if self.offset < self.size:
100 self.fp.seek(self.offset)
100 self.fp.seek(self.offset)
101
101
102 def read(self, count=-1):
102 def read(self, count=-1):
103 '''only trick here is reads that span real file and data'''
103 '''only trick here is reads that span real file and data'''
104 ret = ""
104 ret = ""
105 if self.offset < self.size:
105 if self.offset < self.size:
106 s = self.fp.read(count)
106 s = self.fp.read(count)
107 ret = s
107 ret = s
108 self.offset += len(s)
108 self.offset += len(s)
109 if count > 0:
109 if count > 0:
110 count -= len(s)
110 count -= len(s)
111 if count != 0:
111 if count != 0:
112 doff = self.offset - self.size
112 doff = self.offset - self.size
113 self.data.insert(0, "".join(self.data))
113 self.data.insert(0, "".join(self.data))
114 del self.data[1:]
114 del self.data[1:]
115 s = self.data[0][doff:doff + count]
115 s = self.data[0][doff:doff + count]
116 self.offset += len(s)
116 self.offset += len(s)
117 ret += s
117 ret += s
118 return ret
118 return ret
119
119
120 def write(self, s):
120 def write(self, s):
121 self.data.append(str(s))
121 self.data.append(str(s))
122 self.offset += len(s)
122 self.offset += len(s)
123
123
124 def _divertopener(opener, target):
124 def _divertopener(opener, target):
125 """build an opener that writes in 'target.a' instead of 'target'"""
125 """build an opener that writes in 'target.a' instead of 'target'"""
126 def _divert(name, mode='r'):
126 def _divert(name, mode='r'):
127 if name != target:
127 if name != target:
128 return opener(name, mode)
128 return opener(name, mode)
129 return opener(name + ".a", mode)
129 return opener(name + ".a", mode)
130 return _divert
130 return _divert
131
131
132 def _delayopener(opener, target, buf):
132 def _delayopener(opener, target, buf):
133 """build an opener that stores chunks in 'buf' instead of 'target'"""
133 """build an opener that stores chunks in 'buf' instead of 'target'"""
134 def _delay(name, mode='r'):
134 def _delay(name, mode='r'):
135 if name != target:
135 if name != target:
136 return opener(name, mode)
136 return opener(name, mode)
137 return appender(opener, name, mode, buf)
137 return appender(opener, name, mode, buf)
138 return _delay
138 return _delay
139
139
140 class changelog(revlog.revlog):
140 class changelog(revlog.revlog):
141 def __init__(self, opener):
141 def __init__(self, opener):
142 revlog.revlog.__init__(self, opener, "00changelog.i")
142 revlog.revlog.__init__(self, opener, "00changelog.i")
143 if self._initempty:
143 if self._initempty:
144 # changelogs don't benefit from generaldelta
144 # changelogs don't benefit from generaldelta
145 self.version &= ~revlog.REVLOGGENERALDELTA
145 self.version &= ~revlog.REVLOGGENERALDELTA
146 self._generaldelta = False
146 self._generaldelta = False
147 self._realopener = opener
147 self._realopener = opener
148 self._delayed = False
148 self._delayed = False
149 self._delaybuf = None
149 self._delaybuf = None
150 self._divert = False
150 self._divert = False
151 self.filteredrevs = frozenset()
151 self.filteredrevs = frozenset()
152
152
153 def tip(self):
153 def tip(self):
154 """filtered version of revlog.tip"""
154 """filtered version of revlog.tip"""
155 for i in xrange(len(self) -1, -2, -1):
155 for i in xrange(len(self) -1, -2, -1):
156 if i not in self.filteredrevs:
156 if i not in self.filteredrevs:
157 return self.node(i)
157 return self.node(i)
158
158
159 def __contains__(self, rev):
159 def __contains__(self, rev):
160 """filtered version of revlog.__contains__"""
160 """filtered version of revlog.__contains__"""
161 return (0 <= rev < len(self)
161 return (0 <= rev < len(self)
162 and rev not in self.filteredrevs)
162 and rev not in self.filteredrevs)
163
163
164 def __iter__(self):
164 def __iter__(self):
165 """filtered version of revlog.__iter__"""
165 """filtered version of revlog.__iter__"""
166 if len(self.filteredrevs) == 0:
166 if len(self.filteredrevs) == 0:
167 return revlog.revlog.__iter__(self)
167 return revlog.revlog.__iter__(self)
168
168
169 def filterediter():
169 def filterediter():
170 for i in xrange(len(self)):
170 for i in xrange(len(self)):
171 if i not in self.filteredrevs:
171 if i not in self.filteredrevs:
172 yield i
172 yield i
173
173
174 return filterediter()
174 return filterediter()
175
175
176 def revs(self, start=0, stop=None):
176 def revs(self, start=0, stop=None):
177 """filtered version of revlog.revs"""
177 """filtered version of revlog.revs"""
178 for i in super(changelog, self).revs(start, stop):
178 for i in super(changelog, self).revs(start, stop):
179 if i not in self.filteredrevs:
179 if i not in self.filteredrevs:
180 yield i
180 yield i
181
181
182 @util.propertycache
182 @util.propertycache
183 def nodemap(self):
183 def nodemap(self):
184 # XXX need filtering too
184 # XXX need filtering too
185 self.rev(self.node(0))
185 self.rev(self.node(0))
186 return self._nodecache
186 return self._nodecache
187
187
188 def reachableroots(self, minroot, heads, roots, includepath=False):
188 def reachableroots(self, minroot, heads, roots, includepath=False):
189 return revset.baseset(sorted(
189 rroots = self.index.reachableroots2(minroot, heads, roots, includepath)
190 self.index.reachableroots2(minroot, heads, roots, includepath)))
190 rroots = revset.baseset(rroots)
191 rroots.sort()
192 return rroots
191
193
192 def headrevs(self):
194 def headrevs(self):
193 if self.filteredrevs:
195 if self.filteredrevs:
194 try:
196 try:
195 return self.index.headrevsfiltered(self.filteredrevs)
197 return self.index.headrevsfiltered(self.filteredrevs)
196 # AttributeError covers non-c-extension environments and
198 # AttributeError covers non-c-extension environments and
197 # old c extensions without filter handling.
199 # old c extensions without filter handling.
198 except AttributeError:
200 except AttributeError:
199 return self._headrevs()
201 return self._headrevs()
200
202
201 return super(changelog, self).headrevs()
203 return super(changelog, self).headrevs()
202
204
203 def strip(self, *args, **kwargs):
205 def strip(self, *args, **kwargs):
204 # XXX make something better than assert
206 # XXX make something better than assert
205 # We can't expect proper strip behavior if we are filtered.
207 # We can't expect proper strip behavior if we are filtered.
206 assert not self.filteredrevs
208 assert not self.filteredrevs
207 super(changelog, self).strip(*args, **kwargs)
209 super(changelog, self).strip(*args, **kwargs)
208
210
209 def rev(self, node):
211 def rev(self, node):
210 """filtered version of revlog.rev"""
212 """filtered version of revlog.rev"""
211 r = super(changelog, self).rev(node)
213 r = super(changelog, self).rev(node)
212 if r in self.filteredrevs:
214 if r in self.filteredrevs:
213 raise error.FilteredLookupError(hex(node), self.indexfile,
215 raise error.FilteredLookupError(hex(node), self.indexfile,
214 _('filtered node'))
216 _('filtered node'))
215 return r
217 return r
216
218
217 def node(self, rev):
219 def node(self, rev):
218 """filtered version of revlog.node"""
220 """filtered version of revlog.node"""
219 if rev in self.filteredrevs:
221 if rev in self.filteredrevs:
220 raise error.FilteredIndexError(rev)
222 raise error.FilteredIndexError(rev)
221 return super(changelog, self).node(rev)
223 return super(changelog, self).node(rev)
222
224
223 def linkrev(self, rev):
225 def linkrev(self, rev):
224 """filtered version of revlog.linkrev"""
226 """filtered version of revlog.linkrev"""
225 if rev in self.filteredrevs:
227 if rev in self.filteredrevs:
226 raise error.FilteredIndexError(rev)
228 raise error.FilteredIndexError(rev)
227 return super(changelog, self).linkrev(rev)
229 return super(changelog, self).linkrev(rev)
228
230
229 def parentrevs(self, rev):
231 def parentrevs(self, rev):
230 """filtered version of revlog.parentrevs"""
232 """filtered version of revlog.parentrevs"""
231 if rev in self.filteredrevs:
233 if rev in self.filteredrevs:
232 raise error.FilteredIndexError(rev)
234 raise error.FilteredIndexError(rev)
233 return super(changelog, self).parentrevs(rev)
235 return super(changelog, self).parentrevs(rev)
234
236
235 def flags(self, rev):
237 def flags(self, rev):
236 """filtered version of revlog.flags"""
238 """filtered version of revlog.flags"""
237 if rev in self.filteredrevs:
239 if rev in self.filteredrevs:
238 raise error.FilteredIndexError(rev)
240 raise error.FilteredIndexError(rev)
239 return super(changelog, self).flags(rev)
241 return super(changelog, self).flags(rev)
240
242
241 def delayupdate(self, tr):
243 def delayupdate(self, tr):
242 "delay visibility of index updates to other readers"
244 "delay visibility of index updates to other readers"
243
245
244 if not self._delayed:
246 if not self._delayed:
245 if len(self) == 0:
247 if len(self) == 0:
246 self._divert = True
248 self._divert = True
247 if self._realopener.exists(self.indexfile + '.a'):
249 if self._realopener.exists(self.indexfile + '.a'):
248 self._realopener.unlink(self.indexfile + '.a')
250 self._realopener.unlink(self.indexfile + '.a')
249 self.opener = _divertopener(self._realopener, self.indexfile)
251 self.opener = _divertopener(self._realopener, self.indexfile)
250 else:
252 else:
251 self._delaybuf = []
253 self._delaybuf = []
252 self.opener = _delayopener(self._realopener, self.indexfile,
254 self.opener = _delayopener(self._realopener, self.indexfile,
253 self._delaybuf)
255 self._delaybuf)
254 self._delayed = True
256 self._delayed = True
255 tr.addpending('cl-%i' % id(self), self._writepending)
257 tr.addpending('cl-%i' % id(self), self._writepending)
256 tr.addfinalize('cl-%i' % id(self), self._finalize)
258 tr.addfinalize('cl-%i' % id(self), self._finalize)
257
259
258 def _finalize(self, tr):
260 def _finalize(self, tr):
259 "finalize index updates"
261 "finalize index updates"
260 self._delayed = False
262 self._delayed = False
261 self.opener = self._realopener
263 self.opener = self._realopener
262 # move redirected index data back into place
264 # move redirected index data back into place
263 if self._divert:
265 if self._divert:
264 assert not self._delaybuf
266 assert not self._delaybuf
265 tmpname = self.indexfile + ".a"
267 tmpname = self.indexfile + ".a"
266 nfile = self.opener.open(tmpname)
268 nfile = self.opener.open(tmpname)
267 nfile.close()
269 nfile.close()
268 self.opener.rename(tmpname, self.indexfile)
270 self.opener.rename(tmpname, self.indexfile)
269 elif self._delaybuf:
271 elif self._delaybuf:
270 fp = self.opener(self.indexfile, 'a')
272 fp = self.opener(self.indexfile, 'a')
271 fp.write("".join(self._delaybuf))
273 fp.write("".join(self._delaybuf))
272 fp.close()
274 fp.close()
273 self._delaybuf = None
275 self._delaybuf = None
274 self._divert = False
276 self._divert = False
275 # split when we're done
277 # split when we're done
276 self.checkinlinesize(tr)
278 self.checkinlinesize(tr)
277
279
278 def readpending(self, file):
280 def readpending(self, file):
279 """read index data from a "pending" file
281 """read index data from a "pending" file
280
282
281 During a transaction, the actual changeset data is already stored in the
283 During a transaction, the actual changeset data is already stored in the
282 main file, but not yet finalized in the on-disk index. Instead, a
284 main file, but not yet finalized in the on-disk index. Instead, a
283 "pending" index is written by the transaction logic. If this function
285 "pending" index is written by the transaction logic. If this function
284 is running, we are likely in a subprocess invoked in a hook. The
286 is running, we are likely in a subprocess invoked in a hook. The
285 subprocess is informed that it is within a transaction and needs to
287 subprocess is informed that it is within a transaction and needs to
286 access its content.
288 access its content.
287
289
288 This function will read all the index data out of the pending file and
290 This function will read all the index data out of the pending file and
289 overwrite the main index."""
291 overwrite the main index."""
290
292
291 if not self.opener.exists(file):
293 if not self.opener.exists(file):
292 return # no pending data for changelog
294 return # no pending data for changelog
293 r = revlog.revlog(self.opener, file)
295 r = revlog.revlog(self.opener, file)
294 self.index = r.index
296 self.index = r.index
295 self.nodemap = r.nodemap
297 self.nodemap = r.nodemap
296 self._nodecache = r._nodecache
298 self._nodecache = r._nodecache
297 self._chunkcache = r._chunkcache
299 self._chunkcache = r._chunkcache
298
300
299 def _writepending(self, tr):
301 def _writepending(self, tr):
300 "create a file containing the unfinalized state for pretxnchangegroup"
302 "create a file containing the unfinalized state for pretxnchangegroup"
301 if self._delaybuf:
303 if self._delaybuf:
302 # make a temporary copy of the index
304 # make a temporary copy of the index
303 fp1 = self._realopener(self.indexfile)
305 fp1 = self._realopener(self.indexfile)
304 pendingfilename = self.indexfile + ".a"
306 pendingfilename = self.indexfile + ".a"
305 # register as a temp file to ensure cleanup on failure
307 # register as a temp file to ensure cleanup on failure
306 tr.registertmp(pendingfilename)
308 tr.registertmp(pendingfilename)
307 # write existing data
309 # write existing data
308 fp2 = self._realopener(pendingfilename, "w")
310 fp2 = self._realopener(pendingfilename, "w")
309 fp2.write(fp1.read())
311 fp2.write(fp1.read())
310 # add pending data
312 # add pending data
311 fp2.write("".join(self._delaybuf))
313 fp2.write("".join(self._delaybuf))
312 fp2.close()
314 fp2.close()
313 # switch modes so finalize can simply rename
315 # switch modes so finalize can simply rename
314 self._delaybuf = None
316 self._delaybuf = None
315 self._divert = True
317 self._divert = True
316 self.opener = _divertopener(self._realopener, self.indexfile)
318 self.opener = _divertopener(self._realopener, self.indexfile)
317
319
318 if self._divert:
320 if self._divert:
319 return True
321 return True
320
322
321 return False
323 return False
322
324
323 def checkinlinesize(self, tr, fp=None):
325 def checkinlinesize(self, tr, fp=None):
324 if not self._delayed:
326 if not self._delayed:
325 revlog.revlog.checkinlinesize(self, tr, fp)
327 revlog.revlog.checkinlinesize(self, tr, fp)
326
328
327 def read(self, node):
329 def read(self, node):
328 """
330 """
329 format used:
331 format used:
330 nodeid\n : manifest node in ascii
332 nodeid\n : manifest node in ascii
331 user\n : user, no \n or \r allowed
333 user\n : user, no \n or \r allowed
332 time tz extra\n : date (time is int or float, timezone is int)
334 time tz extra\n : date (time is int or float, timezone is int)
333 : extra is metadata, encoded and separated by '\0'
335 : extra is metadata, encoded and separated by '\0'
334 : older versions ignore it
336 : older versions ignore it
335 files\n\n : files modified by the cset, no \n or \r allowed
337 files\n\n : files modified by the cset, no \n or \r allowed
336 (.*) : comment (free text, ideally utf-8)
338 (.*) : comment (free text, ideally utf-8)
337
339
338 changelog v0 doesn't use extra
340 changelog v0 doesn't use extra
339 """
341 """
340 text = self.revision(node)
342 text = self.revision(node)
341 if not text:
343 if not text:
342 return (nullid, "", (0, 0), [], "", _defaultextra)
344 return (nullid, "", (0, 0), [], "", _defaultextra)
343 last = text.index("\n\n")
345 last = text.index("\n\n")
344 desc = encoding.tolocal(text[last + 2:])
346 desc = encoding.tolocal(text[last + 2:])
345 l = text[:last].split('\n')
347 l = text[:last].split('\n')
346 manifest = bin(l[0])
348 manifest = bin(l[0])
347 user = encoding.tolocal(l[1])
349 user = encoding.tolocal(l[1])
348
350
349 tdata = l[2].split(' ', 2)
351 tdata = l[2].split(' ', 2)
350 if len(tdata) != 3:
352 if len(tdata) != 3:
351 time = float(tdata[0])
353 time = float(tdata[0])
352 try:
354 try:
353 # various tools did silly things with the time zone field.
355 # various tools did silly things with the time zone field.
354 timezone = int(tdata[1])
356 timezone = int(tdata[1])
355 except ValueError:
357 except ValueError:
356 timezone = 0
358 timezone = 0
357 extra = _defaultextra
359 extra = _defaultextra
358 else:
360 else:
359 time, timezone = float(tdata[0]), int(tdata[1])
361 time, timezone = float(tdata[0]), int(tdata[1])
360 extra = decodeextra(tdata[2])
362 extra = decodeextra(tdata[2])
361
363
362 files = l[3:]
364 files = l[3:]
363 return (manifest, user, (time, timezone), files, desc, extra)
365 return (manifest, user, (time, timezone), files, desc, extra)
364
366
365 def add(self, manifest, files, desc, transaction, p1, p2,
367 def add(self, manifest, files, desc, transaction, p1, p2,
366 user, date=None, extra=None):
368 user, date=None, extra=None):
367 # Convert to UTF-8 encoded bytestrings as the very first
369 # Convert to UTF-8 encoded bytestrings as the very first
368 # thing: calling any method on a localstr object will turn it
370 # thing: calling any method on a localstr object will turn it
369 # into a str object and the cached UTF-8 string is thus lost.
371 # into a str object and the cached UTF-8 string is thus lost.
370 user, desc = encoding.fromlocal(user), encoding.fromlocal(desc)
372 user, desc = encoding.fromlocal(user), encoding.fromlocal(desc)
371
373
372 user = user.strip()
374 user = user.strip()
373 # An empty username or a username with a "\n" will make the
375 # An empty username or a username with a "\n" will make the
374 # revision text contain two "\n\n" sequences -> corrupt
376 # revision text contain two "\n\n" sequences -> corrupt
375 # repository since read cannot unpack the revision.
377 # repository since read cannot unpack the revision.
376 if not user:
378 if not user:
377 raise error.RevlogError(_("empty username"))
379 raise error.RevlogError(_("empty username"))
378 if "\n" in user:
380 if "\n" in user:
379 raise error.RevlogError(_("username %s contains a newline")
381 raise error.RevlogError(_("username %s contains a newline")
380 % repr(user))
382 % repr(user))
381
383
382 desc = stripdesc(desc)
384 desc = stripdesc(desc)
383
385
384 if date:
386 if date:
385 parseddate = "%d %d" % util.parsedate(date)
387 parseddate = "%d %d" % util.parsedate(date)
386 else:
388 else:
387 parseddate = "%d %d" % util.makedate()
389 parseddate = "%d %d" % util.makedate()
388 if extra:
390 if extra:
389 branch = extra.get("branch")
391 branch = extra.get("branch")
390 if branch in ("default", ""):
392 if branch in ("default", ""):
391 del extra["branch"]
393 del extra["branch"]
392 elif branch in (".", "null", "tip"):
394 elif branch in (".", "null", "tip"):
393 raise error.RevlogError(_('the name \'%s\' is reserved')
395 raise error.RevlogError(_('the name \'%s\' is reserved')
394 % branch)
396 % branch)
395 if extra:
397 if extra:
396 extra = encodeextra(extra)
398 extra = encodeextra(extra)
397 parseddate = "%s %s" % (parseddate, extra)
399 parseddate = "%s %s" % (parseddate, extra)
398 l = [hex(manifest), user, parseddate] + sorted(files) + ["", desc]
400 l = [hex(manifest), user, parseddate] + sorted(files) + ["", desc]
399 text = "\n".join(l)
401 text = "\n".join(l)
400 return self.addrevision(text, transaction, len(self), p1, p2)
402 return self.addrevision(text, transaction, len(self), p1, p2)
401
403
402 def branchinfo(self, rev):
404 def branchinfo(self, rev):
403 """return the branch name and open/close state of a revision
405 """return the branch name and open/close state of a revision
404
406
405 This function exists because creating a changectx object
407 This function exists because creating a changectx object
406 just to access this is costly."""
408 just to access this is costly."""
407 extra = self.read(rev)[5]
409 extra = self.read(rev)[5]
408 return encoding.tolocal(extra.get("branch")), 'close' in extra
410 return encoding.tolocal(extra.get("branch")), 'close' in extra
@@ -1,185 +1,185
1 revlog.parseindex must be able to parse the index file even if
1 revlog.parseindex must be able to parse the index file even if
2 an index entry is split between two 64k blocks. The ideal test
2 an index entry is split between two 64k blocks. The ideal test
3 would be to create an index file with inline data where
3 would be to create an index file with inline data where
4 64k < size < 64k + 64 (64k is the size of the read buffer, 64 is
4 64k < size < 64k + 64 (64k is the size of the read buffer, 64 is
5 the size of an index entry) and with an index entry starting right
5 the size of an index entry) and with an index entry starting right
6 before the 64k block boundary, and try to read it.
6 before the 64k block boundary, and try to read it.
7 We approximate that by reducing the read buffer to 1 byte.
7 We approximate that by reducing the read buffer to 1 byte.
8
8
9 $ hg init a
9 $ hg init a
10 $ cd a
10 $ cd a
11 $ echo abc > foo
11 $ echo abc > foo
12 $ hg add foo
12 $ hg add foo
13 $ hg commit -m 'add foo'
13 $ hg commit -m 'add foo'
14 $ echo >> foo
14 $ echo >> foo
15 $ hg commit -m 'change foo'
15 $ hg commit -m 'change foo'
16 $ hg log -r 0:
16 $ hg log -r 0:
17 changeset: 0:7c31755bf9b5
17 changeset: 0:7c31755bf9b5
18 user: test
18 user: test
19 date: Thu Jan 01 00:00:00 1970 +0000
19 date: Thu Jan 01 00:00:00 1970 +0000
20 summary: add foo
20 summary: add foo
21
21
22 changeset: 1:26333235a41c
22 changeset: 1:26333235a41c
23 tag: tip
23 tag: tip
24 user: test
24 user: test
25 date: Thu Jan 01 00:00:00 1970 +0000
25 date: Thu Jan 01 00:00:00 1970 +0000
26 summary: change foo
26 summary: change foo
27
27
28 $ cat >> test.py << EOF
28 $ cat >> test.py << EOF
29 > from mercurial import changelog, scmutil
29 > from mercurial import changelog, scmutil
30 > from mercurial.node import *
30 > from mercurial.node import *
31 >
31 >
32 > class singlebyteread(object):
32 > class singlebyteread(object):
33 > def __init__(self, real):
33 > def __init__(self, real):
34 > self.real = real
34 > self.real = real
35 >
35 >
36 > def read(self, size=-1):
36 > def read(self, size=-1):
37 > if size == 65536:
37 > if size == 65536:
38 > size = 1
38 > size = 1
39 > return self.real.read(size)
39 > return self.real.read(size)
40 >
40 >
41 > def __getattr__(self, key):
41 > def __getattr__(self, key):
42 > return getattr(self.real, key)
42 > return getattr(self.real, key)
43 >
43 >
44 > def opener(*args):
44 > def opener(*args):
45 > o = scmutil.opener(*args)
45 > o = scmutil.opener(*args)
46 > def wrapper(*a):
46 > def wrapper(*a):
47 > f = o(*a)
47 > f = o(*a)
48 > return singlebyteread(f)
48 > return singlebyteread(f)
49 > return wrapper
49 > return wrapper
50 >
50 >
51 > cl = changelog.changelog(opener('.hg/store'))
51 > cl = changelog.changelog(opener('.hg/store'))
52 > print len(cl), 'revisions:'
52 > print len(cl), 'revisions:'
53 > for r in cl:
53 > for r in cl:
54 > print short(cl.node(r))
54 > print short(cl.node(r))
55 > EOF
55 > EOF
56 $ python test.py
56 $ python test.py
57 2 revisions:
57 2 revisions:
58 7c31755bf9b5
58 7c31755bf9b5
59 26333235a41c
59 26333235a41c
60
60
61 $ cd ..
61 $ cd ..
62
62
63 #if no-pure
63 #if no-pure
64
64
65 Test SEGV caused by bad revision passed to reachableroots() (issue4775):
65 Test SEGV caused by bad revision passed to reachableroots() (issue4775):
66
66
67 $ cd a
67 $ cd a
68
68
69 $ python <<EOF
69 $ python <<EOF
70 > from mercurial import changelog, scmutil
70 > from mercurial import changelog, scmutil
71 > cl = changelog.changelog(scmutil.vfs('.hg/store'))
71 > cl = changelog.changelog(scmutil.vfs('.hg/store'))
72 > print 'good heads:'
72 > print 'good heads:'
73 > for head in [0, len(cl) - 1, -1]:
73 > for head in [0, len(cl) - 1, -1]:
74 > print'%s: %r' % (head, cl.reachableroots(0, [head], [0]))
74 > print'%s: %r' % (head, cl.reachableroots(0, [head], [0]))
75 > print 'bad heads:'
75 > print 'bad heads:'
76 > for head in [len(cl), 10000, -2, -10000, None]:
76 > for head in [len(cl), 10000, -2, -10000, None]:
77 > print '%s:' % head,
77 > print '%s:' % head,
78 > try:
78 > try:
79 > cl.reachableroots(0, [head], [0])
79 > cl.reachableroots(0, [head], [0])
80 > print 'uncaught buffer overflow?'
80 > print 'uncaught buffer overflow?'
81 > except (IndexError, TypeError) as inst:
81 > except (IndexError, TypeError) as inst:
82 > print inst
82 > print inst
83 > print 'good roots:'
83 > print 'good roots:'
84 > for root in [0, len(cl) - 1, -1]:
84 > for root in [0, len(cl) - 1, -1]:
85 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
85 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
86 > print 'out-of-range roots are ignored:'
86 > print 'out-of-range roots are ignored:'
87 > for root in [len(cl), 10000, -2, -10000]:
87 > for root in [len(cl), 10000, -2, -10000]:
88 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
88 > print '%s: %r' % (root, cl.reachableroots(root, [len(cl) - 1], [root]))
89 > print 'bad roots:'
89 > print 'bad roots:'
90 > for root in [None]:
90 > for root in [None]:
91 > print '%s:' % root,
91 > print '%s:' % root,
92 > try:
92 > try:
93 > cl.reachableroots(root, [len(cl) - 1], [root])
93 > cl.reachableroots(root, [len(cl) - 1], [root])
94 > print 'uncaught error?'
94 > print 'uncaught error?'
95 > except TypeError as inst:
95 > except TypeError as inst:
96 > print inst
96 > print inst
97 > EOF
97 > EOF
98 good heads:
98 good heads:
99 0: <baseset [0]>
99 0: <baseset+ [0]>
100 1: <baseset [0]>
100 1: <baseset+ [0]>
101 -1: <baseset []>
101 -1: <baseset+ []>
102 bad heads:
102 bad heads:
103 2: head out of range
103 2: head out of range
104 10000: head out of range
104 10000: head out of range
105 -2: head out of range
105 -2: head out of range
106 -10000: head out of range
106 -10000: head out of range
107 None: an integer is required
107 None: an integer is required
108 good roots:
108 good roots:
109 0: <baseset [0]>
109 0: <baseset+ [0]>
110 1: <baseset [1]>
110 1: <baseset+ [1]>
111 -1: <baseset [-1]>
111 -1: <baseset+ [-1]>
112 out-of-range roots are ignored:
112 out-of-range roots are ignored:
113 2: <baseset []>
113 2: <baseset+ []>
114 10000: <baseset []>
114 10000: <baseset+ []>
115 -2: <baseset []>
115 -2: <baseset+ []>
116 -10000: <baseset []>
116 -10000: <baseset+ []>
117 bad roots:
117 bad roots:
118 None: an integer is required
118 None: an integer is required
119
119
120 $ cd ..
120 $ cd ..
121
121
122 Test corrupted p1/p2 fields that could cause SEGV at parsers.c:
122 Test corrupted p1/p2 fields that could cause SEGV at parsers.c:
123
123
124 $ mkdir invalidparent
124 $ mkdir invalidparent
125 $ cd invalidparent
125 $ cd invalidparent
126
126
127 $ hg clone --pull -q --config phases.publish=False ../a limit
127 $ hg clone --pull -q --config phases.publish=False ../a limit
128 $ hg clone --pull -q --config phases.publish=False ../a segv
128 $ hg clone --pull -q --config phases.publish=False ../a segv
129 $ rm -R limit/.hg/cache segv/.hg/cache
129 $ rm -R limit/.hg/cache segv/.hg/cache
130
130
131 $ python <<EOF
131 $ python <<EOF
132 > data = open("limit/.hg/store/00changelog.i", "rb").read()
132 > data = open("limit/.hg/store/00changelog.i", "rb").read()
133 > for n, p in [('limit', '\0\0\0\x02'), ('segv', '\0\x01\0\0')]:
133 > for n, p in [('limit', '\0\0\0\x02'), ('segv', '\0\x01\0\0')]:
134 > # corrupt p1 at rev0 and p2 at rev1
134 > # corrupt p1 at rev0 and p2 at rev1
135 > d = data[:24] + p + data[28:127 + 28] + p + data[127 + 32:]
135 > d = data[:24] + p + data[28:127 + 28] + p + data[127 + 32:]
136 > open(n + "/.hg/store/00changelog.i", "wb").write(d)
136 > open(n + "/.hg/store/00changelog.i", "wb").write(d)
137 > EOF
137 > EOF
138
138
139 $ hg debugindex -f1 limit/.hg/store/00changelog.i
139 $ hg debugindex -f1 limit/.hg/store/00changelog.i
140 rev flag offset length size base link p1 p2 nodeid
140 rev flag offset length size base link p1 p2 nodeid
141 0 0000 0 63 62 0 0 2 -1 7c31755bf9b5
141 0 0000 0 63 62 0 0 2 -1 7c31755bf9b5
142 1 0000 63 66 65 1 1 0 2 26333235a41c
142 1 0000 63 66 65 1 1 0 2 26333235a41c
143 $ hg debugindex -f1 segv/.hg/store/00changelog.i
143 $ hg debugindex -f1 segv/.hg/store/00changelog.i
144 rev flag offset length size base link p1 p2 nodeid
144 rev flag offset length size base link p1 p2 nodeid
145 0 0000 0 63 62 0 0 65536 -1 7c31755bf9b5
145 0 0000 0 63 62 0 0 65536 -1 7c31755bf9b5
146 1 0000 63 66 65 1 1 0 65536 26333235a41c
146 1 0000 63 66 65 1 1 0 65536 26333235a41c
147
147
148 $ cat <<EOF > test.py
148 $ cat <<EOF > test.py
149 > import sys
149 > import sys
150 > from mercurial import changelog, scmutil
150 > from mercurial import changelog, scmutil
151 > cl = changelog.changelog(scmutil.vfs(sys.argv[1]))
151 > cl = changelog.changelog(scmutil.vfs(sys.argv[1]))
152 > n0, n1 = cl.node(0), cl.node(1)
152 > n0, n1 = cl.node(0), cl.node(1)
153 > ops = [
153 > ops = [
154 > ('reachableroots',
154 > ('reachableroots',
155 > lambda: cl.index.reachableroots2(0, [1], [0], False)),
155 > lambda: cl.index.reachableroots2(0, [1], [0], False)),
156 > ('compute_phases_map_sets', lambda: cl.computephases([[0], []])),
156 > ('compute_phases_map_sets', lambda: cl.computephases([[0], []])),
157 > ('index_headrevs', lambda: cl.headrevs()),
157 > ('index_headrevs', lambda: cl.headrevs()),
158 > ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)),
158 > ('find_gca_candidates', lambda: cl.commonancestorsheads(n0, n1)),
159 > ('find_deepest', lambda: cl.ancestor(n0, n1)),
159 > ('find_deepest', lambda: cl.ancestor(n0, n1)),
160 > ]
160 > ]
161 > for l, f in ops:
161 > for l, f in ops:
162 > print l + ':',
162 > print l + ':',
163 > try:
163 > try:
164 > f()
164 > f()
165 > print 'uncaught buffer overflow?'
165 > print 'uncaught buffer overflow?'
166 > except ValueError, inst:
166 > except ValueError, inst:
167 > print inst
167 > print inst
168 > EOF
168 > EOF
169
169
170 $ python test.py limit/.hg/store
170 $ python test.py limit/.hg/store
171 reachableroots: parent out of range
171 reachableroots: parent out of range
172 compute_phases_map_sets: parent out of range
172 compute_phases_map_sets: parent out of range
173 index_headrevs: parent out of range
173 index_headrevs: parent out of range
174 find_gca_candidates: parent out of range
174 find_gca_candidates: parent out of range
175 find_deepest: parent out of range
175 find_deepest: parent out of range
176 $ python test.py segv/.hg/store
176 $ python test.py segv/.hg/store
177 reachableroots: parent out of range
177 reachableroots: parent out of range
178 compute_phases_map_sets: parent out of range
178 compute_phases_map_sets: parent out of range
179 index_headrevs: parent out of range
179 index_headrevs: parent out of range
180 find_gca_candidates: parent out of range
180 find_gca_candidates: parent out of range
181 find_deepest: parent out of range
181 find_deepest: parent out of range
182
182
183 $ cd ..
183 $ cd ..
184
184
185 #endif
185 #endif
@@ -1,2169 +1,2169
1 $ HGENCODING=utf-8
1 $ HGENCODING=utf-8
2 $ export HGENCODING
2 $ export HGENCODING
3 $ cat > testrevset.py << EOF
3 $ cat > testrevset.py << EOF
4 > import mercurial.revset
4 > import mercurial.revset
5 >
5 >
6 > baseset = mercurial.revset.baseset
6 > baseset = mercurial.revset.baseset
7 >
7 >
8 > def r3232(repo, subset, x):
8 > def r3232(repo, subset, x):
9 > """"simple revset that return [3,2,3,2]
9 > """"simple revset that return [3,2,3,2]
10 >
10 >
11 > revisions duplicated on purpose.
11 > revisions duplicated on purpose.
12 > """
12 > """
13 > if 3 not in subset:
13 > if 3 not in subset:
14 > if 2 in subset:
14 > if 2 in subset:
15 > return baseset([2,2])
15 > return baseset([2,2])
16 > return baseset()
16 > return baseset()
17 > return baseset([3,3,2,2])
17 > return baseset([3,3,2,2])
18 >
18 >
19 > mercurial.revset.symbols['r3232'] = r3232
19 > mercurial.revset.symbols['r3232'] = r3232
20 > EOF
20 > EOF
21 $ cat >> $HGRCPATH << EOF
21 $ cat >> $HGRCPATH << EOF
22 > [extensions]
22 > [extensions]
23 > testrevset=$TESTTMP/testrevset.py
23 > testrevset=$TESTTMP/testrevset.py
24 > EOF
24 > EOF
25
25
26 $ try() {
26 $ try() {
27 > hg debugrevspec --debug "$@"
27 > hg debugrevspec --debug "$@"
28 > }
28 > }
29
29
30 $ log() {
30 $ log() {
31 > hg log --template '{rev}\n' -r "$1"
31 > hg log --template '{rev}\n' -r "$1"
32 > }
32 > }
33
33
34 $ hg init repo
34 $ hg init repo
35 $ cd repo
35 $ cd repo
36
36
37 $ echo a > a
37 $ echo a > a
38 $ hg branch a
38 $ hg branch a
39 marked working directory as branch a
39 marked working directory as branch a
40 (branches are permanent and global, did you want a bookmark?)
40 (branches are permanent and global, did you want a bookmark?)
41 $ hg ci -Aqm0
41 $ hg ci -Aqm0
42
42
43 $ echo b > b
43 $ echo b > b
44 $ hg branch b
44 $ hg branch b
45 marked working directory as branch b
45 marked working directory as branch b
46 $ hg ci -Aqm1
46 $ hg ci -Aqm1
47
47
48 $ rm a
48 $ rm a
49 $ hg branch a-b-c-
49 $ hg branch a-b-c-
50 marked working directory as branch a-b-c-
50 marked working directory as branch a-b-c-
51 $ hg ci -Aqm2 -u Bob
51 $ hg ci -Aqm2 -u Bob
52
52
53 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
53 $ hg log -r "extra('branch', 'a-b-c-')" --template '{rev}\n'
54 2
54 2
55 $ hg log -r "extra('branch')" --template '{rev}\n'
55 $ hg log -r "extra('branch')" --template '{rev}\n'
56 0
56 0
57 1
57 1
58 2
58 2
59 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
59 $ hg log -r "extra('branch', 're:a')" --template '{rev} {branch}\n'
60 0 a
60 0 a
61 2 a-b-c-
61 2 a-b-c-
62
62
63 $ hg co 1
63 $ hg co 1
64 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
65 $ hg branch +a+b+c+
65 $ hg branch +a+b+c+
66 marked working directory as branch +a+b+c+
66 marked working directory as branch +a+b+c+
67 $ hg ci -Aqm3
67 $ hg ci -Aqm3
68
68
69 $ hg co 2 # interleave
69 $ hg co 2 # interleave
70 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
70 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
71 $ echo bb > b
71 $ echo bb > b
72 $ hg branch -- -a-b-c-
72 $ hg branch -- -a-b-c-
73 marked working directory as branch -a-b-c-
73 marked working directory as branch -a-b-c-
74 $ hg ci -Aqm4 -d "May 12 2005"
74 $ hg ci -Aqm4 -d "May 12 2005"
75
75
76 $ hg co 3
76 $ hg co 3
77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 $ hg branch !a/b/c/
78 $ hg branch !a/b/c/
79 marked working directory as branch !a/b/c/
79 marked working directory as branch !a/b/c/
80 $ hg ci -Aqm"5 bug"
80 $ hg ci -Aqm"5 bug"
81
81
82 $ hg merge 4
82 $ hg merge 4
83 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
83 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
84 (branch merge, don't forget to commit)
84 (branch merge, don't forget to commit)
85 $ hg branch _a_b_c_
85 $ hg branch _a_b_c_
86 marked working directory as branch _a_b_c_
86 marked working directory as branch _a_b_c_
87 $ hg ci -Aqm"6 issue619"
87 $ hg ci -Aqm"6 issue619"
88
88
89 $ hg branch .a.b.c.
89 $ hg branch .a.b.c.
90 marked working directory as branch .a.b.c.
90 marked working directory as branch .a.b.c.
91 $ hg ci -Aqm7
91 $ hg ci -Aqm7
92
92
93 $ hg branch all
93 $ hg branch all
94 marked working directory as branch all
94 marked working directory as branch all
95
95
96 $ hg co 4
96 $ hg co 4
97 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
97 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
98 $ hg branch Γ©
98 $ hg branch Γ©
99 marked working directory as branch \xc3\xa9 (esc)
99 marked working directory as branch \xc3\xa9 (esc)
100 $ hg ci -Aqm9
100 $ hg ci -Aqm9
101
101
102 $ hg tag -r6 1.0
102 $ hg tag -r6 1.0
103 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
103 $ hg bookmark -r6 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
104
104
105 $ hg clone --quiet -U -r 7 . ../remote1
105 $ hg clone --quiet -U -r 7 . ../remote1
106 $ hg clone --quiet -U -r 8 . ../remote2
106 $ hg clone --quiet -U -r 8 . ../remote2
107 $ echo "[paths]" >> .hg/hgrc
107 $ echo "[paths]" >> .hg/hgrc
108 $ echo "default = ../remote1" >> .hg/hgrc
108 $ echo "default = ../remote1" >> .hg/hgrc
109
109
110 trivial
110 trivial
111
111
112 $ try 0:1
112 $ try 0:1
113 (range
113 (range
114 ('symbol', '0')
114 ('symbol', '0')
115 ('symbol', '1'))
115 ('symbol', '1'))
116 * set:
116 * set:
117 <spanset+ 0:1>
117 <spanset+ 0:1>
118 0
118 0
119 1
119 1
120 $ try --optimize :
120 $ try --optimize :
121 (rangeall
121 (rangeall
122 None)
122 None)
123 * optimized:
123 * optimized:
124 (range
124 (range
125 ('string', '0')
125 ('string', '0')
126 ('string', 'tip'))
126 ('string', 'tip'))
127 * set:
127 * set:
128 <spanset+ 0:9>
128 <spanset+ 0:9>
129 0
129 0
130 1
130 1
131 2
131 2
132 3
132 3
133 4
133 4
134 5
134 5
135 6
135 6
136 7
136 7
137 8
137 8
138 9
138 9
139 $ try 3::6
139 $ try 3::6
140 (dagrange
140 (dagrange
141 ('symbol', '3')
141 ('symbol', '3')
142 ('symbol', '6'))
142 ('symbol', '6'))
143 * set:
143 * set:
144 <baseset [3, 5, 6]>
144 <baseset+ [3, 5, 6]>
145 3
145 3
146 5
146 5
147 6
147 6
148 $ try '0|1|2'
148 $ try '0|1|2'
149 (or
149 (or
150 ('symbol', '0')
150 ('symbol', '0')
151 ('symbol', '1')
151 ('symbol', '1')
152 ('symbol', '2'))
152 ('symbol', '2'))
153 * set:
153 * set:
154 <baseset [0, 1, 2]>
154 <baseset [0, 1, 2]>
155 0
155 0
156 1
156 1
157 2
157 2
158
158
159 names that should work without quoting
159 names that should work without quoting
160
160
161 $ try a
161 $ try a
162 ('symbol', 'a')
162 ('symbol', 'a')
163 * set:
163 * set:
164 <baseset [0]>
164 <baseset [0]>
165 0
165 0
166 $ try b-a
166 $ try b-a
167 (minus
167 (minus
168 ('symbol', 'b')
168 ('symbol', 'b')
169 ('symbol', 'a'))
169 ('symbol', 'a'))
170 * set:
170 * set:
171 <filteredset
171 <filteredset
172 <baseset [1]>>
172 <baseset [1]>>
173 1
173 1
174 $ try _a_b_c_
174 $ try _a_b_c_
175 ('symbol', '_a_b_c_')
175 ('symbol', '_a_b_c_')
176 * set:
176 * set:
177 <baseset [6]>
177 <baseset [6]>
178 6
178 6
179 $ try _a_b_c_-a
179 $ try _a_b_c_-a
180 (minus
180 (minus
181 ('symbol', '_a_b_c_')
181 ('symbol', '_a_b_c_')
182 ('symbol', 'a'))
182 ('symbol', 'a'))
183 * set:
183 * set:
184 <filteredset
184 <filteredset
185 <baseset [6]>>
185 <baseset [6]>>
186 6
186 6
187 $ try .a.b.c.
187 $ try .a.b.c.
188 ('symbol', '.a.b.c.')
188 ('symbol', '.a.b.c.')
189 * set:
189 * set:
190 <baseset [7]>
190 <baseset [7]>
191 7
191 7
192 $ try .a.b.c.-a
192 $ try .a.b.c.-a
193 (minus
193 (minus
194 ('symbol', '.a.b.c.')
194 ('symbol', '.a.b.c.')
195 ('symbol', 'a'))
195 ('symbol', 'a'))
196 * set:
196 * set:
197 <filteredset
197 <filteredset
198 <baseset [7]>>
198 <baseset [7]>>
199 7
199 7
200
200
201 names that should be caught by fallback mechanism
201 names that should be caught by fallback mechanism
202
202
203 $ try -- '-a-b-c-'
203 $ try -- '-a-b-c-'
204 ('symbol', '-a-b-c-')
204 ('symbol', '-a-b-c-')
205 * set:
205 * set:
206 <baseset [4]>
206 <baseset [4]>
207 4
207 4
208 $ log -a-b-c-
208 $ log -a-b-c-
209 4
209 4
210 $ try '+a+b+c+'
210 $ try '+a+b+c+'
211 ('symbol', '+a+b+c+')
211 ('symbol', '+a+b+c+')
212 * set:
212 * set:
213 <baseset [3]>
213 <baseset [3]>
214 3
214 3
215 $ try '+a+b+c+:'
215 $ try '+a+b+c+:'
216 (rangepost
216 (rangepost
217 ('symbol', '+a+b+c+'))
217 ('symbol', '+a+b+c+'))
218 * set:
218 * set:
219 <spanset+ 3:9>
219 <spanset+ 3:9>
220 3
220 3
221 4
221 4
222 5
222 5
223 6
223 6
224 7
224 7
225 8
225 8
226 9
226 9
227 $ try ':+a+b+c+'
227 $ try ':+a+b+c+'
228 (rangepre
228 (rangepre
229 ('symbol', '+a+b+c+'))
229 ('symbol', '+a+b+c+'))
230 * set:
230 * set:
231 <spanset+ 0:3>
231 <spanset+ 0:3>
232 0
232 0
233 1
233 1
234 2
234 2
235 3
235 3
236 $ try -- '-a-b-c-:+a+b+c+'
236 $ try -- '-a-b-c-:+a+b+c+'
237 (range
237 (range
238 ('symbol', '-a-b-c-')
238 ('symbol', '-a-b-c-')
239 ('symbol', '+a+b+c+'))
239 ('symbol', '+a+b+c+'))
240 * set:
240 * set:
241 <spanset- 3:4>
241 <spanset- 3:4>
242 4
242 4
243 3
243 3
244 $ log '-a-b-c-:+a+b+c+'
244 $ log '-a-b-c-:+a+b+c+'
245 4
245 4
246 3
246 3
247
247
248 $ try -- -a-b-c--a # complains
248 $ try -- -a-b-c--a # complains
249 (minus
249 (minus
250 (minus
250 (minus
251 (minus
251 (minus
252 (negate
252 (negate
253 ('symbol', 'a'))
253 ('symbol', 'a'))
254 ('symbol', 'b'))
254 ('symbol', 'b'))
255 ('symbol', 'c'))
255 ('symbol', 'c'))
256 (negate
256 (negate
257 ('symbol', 'a')))
257 ('symbol', 'a')))
258 abort: unknown revision '-a'!
258 abort: unknown revision '-a'!
259 [255]
259 [255]
260 $ try Γ©
260 $ try Γ©
261 ('symbol', '\xc3\xa9')
261 ('symbol', '\xc3\xa9')
262 * set:
262 * set:
263 <baseset [9]>
263 <baseset [9]>
264 9
264 9
265
265
266 no quoting needed
266 no quoting needed
267
267
268 $ log ::a-b-c-
268 $ log ::a-b-c-
269 0
269 0
270 1
270 1
271 2
271 2
272
272
273 quoting needed
273 quoting needed
274
274
275 $ try '"-a-b-c-"-a'
275 $ try '"-a-b-c-"-a'
276 (minus
276 (minus
277 ('string', '-a-b-c-')
277 ('string', '-a-b-c-')
278 ('symbol', 'a'))
278 ('symbol', 'a'))
279 * set:
279 * set:
280 <filteredset
280 <filteredset
281 <baseset [4]>>
281 <baseset [4]>>
282 4
282 4
283
283
284 $ log '1 or 2'
284 $ log '1 or 2'
285 1
285 1
286 2
286 2
287 $ log '1|2'
287 $ log '1|2'
288 1
288 1
289 2
289 2
290 $ log '1 and 2'
290 $ log '1 and 2'
291 $ log '1&2'
291 $ log '1&2'
292 $ try '1&2|3' # precedence - and is higher
292 $ try '1&2|3' # precedence - and is higher
293 (or
293 (or
294 (and
294 (and
295 ('symbol', '1')
295 ('symbol', '1')
296 ('symbol', '2'))
296 ('symbol', '2'))
297 ('symbol', '3'))
297 ('symbol', '3'))
298 * set:
298 * set:
299 <addset
299 <addset
300 <baseset []>,
300 <baseset []>,
301 <baseset [3]>>
301 <baseset [3]>>
302 3
302 3
303 $ try '1|2&3'
303 $ try '1|2&3'
304 (or
304 (or
305 ('symbol', '1')
305 ('symbol', '1')
306 (and
306 (and
307 ('symbol', '2')
307 ('symbol', '2')
308 ('symbol', '3')))
308 ('symbol', '3')))
309 * set:
309 * set:
310 <addset
310 <addset
311 <baseset [1]>,
311 <baseset [1]>,
312 <baseset []>>
312 <baseset []>>
313 1
313 1
314 $ try '1&2&3' # associativity
314 $ try '1&2&3' # associativity
315 (and
315 (and
316 (and
316 (and
317 ('symbol', '1')
317 ('symbol', '1')
318 ('symbol', '2'))
318 ('symbol', '2'))
319 ('symbol', '3'))
319 ('symbol', '3'))
320 * set:
320 * set:
321 <baseset []>
321 <baseset []>
322 $ try '1|(2|3)'
322 $ try '1|(2|3)'
323 (or
323 (or
324 ('symbol', '1')
324 ('symbol', '1')
325 (group
325 (group
326 (or
326 (or
327 ('symbol', '2')
327 ('symbol', '2')
328 ('symbol', '3'))))
328 ('symbol', '3'))))
329 * set:
329 * set:
330 <addset
330 <addset
331 <baseset [1]>,
331 <baseset [1]>,
332 <baseset [2, 3]>>
332 <baseset [2, 3]>>
333 1
333 1
334 2
334 2
335 3
335 3
336 $ log '1.0' # tag
336 $ log '1.0' # tag
337 6
337 6
338 $ log 'a' # branch
338 $ log 'a' # branch
339 0
339 0
340 $ log '2785f51ee'
340 $ log '2785f51ee'
341 0
341 0
342 $ log 'date(2005)'
342 $ log 'date(2005)'
343 4
343 4
344 $ log 'date(this is a test)'
344 $ log 'date(this is a test)'
345 hg: parse error at 10: unexpected token: symbol
345 hg: parse error at 10: unexpected token: symbol
346 [255]
346 [255]
347 $ log 'date()'
347 $ log 'date()'
348 hg: parse error: date requires a string
348 hg: parse error: date requires a string
349 [255]
349 [255]
350 $ log 'date'
350 $ log 'date'
351 abort: unknown revision 'date'!
351 abort: unknown revision 'date'!
352 [255]
352 [255]
353 $ log 'date('
353 $ log 'date('
354 hg: parse error at 5: not a prefix: end
354 hg: parse error at 5: not a prefix: end
355 [255]
355 [255]
356 $ log 'date(tip)'
356 $ log 'date(tip)'
357 abort: invalid date: 'tip'
357 abort: invalid date: 'tip'
358 [255]
358 [255]
359 $ log '0:date'
359 $ log '0:date'
360 abort: unknown revision 'date'!
360 abort: unknown revision 'date'!
361 [255]
361 [255]
362 $ log '::"date"'
362 $ log '::"date"'
363 abort: unknown revision 'date'!
363 abort: unknown revision 'date'!
364 [255]
364 [255]
365 $ hg book date -r 4
365 $ hg book date -r 4
366 $ log '0:date'
366 $ log '0:date'
367 0
367 0
368 1
368 1
369 2
369 2
370 3
370 3
371 4
371 4
372 $ log '::date'
372 $ log '::date'
373 0
373 0
374 1
374 1
375 2
375 2
376 4
376 4
377 $ log '::"date"'
377 $ log '::"date"'
378 0
378 0
379 1
379 1
380 2
380 2
381 4
381 4
382 $ log 'date(2005) and 1::'
382 $ log 'date(2005) and 1::'
383 4
383 4
384 $ hg book -d date
384 $ hg book -d date
385
385
386 keyword arguments
386 keyword arguments
387
387
388 $ log 'extra(branch, value=a)'
388 $ log 'extra(branch, value=a)'
389 0
389 0
390
390
391 $ log 'extra(branch, a, b)'
391 $ log 'extra(branch, a, b)'
392 hg: parse error: extra takes at most 2 arguments
392 hg: parse error: extra takes at most 2 arguments
393 [255]
393 [255]
394 $ log 'extra(a, label=b)'
394 $ log 'extra(a, label=b)'
395 hg: parse error: extra got multiple values for keyword argument 'label'
395 hg: parse error: extra got multiple values for keyword argument 'label'
396 [255]
396 [255]
397 $ log 'extra(label=branch, default)'
397 $ log 'extra(label=branch, default)'
398 hg: parse error: extra got an invalid argument
398 hg: parse error: extra got an invalid argument
399 [255]
399 [255]
400 $ log 'extra(branch, foo+bar=baz)'
400 $ log 'extra(branch, foo+bar=baz)'
401 hg: parse error: extra got an invalid argument
401 hg: parse error: extra got an invalid argument
402 [255]
402 [255]
403 $ log 'extra(unknown=branch)'
403 $ log 'extra(unknown=branch)'
404 hg: parse error: extra got an unexpected keyword argument 'unknown'
404 hg: parse error: extra got an unexpected keyword argument 'unknown'
405 [255]
405 [255]
406
406
407 $ try 'foo=bar|baz'
407 $ try 'foo=bar|baz'
408 (keyvalue
408 (keyvalue
409 ('symbol', 'foo')
409 ('symbol', 'foo')
410 (or
410 (or
411 ('symbol', 'bar')
411 ('symbol', 'bar')
412 ('symbol', 'baz')))
412 ('symbol', 'baz')))
413 hg: parse error: can't use a key-value pair in this context
413 hg: parse error: can't use a key-value pair in this context
414 [255]
414 [255]
415
415
416 Test that symbols only get parsed as functions if there's an opening
416 Test that symbols only get parsed as functions if there's an opening
417 parenthesis.
417 parenthesis.
418
418
419 $ hg book only -r 9
419 $ hg book only -r 9
420 $ log 'only(only)' # Outer "only" is a function, inner "only" is the bookmark
420 $ log 'only(only)' # Outer "only" is a function, inner "only" is the bookmark
421 8
421 8
422 9
422 9
423
423
424 ancestor can accept 0 or more arguments
424 ancestor can accept 0 or more arguments
425
425
426 $ log 'ancestor()'
426 $ log 'ancestor()'
427 $ log 'ancestor(1)'
427 $ log 'ancestor(1)'
428 1
428 1
429 $ log 'ancestor(4,5)'
429 $ log 'ancestor(4,5)'
430 1
430 1
431 $ log 'ancestor(4,5) and 4'
431 $ log 'ancestor(4,5) and 4'
432 $ log 'ancestor(0,0,1,3)'
432 $ log 'ancestor(0,0,1,3)'
433 0
433 0
434 $ log 'ancestor(3,1,5,3,5,1)'
434 $ log 'ancestor(3,1,5,3,5,1)'
435 1
435 1
436 $ log 'ancestor(0,1,3,5)'
436 $ log 'ancestor(0,1,3,5)'
437 0
437 0
438 $ log 'ancestor(1,2,3,4,5)'
438 $ log 'ancestor(1,2,3,4,5)'
439 1
439 1
440
440
441 test ancestors
441 test ancestors
442
442
443 $ log 'ancestors(5)'
443 $ log 'ancestors(5)'
444 0
444 0
445 1
445 1
446 3
446 3
447 5
447 5
448 $ log 'ancestor(ancestors(5))'
448 $ log 'ancestor(ancestors(5))'
449 0
449 0
450 $ log '::r3232()'
450 $ log '::r3232()'
451 0
451 0
452 1
452 1
453 2
453 2
454 3
454 3
455
455
456 $ log 'author(bob)'
456 $ log 'author(bob)'
457 2
457 2
458 $ log 'author("re:bob|test")'
458 $ log 'author("re:bob|test")'
459 0
459 0
460 1
460 1
461 2
461 2
462 3
462 3
463 4
463 4
464 5
464 5
465 6
465 6
466 7
466 7
467 8
467 8
468 9
468 9
469 $ log 'branch(Γ©)'
469 $ log 'branch(Γ©)'
470 8
470 8
471 9
471 9
472 $ log 'branch(a)'
472 $ log 'branch(a)'
473 0
473 0
474 $ hg log -r 'branch("re:a")' --template '{rev} {branch}\n'
474 $ hg log -r 'branch("re:a")' --template '{rev} {branch}\n'
475 0 a
475 0 a
476 2 a-b-c-
476 2 a-b-c-
477 3 +a+b+c+
477 3 +a+b+c+
478 4 -a-b-c-
478 4 -a-b-c-
479 5 !a/b/c/
479 5 !a/b/c/
480 6 _a_b_c_
480 6 _a_b_c_
481 7 .a.b.c.
481 7 .a.b.c.
482 $ log 'children(ancestor(4,5))'
482 $ log 'children(ancestor(4,5))'
483 2
483 2
484 3
484 3
485 $ log 'closed()'
485 $ log 'closed()'
486 $ log 'contains(a)'
486 $ log 'contains(a)'
487 0
487 0
488 1
488 1
489 3
489 3
490 5
490 5
491 $ log 'contains("../repo/a")'
491 $ log 'contains("../repo/a")'
492 0
492 0
493 1
493 1
494 3
494 3
495 5
495 5
496 $ log 'desc(B)'
496 $ log 'desc(B)'
497 5
497 5
498 $ log 'descendants(2 or 3)'
498 $ log 'descendants(2 or 3)'
499 2
499 2
500 3
500 3
501 4
501 4
502 5
502 5
503 6
503 6
504 7
504 7
505 8
505 8
506 9
506 9
507 $ log 'file("b*")'
507 $ log 'file("b*")'
508 1
508 1
509 4
509 4
510 $ log 'filelog("b")'
510 $ log 'filelog("b")'
511 1
511 1
512 4
512 4
513 $ log 'filelog("../repo/b")'
513 $ log 'filelog("../repo/b")'
514 1
514 1
515 4
515 4
516 $ log 'follow()'
516 $ log 'follow()'
517 0
517 0
518 1
518 1
519 2
519 2
520 4
520 4
521 8
521 8
522 9
522 9
523 $ log 'grep("issue\d+")'
523 $ log 'grep("issue\d+")'
524 6
524 6
525 $ try 'grep("(")' # invalid regular expression
525 $ try 'grep("(")' # invalid regular expression
526 (func
526 (func
527 ('symbol', 'grep')
527 ('symbol', 'grep')
528 ('string', '('))
528 ('string', '('))
529 hg: parse error: invalid match pattern: unbalanced parenthesis
529 hg: parse error: invalid match pattern: unbalanced parenthesis
530 [255]
530 [255]
531 $ try 'grep("\bissue\d+")'
531 $ try 'grep("\bissue\d+")'
532 (func
532 (func
533 ('symbol', 'grep')
533 ('symbol', 'grep')
534 ('string', '\x08issue\\d+'))
534 ('string', '\x08issue\\d+'))
535 * set:
535 * set:
536 <filteredset
536 <filteredset
537 <fullreposet+ 0:9>>
537 <fullreposet+ 0:9>>
538 $ try 'grep(r"\bissue\d+")'
538 $ try 'grep(r"\bissue\d+")'
539 (func
539 (func
540 ('symbol', 'grep')
540 ('symbol', 'grep')
541 ('string', '\\bissue\\d+'))
541 ('string', '\\bissue\\d+'))
542 * set:
542 * set:
543 <filteredset
543 <filteredset
544 <fullreposet+ 0:9>>
544 <fullreposet+ 0:9>>
545 6
545 6
546 $ try 'grep(r"\")'
546 $ try 'grep(r"\")'
547 hg: parse error at 7: unterminated string
547 hg: parse error at 7: unterminated string
548 [255]
548 [255]
549 $ log 'head()'
549 $ log 'head()'
550 0
550 0
551 1
551 1
552 2
552 2
553 3
553 3
554 4
554 4
555 5
555 5
556 6
556 6
557 7
557 7
558 9
558 9
559 $ log 'heads(6::)'
559 $ log 'heads(6::)'
560 7
560 7
561 $ log 'keyword(issue)'
561 $ log 'keyword(issue)'
562 6
562 6
563 $ log 'keyword("test a")'
563 $ log 'keyword("test a")'
564 $ log 'limit(head(), 1)'
564 $ log 'limit(head(), 1)'
565 0
565 0
566 $ log 'matching(6)'
566 $ log 'matching(6)'
567 6
567 6
568 $ log 'matching(6:7, "phase parents user date branch summary files description substate")'
568 $ log 'matching(6:7, "phase parents user date branch summary files description substate")'
569 6
569 6
570 7
570 7
571
571
572 Testing min and max
572 Testing min and max
573
573
574 max: simple
574 max: simple
575
575
576 $ log 'max(contains(a))'
576 $ log 'max(contains(a))'
577 5
577 5
578
578
579 max: simple on unordered set)
579 max: simple on unordered set)
580
580
581 $ log 'max((4+0+2+5+7) and contains(a))'
581 $ log 'max((4+0+2+5+7) and contains(a))'
582 5
582 5
583
583
584 max: no result
584 max: no result
585
585
586 $ log 'max(contains(stringthatdoesnotappearanywhere))'
586 $ log 'max(contains(stringthatdoesnotappearanywhere))'
587
587
588 max: no result on unordered set
588 max: no result on unordered set
589
589
590 $ log 'max((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
590 $ log 'max((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
591
591
592 min: simple
592 min: simple
593
593
594 $ log 'min(contains(a))'
594 $ log 'min(contains(a))'
595 0
595 0
596
596
597 min: simple on unordered set
597 min: simple on unordered set
598
598
599 $ log 'min((4+0+2+5+7) and contains(a))'
599 $ log 'min((4+0+2+5+7) and contains(a))'
600 0
600 0
601
601
602 min: empty
602 min: empty
603
603
604 $ log 'min(contains(stringthatdoesnotappearanywhere))'
604 $ log 'min(contains(stringthatdoesnotappearanywhere))'
605
605
606 min: empty on unordered set
606 min: empty on unordered set
607
607
608 $ log 'min((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
608 $ log 'min((4+0+2+5+7) and contains(stringthatdoesnotappearanywhere))'
609
609
610
610
611 $ log 'merge()'
611 $ log 'merge()'
612 6
612 6
613 $ log 'branchpoint()'
613 $ log 'branchpoint()'
614 1
614 1
615 4
615 4
616 $ log 'modifies(b)'
616 $ log 'modifies(b)'
617 4
617 4
618 $ log 'modifies("path:b")'
618 $ log 'modifies("path:b")'
619 4
619 4
620 $ log 'modifies("*")'
620 $ log 'modifies("*")'
621 4
621 4
622 6
622 6
623 $ log 'modifies("set:modified()")'
623 $ log 'modifies("set:modified()")'
624 4
624 4
625 $ log 'id(5)'
625 $ log 'id(5)'
626 2
626 2
627 $ log 'only(9)'
627 $ log 'only(9)'
628 8
628 8
629 9
629 9
630 $ log 'only(8)'
630 $ log 'only(8)'
631 8
631 8
632 $ log 'only(9, 5)'
632 $ log 'only(9, 5)'
633 2
633 2
634 4
634 4
635 8
635 8
636 9
636 9
637 $ log 'only(7 + 9, 5 + 2)'
637 $ log 'only(7 + 9, 5 + 2)'
638 4
638 4
639 6
639 6
640 7
640 7
641 8
641 8
642 9
642 9
643
643
644 Test empty set input
644 Test empty set input
645 $ log 'only(p2())'
645 $ log 'only(p2())'
646 $ log 'only(p1(), p2())'
646 $ log 'only(p1(), p2())'
647 0
647 0
648 1
648 1
649 2
649 2
650 4
650 4
651 8
651 8
652 9
652 9
653
653
654 Test '%' operator
654 Test '%' operator
655
655
656 $ log '9%'
656 $ log '9%'
657 8
657 8
658 9
658 9
659 $ log '9%5'
659 $ log '9%5'
660 2
660 2
661 4
661 4
662 8
662 8
663 9
663 9
664 $ log '(7 + 9)%(5 + 2)'
664 $ log '(7 + 9)%(5 + 2)'
665 4
665 4
666 6
666 6
667 7
667 7
668 8
668 8
669 9
669 9
670
670
671 Test opreand of '%' is optimized recursively (issue4670)
671 Test opreand of '%' is optimized recursively (issue4670)
672
672
673 $ try --optimize '8:9-8%'
673 $ try --optimize '8:9-8%'
674 (onlypost
674 (onlypost
675 (minus
675 (minus
676 (range
676 (range
677 ('symbol', '8')
677 ('symbol', '8')
678 ('symbol', '9'))
678 ('symbol', '9'))
679 ('symbol', '8')))
679 ('symbol', '8')))
680 * optimized:
680 * optimized:
681 (func
681 (func
682 ('symbol', 'only')
682 ('symbol', 'only')
683 (and
683 (and
684 (range
684 (range
685 ('symbol', '8')
685 ('symbol', '8')
686 ('symbol', '9'))
686 ('symbol', '9'))
687 (not
687 (not
688 ('symbol', '8'))))
688 ('symbol', '8'))))
689 * set:
689 * set:
690 <baseset+ [8, 9]>
690 <baseset+ [8, 9]>
691 8
691 8
692 9
692 9
693 $ try --optimize '(9)%(5)'
693 $ try --optimize '(9)%(5)'
694 (only
694 (only
695 (group
695 (group
696 ('symbol', '9'))
696 ('symbol', '9'))
697 (group
697 (group
698 ('symbol', '5')))
698 ('symbol', '5')))
699 * optimized:
699 * optimized:
700 (func
700 (func
701 ('symbol', 'only')
701 ('symbol', 'only')
702 (list
702 (list
703 ('symbol', '9')
703 ('symbol', '9')
704 ('symbol', '5')))
704 ('symbol', '5')))
705 * set:
705 * set:
706 <baseset+ [8, 9, 2, 4]>
706 <baseset+ [8, 9, 2, 4]>
707 2
707 2
708 4
708 4
709 8
709 8
710 9
710 9
711
711
712 Test the order of operations
712 Test the order of operations
713
713
714 $ log '7 + 9%5 + 2'
714 $ log '7 + 9%5 + 2'
715 7
715 7
716 2
716 2
717 4
717 4
718 8
718 8
719 9
719 9
720
720
721 Test explicit numeric revision
721 Test explicit numeric revision
722 $ log 'rev(-2)'
722 $ log 'rev(-2)'
723 $ log 'rev(-1)'
723 $ log 'rev(-1)'
724 -1
724 -1
725 $ log 'rev(0)'
725 $ log 'rev(0)'
726 0
726 0
727 $ log 'rev(9)'
727 $ log 'rev(9)'
728 9
728 9
729 $ log 'rev(10)'
729 $ log 'rev(10)'
730 $ log 'rev(tip)'
730 $ log 'rev(tip)'
731 hg: parse error: rev expects a number
731 hg: parse error: rev expects a number
732 [255]
732 [255]
733
733
734 Test hexadecimal revision
734 Test hexadecimal revision
735 $ log 'id(2)'
735 $ log 'id(2)'
736 abort: 00changelog.i@2: ambiguous identifier!
736 abort: 00changelog.i@2: ambiguous identifier!
737 [255]
737 [255]
738 $ log 'id(23268)'
738 $ log 'id(23268)'
739 4
739 4
740 $ log 'id(2785f51eece)'
740 $ log 'id(2785f51eece)'
741 0
741 0
742 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532c)'
742 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532c)'
743 8
743 8
744 $ log 'id(d5d0dcbdc4a)'
744 $ log 'id(d5d0dcbdc4a)'
745 $ log 'id(d5d0dcbdc4w)'
745 $ log 'id(d5d0dcbdc4w)'
746 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532d)'
746 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532d)'
747 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532q)'
747 $ log 'id(d5d0dcbdc4d9ff5dbb2d336f32f0bb561c1a532q)'
748 $ log 'id(1.0)'
748 $ log 'id(1.0)'
749 $ log 'id(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)'
749 $ log 'id(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)'
750
750
751 Test null revision
751 Test null revision
752 $ log '(null)'
752 $ log '(null)'
753 -1
753 -1
754 $ log '(null:0)'
754 $ log '(null:0)'
755 -1
755 -1
756 0
756 0
757 $ log '(0:null)'
757 $ log '(0:null)'
758 0
758 0
759 -1
759 -1
760 $ log 'null::0'
760 $ log 'null::0'
761 -1
761 -1
762 0
762 0
763 $ log 'null:tip - 0:'
763 $ log 'null:tip - 0:'
764 -1
764 -1
765 $ log 'null: and null::' | head -1
765 $ log 'null: and null::' | head -1
766 -1
766 -1
767 $ log 'null: or 0:' | head -2
767 $ log 'null: or 0:' | head -2
768 -1
768 -1
769 0
769 0
770 $ log 'ancestors(null)'
770 $ log 'ancestors(null)'
771 -1
771 -1
772 $ log 'reverse(null:)' | tail -2
772 $ log 'reverse(null:)' | tail -2
773 0
773 0
774 -1
774 -1
775 BROKEN: should be '-1'
775 BROKEN: should be '-1'
776 $ log 'first(null:)'
776 $ log 'first(null:)'
777 BROKEN: should be '-1'
777 BROKEN: should be '-1'
778 $ log 'min(null:)'
778 $ log 'min(null:)'
779 $ log 'tip:null and all()' | tail -2
779 $ log 'tip:null and all()' | tail -2
780 1
780 1
781 0
781 0
782
782
783 Test working-directory revision
783 Test working-directory revision
784 $ hg debugrevspec 'wdir()'
784 $ hg debugrevspec 'wdir()'
785 2147483647
785 2147483647
786 $ hg debugrevspec 'tip or wdir()'
786 $ hg debugrevspec 'tip or wdir()'
787 9
787 9
788 2147483647
788 2147483647
789 $ hg debugrevspec '0:tip and wdir()'
789 $ hg debugrevspec '0:tip and wdir()'
790 $ log '0:wdir()' | tail -3
790 $ log '0:wdir()' | tail -3
791 8
791 8
792 9
792 9
793 2147483647
793 2147483647
794 $ log 'wdir():0' | head -3
794 $ log 'wdir():0' | head -3
795 2147483647
795 2147483647
796 9
796 9
797 8
797 8
798 $ log 'wdir():wdir()'
798 $ log 'wdir():wdir()'
799 2147483647
799 2147483647
800 $ log '(all() + wdir()) & min(. + wdir())'
800 $ log '(all() + wdir()) & min(. + wdir())'
801 9
801 9
802 $ log '(all() + wdir()) & max(. + wdir())'
802 $ log '(all() + wdir()) & max(. + wdir())'
803 2147483647
803 2147483647
804 $ log '(all() + wdir()) & first(wdir() + .)'
804 $ log '(all() + wdir()) & first(wdir() + .)'
805 2147483647
805 2147483647
806 $ log '(all() + wdir()) & last(. + wdir())'
806 $ log '(all() + wdir()) & last(. + wdir())'
807 2147483647
807 2147483647
808
808
809 $ log 'outgoing()'
809 $ log 'outgoing()'
810 8
810 8
811 9
811 9
812 $ log 'outgoing("../remote1")'
812 $ log 'outgoing("../remote1")'
813 8
813 8
814 9
814 9
815 $ log 'outgoing("../remote2")'
815 $ log 'outgoing("../remote2")'
816 3
816 3
817 5
817 5
818 6
818 6
819 7
819 7
820 9
820 9
821 $ log 'p1(merge())'
821 $ log 'p1(merge())'
822 5
822 5
823 $ log 'p2(merge())'
823 $ log 'p2(merge())'
824 4
824 4
825 $ log 'parents(merge())'
825 $ log 'parents(merge())'
826 4
826 4
827 5
827 5
828 $ log 'p1(branchpoint())'
828 $ log 'p1(branchpoint())'
829 0
829 0
830 2
830 2
831 $ log 'p2(branchpoint())'
831 $ log 'p2(branchpoint())'
832 $ log 'parents(branchpoint())'
832 $ log 'parents(branchpoint())'
833 0
833 0
834 2
834 2
835 $ log 'removes(a)'
835 $ log 'removes(a)'
836 2
836 2
837 6
837 6
838 $ log 'roots(all())'
838 $ log 'roots(all())'
839 0
839 0
840 $ log 'reverse(2 or 3 or 4 or 5)'
840 $ log 'reverse(2 or 3 or 4 or 5)'
841 5
841 5
842 4
842 4
843 3
843 3
844 2
844 2
845 $ log 'reverse(all())'
845 $ log 'reverse(all())'
846 9
846 9
847 8
847 8
848 7
848 7
849 6
849 6
850 5
850 5
851 4
851 4
852 3
852 3
853 2
853 2
854 1
854 1
855 0
855 0
856 $ log 'reverse(all()) & filelog(b)'
856 $ log 'reverse(all()) & filelog(b)'
857 4
857 4
858 1
858 1
859 $ log 'rev(5)'
859 $ log 'rev(5)'
860 5
860 5
861 $ log 'sort(limit(reverse(all()), 3))'
861 $ log 'sort(limit(reverse(all()), 3))'
862 7
862 7
863 8
863 8
864 9
864 9
865 $ log 'sort(2 or 3 or 4 or 5, date)'
865 $ log 'sort(2 or 3 or 4 or 5, date)'
866 2
866 2
867 3
867 3
868 5
868 5
869 4
869 4
870 $ log 'tagged()'
870 $ log 'tagged()'
871 6
871 6
872 $ log 'tag()'
872 $ log 'tag()'
873 6
873 6
874 $ log 'tag(1.0)'
874 $ log 'tag(1.0)'
875 6
875 6
876 $ log 'tag(tip)'
876 $ log 'tag(tip)'
877 9
877 9
878
878
879 test sort revset
879 test sort revset
880 --------------------------------------------
880 --------------------------------------------
881
881
882 test when adding two unordered revsets
882 test when adding two unordered revsets
883
883
884 $ log 'sort(keyword(issue) or modifies(b))'
884 $ log 'sort(keyword(issue) or modifies(b))'
885 4
885 4
886 6
886 6
887
887
888 test when sorting a reversed collection in the same way it is
888 test when sorting a reversed collection in the same way it is
889
889
890 $ log 'sort(reverse(all()), -rev)'
890 $ log 'sort(reverse(all()), -rev)'
891 9
891 9
892 8
892 8
893 7
893 7
894 6
894 6
895 5
895 5
896 4
896 4
897 3
897 3
898 2
898 2
899 1
899 1
900 0
900 0
901
901
902 test when sorting a reversed collection
902 test when sorting a reversed collection
903
903
904 $ log 'sort(reverse(all()), rev)'
904 $ log 'sort(reverse(all()), rev)'
905 0
905 0
906 1
906 1
907 2
907 2
908 3
908 3
909 4
909 4
910 5
910 5
911 6
911 6
912 7
912 7
913 8
913 8
914 9
914 9
915
915
916
916
917 test sorting two sorted collections in different orders
917 test sorting two sorted collections in different orders
918
918
919 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
919 $ log 'sort(outgoing() or reverse(removes(a)), rev)'
920 2
920 2
921 6
921 6
922 8
922 8
923 9
923 9
924
924
925 test sorting two sorted collections in different orders backwards
925 test sorting two sorted collections in different orders backwards
926
926
927 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
927 $ log 'sort(outgoing() or reverse(removes(a)), -rev)'
928 9
928 9
929 8
929 8
930 6
930 6
931 2
931 2
932
932
933 test subtracting something from an addset
933 test subtracting something from an addset
934
934
935 $ log '(outgoing() or removes(a)) - removes(a)'
935 $ log '(outgoing() or removes(a)) - removes(a)'
936 8
936 8
937 9
937 9
938
938
939 test intersecting something with an addset
939 test intersecting something with an addset
940
940
941 $ log 'parents(outgoing() or removes(a))'
941 $ log 'parents(outgoing() or removes(a))'
942 1
942 1
943 4
943 4
944 5
944 5
945 8
945 8
946
946
947 test that `or` operation combines elements in the right order:
947 test that `or` operation combines elements in the right order:
948
948
949 $ log '3:4 or 2:5'
949 $ log '3:4 or 2:5'
950 3
950 3
951 4
951 4
952 2
952 2
953 5
953 5
954 $ log '3:4 or 5:2'
954 $ log '3:4 or 5:2'
955 3
955 3
956 4
956 4
957 5
957 5
958 2
958 2
959 $ log 'sort(3:4 or 2:5)'
959 $ log 'sort(3:4 or 2:5)'
960 2
960 2
961 3
961 3
962 4
962 4
963 5
963 5
964 $ log 'sort(3:4 or 5:2)'
964 $ log 'sort(3:4 or 5:2)'
965 2
965 2
966 3
966 3
967 4
967 4
968 5
968 5
969
969
970 test that more than one `-r`s are combined in the right order and deduplicated:
970 test that more than one `-r`s are combined in the right order and deduplicated:
971
971
972 $ hg log -T '{rev}\n' -r 3 -r 3 -r 4 -r 5:2 -r 'ancestors(4)'
972 $ hg log -T '{rev}\n' -r 3 -r 3 -r 4 -r 5:2 -r 'ancestors(4)'
973 3
973 3
974 4
974 4
975 5
975 5
976 2
976 2
977 0
977 0
978 1
978 1
979
979
980 test that `or` operation skips duplicated revisions from right-hand side
980 test that `or` operation skips duplicated revisions from right-hand side
981
981
982 $ try 'reverse(1::5) or ancestors(4)'
982 $ try 'reverse(1::5) or ancestors(4)'
983 (or
983 (or
984 (func
984 (func
985 ('symbol', 'reverse')
985 ('symbol', 'reverse')
986 (dagrange
986 (dagrange
987 ('symbol', '1')
987 ('symbol', '1')
988 ('symbol', '5')))
988 ('symbol', '5')))
989 (func
989 (func
990 ('symbol', 'ancestors')
990 ('symbol', 'ancestors')
991 ('symbol', '4')))
991 ('symbol', '4')))
992 * set:
992 * set:
993 <addset
993 <addset
994 <baseset [5, 3, 1]>,
994 <baseset- [1, 3, 5]>,
995 <generatorset+>>
995 <generatorset+>>
996 5
996 5
997 3
997 3
998 1
998 1
999 0
999 0
1000 2
1000 2
1001 4
1001 4
1002 $ try 'sort(ancestors(4) or reverse(1::5))'
1002 $ try 'sort(ancestors(4) or reverse(1::5))'
1003 (func
1003 (func
1004 ('symbol', 'sort')
1004 ('symbol', 'sort')
1005 (or
1005 (or
1006 (func
1006 (func
1007 ('symbol', 'ancestors')
1007 ('symbol', 'ancestors')
1008 ('symbol', '4'))
1008 ('symbol', '4'))
1009 (func
1009 (func
1010 ('symbol', 'reverse')
1010 ('symbol', 'reverse')
1011 (dagrange
1011 (dagrange
1012 ('symbol', '1')
1012 ('symbol', '1')
1013 ('symbol', '5')))))
1013 ('symbol', '5')))))
1014 * set:
1014 * set:
1015 <addset+
1015 <addset+
1016 <generatorset+>,
1016 <generatorset+>,
1017 <baseset [5, 3, 1]>>
1017 <baseset- [1, 3, 5]>>
1018 0
1018 0
1019 1
1019 1
1020 2
1020 2
1021 3
1021 3
1022 4
1022 4
1023 5
1023 5
1024
1024
1025 test optimization of trivial `or` operation
1025 test optimization of trivial `or` operation
1026
1026
1027 $ try --optimize '0|(1)|"2"|-2|tip|null'
1027 $ try --optimize '0|(1)|"2"|-2|tip|null'
1028 (or
1028 (or
1029 ('symbol', '0')
1029 ('symbol', '0')
1030 (group
1030 (group
1031 ('symbol', '1'))
1031 ('symbol', '1'))
1032 ('string', '2')
1032 ('string', '2')
1033 (negate
1033 (negate
1034 ('symbol', '2'))
1034 ('symbol', '2'))
1035 ('symbol', 'tip')
1035 ('symbol', 'tip')
1036 ('symbol', 'null'))
1036 ('symbol', 'null'))
1037 * optimized:
1037 * optimized:
1038 (func
1038 (func
1039 ('symbol', '_list')
1039 ('symbol', '_list')
1040 ('string', '0\x001\x002\x00-2\x00tip\x00null'))
1040 ('string', '0\x001\x002\x00-2\x00tip\x00null'))
1041 * set:
1041 * set:
1042 <baseset [0, 1, 2, 8, 9, -1]>
1042 <baseset [0, 1, 2, 8, 9, -1]>
1043 0
1043 0
1044 1
1044 1
1045 2
1045 2
1046 8
1046 8
1047 9
1047 9
1048 -1
1048 -1
1049
1049
1050 $ try --optimize '0|1|2:3'
1050 $ try --optimize '0|1|2:3'
1051 (or
1051 (or
1052 ('symbol', '0')
1052 ('symbol', '0')
1053 ('symbol', '1')
1053 ('symbol', '1')
1054 (range
1054 (range
1055 ('symbol', '2')
1055 ('symbol', '2')
1056 ('symbol', '3')))
1056 ('symbol', '3')))
1057 * optimized:
1057 * optimized:
1058 (or
1058 (or
1059 (func
1059 (func
1060 ('symbol', '_list')
1060 ('symbol', '_list')
1061 ('string', '0\x001'))
1061 ('string', '0\x001'))
1062 (range
1062 (range
1063 ('symbol', '2')
1063 ('symbol', '2')
1064 ('symbol', '3')))
1064 ('symbol', '3')))
1065 * set:
1065 * set:
1066 <addset
1066 <addset
1067 <baseset [0, 1]>,
1067 <baseset [0, 1]>,
1068 <spanset+ 2:3>>
1068 <spanset+ 2:3>>
1069 0
1069 0
1070 1
1070 1
1071 2
1071 2
1072 3
1072 3
1073
1073
1074 $ try --optimize '0:1|2|3:4|5|6'
1074 $ try --optimize '0:1|2|3:4|5|6'
1075 (or
1075 (or
1076 (range
1076 (range
1077 ('symbol', '0')
1077 ('symbol', '0')
1078 ('symbol', '1'))
1078 ('symbol', '1'))
1079 ('symbol', '2')
1079 ('symbol', '2')
1080 (range
1080 (range
1081 ('symbol', '3')
1081 ('symbol', '3')
1082 ('symbol', '4'))
1082 ('symbol', '4'))
1083 ('symbol', '5')
1083 ('symbol', '5')
1084 ('symbol', '6'))
1084 ('symbol', '6'))
1085 * optimized:
1085 * optimized:
1086 (or
1086 (or
1087 (range
1087 (range
1088 ('symbol', '0')
1088 ('symbol', '0')
1089 ('symbol', '1'))
1089 ('symbol', '1'))
1090 ('symbol', '2')
1090 ('symbol', '2')
1091 (range
1091 (range
1092 ('symbol', '3')
1092 ('symbol', '3')
1093 ('symbol', '4'))
1093 ('symbol', '4'))
1094 (func
1094 (func
1095 ('symbol', '_list')
1095 ('symbol', '_list')
1096 ('string', '5\x006')))
1096 ('string', '5\x006')))
1097 * set:
1097 * set:
1098 <addset
1098 <addset
1099 <addset
1099 <addset
1100 <spanset+ 0:1>,
1100 <spanset+ 0:1>,
1101 <baseset [2]>>,
1101 <baseset [2]>>,
1102 <addset
1102 <addset
1103 <spanset+ 3:4>,
1103 <spanset+ 3:4>,
1104 <baseset [5, 6]>>>
1104 <baseset [5, 6]>>>
1105 0
1105 0
1106 1
1106 1
1107 2
1107 2
1108 3
1108 3
1109 4
1109 4
1110 5
1110 5
1111 6
1111 6
1112
1112
1113 test that `_list` should be narrowed by provided `subset`
1113 test that `_list` should be narrowed by provided `subset`
1114
1114
1115 $ log '0:2 and (null|1|2|3)'
1115 $ log '0:2 and (null|1|2|3)'
1116 1
1116 1
1117 2
1117 2
1118
1118
1119 test that `_list` should remove duplicates
1119 test that `_list` should remove duplicates
1120
1120
1121 $ log '0|1|2|1|2|-1|tip'
1121 $ log '0|1|2|1|2|-1|tip'
1122 0
1122 0
1123 1
1123 1
1124 2
1124 2
1125 9
1125 9
1126
1126
1127 test unknown revision in `_list`
1127 test unknown revision in `_list`
1128
1128
1129 $ log '0|unknown'
1129 $ log '0|unknown'
1130 abort: unknown revision 'unknown'!
1130 abort: unknown revision 'unknown'!
1131 [255]
1131 [255]
1132
1132
1133 test integer range in `_list`
1133 test integer range in `_list`
1134
1134
1135 $ log '-1|-10'
1135 $ log '-1|-10'
1136 9
1136 9
1137 0
1137 0
1138
1138
1139 $ log '-10|-11'
1139 $ log '-10|-11'
1140 abort: unknown revision '-11'!
1140 abort: unknown revision '-11'!
1141 [255]
1141 [255]
1142
1142
1143 $ log '9|10'
1143 $ log '9|10'
1144 abort: unknown revision '10'!
1144 abort: unknown revision '10'!
1145 [255]
1145 [255]
1146
1146
1147 test '0000' != '0' in `_list`
1147 test '0000' != '0' in `_list`
1148
1148
1149 $ log '0|0000'
1149 $ log '0|0000'
1150 0
1150 0
1151 -1
1151 -1
1152
1152
1153 test that chained `or` operations make balanced addsets
1153 test that chained `or` operations make balanced addsets
1154
1154
1155 $ try '0:1|1:2|2:3|3:4|4:5'
1155 $ try '0:1|1:2|2:3|3:4|4:5'
1156 (or
1156 (or
1157 (range
1157 (range
1158 ('symbol', '0')
1158 ('symbol', '0')
1159 ('symbol', '1'))
1159 ('symbol', '1'))
1160 (range
1160 (range
1161 ('symbol', '1')
1161 ('symbol', '1')
1162 ('symbol', '2'))
1162 ('symbol', '2'))
1163 (range
1163 (range
1164 ('symbol', '2')
1164 ('symbol', '2')
1165 ('symbol', '3'))
1165 ('symbol', '3'))
1166 (range
1166 (range
1167 ('symbol', '3')
1167 ('symbol', '3')
1168 ('symbol', '4'))
1168 ('symbol', '4'))
1169 (range
1169 (range
1170 ('symbol', '4')
1170 ('symbol', '4')
1171 ('symbol', '5')))
1171 ('symbol', '5')))
1172 * set:
1172 * set:
1173 <addset
1173 <addset
1174 <addset
1174 <addset
1175 <spanset+ 0:1>,
1175 <spanset+ 0:1>,
1176 <spanset+ 1:2>>,
1176 <spanset+ 1:2>>,
1177 <addset
1177 <addset
1178 <spanset+ 2:3>,
1178 <spanset+ 2:3>,
1179 <addset
1179 <addset
1180 <spanset+ 3:4>,
1180 <spanset+ 3:4>,
1181 <spanset+ 4:5>>>>
1181 <spanset+ 4:5>>>>
1182 0
1182 0
1183 1
1183 1
1184 2
1184 2
1185 3
1185 3
1186 4
1186 4
1187 5
1187 5
1188
1188
1189 no crash by empty group "()" while optimizing `or` operations
1189 no crash by empty group "()" while optimizing `or` operations
1190
1190
1191 $ try --optimize '0|()'
1191 $ try --optimize '0|()'
1192 (or
1192 (or
1193 ('symbol', '0')
1193 ('symbol', '0')
1194 (group
1194 (group
1195 None))
1195 None))
1196 * optimized:
1196 * optimized:
1197 (or
1197 (or
1198 ('symbol', '0')
1198 ('symbol', '0')
1199 None)
1199 None)
1200 hg: parse error: missing argument
1200 hg: parse error: missing argument
1201 [255]
1201 [255]
1202
1202
1203 test that chained `or` operations never eat up stack (issue4624)
1203 test that chained `or` operations never eat up stack (issue4624)
1204 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
1204 (uses `0:1` instead of `0` to avoid future optimization of trivial revisions)
1205
1205
1206 $ hg log -T '{rev}\n' -r "`python -c "print '|'.join(['0:1'] * 500)"`"
1206 $ hg log -T '{rev}\n' -r "`python -c "print '|'.join(['0:1'] * 500)"`"
1207 0
1207 0
1208 1
1208 1
1209
1209
1210 test that repeated `-r` options never eat up stack (issue4565)
1210 test that repeated `-r` options never eat up stack (issue4565)
1211 (uses `-r 0::1` to avoid possible optimization at old-style parser)
1211 (uses `-r 0::1` to avoid possible optimization at old-style parser)
1212
1212
1213 $ hg log -T '{rev}\n' `python -c "for i in xrange(500): print '-r 0::1 ',"`
1213 $ hg log -T '{rev}\n' `python -c "for i in xrange(500): print '-r 0::1 ',"`
1214 0
1214 0
1215 1
1215 1
1216
1216
1217 check that conversion to only works
1217 check that conversion to only works
1218 $ try --optimize '::3 - ::1'
1218 $ try --optimize '::3 - ::1'
1219 (minus
1219 (minus
1220 (dagrangepre
1220 (dagrangepre
1221 ('symbol', '3'))
1221 ('symbol', '3'))
1222 (dagrangepre
1222 (dagrangepre
1223 ('symbol', '1')))
1223 ('symbol', '1')))
1224 * optimized:
1224 * optimized:
1225 (func
1225 (func
1226 ('symbol', 'only')
1226 ('symbol', 'only')
1227 (list
1227 (list
1228 ('symbol', '3')
1228 ('symbol', '3')
1229 ('symbol', '1')))
1229 ('symbol', '1')))
1230 * set:
1230 * set:
1231 <baseset+ [3]>
1231 <baseset+ [3]>
1232 3
1232 3
1233 $ try --optimize 'ancestors(1) - ancestors(3)'
1233 $ try --optimize 'ancestors(1) - ancestors(3)'
1234 (minus
1234 (minus
1235 (func
1235 (func
1236 ('symbol', 'ancestors')
1236 ('symbol', 'ancestors')
1237 ('symbol', '1'))
1237 ('symbol', '1'))
1238 (func
1238 (func
1239 ('symbol', 'ancestors')
1239 ('symbol', 'ancestors')
1240 ('symbol', '3')))
1240 ('symbol', '3')))
1241 * optimized:
1241 * optimized:
1242 (func
1242 (func
1243 ('symbol', 'only')
1243 ('symbol', 'only')
1244 (list
1244 (list
1245 ('symbol', '1')
1245 ('symbol', '1')
1246 ('symbol', '3')))
1246 ('symbol', '3')))
1247 * set:
1247 * set:
1248 <baseset+ []>
1248 <baseset+ []>
1249 $ try --optimize 'not ::2 and ::6'
1249 $ try --optimize 'not ::2 and ::6'
1250 (and
1250 (and
1251 (not
1251 (not
1252 (dagrangepre
1252 (dagrangepre
1253 ('symbol', '2')))
1253 ('symbol', '2')))
1254 (dagrangepre
1254 (dagrangepre
1255 ('symbol', '6')))
1255 ('symbol', '6')))
1256 * optimized:
1256 * optimized:
1257 (func
1257 (func
1258 ('symbol', 'only')
1258 ('symbol', 'only')
1259 (list
1259 (list
1260 ('symbol', '6')
1260 ('symbol', '6')
1261 ('symbol', '2')))
1261 ('symbol', '2')))
1262 * set:
1262 * set:
1263 <baseset+ [3, 4, 5, 6]>
1263 <baseset+ [3, 4, 5, 6]>
1264 3
1264 3
1265 4
1265 4
1266 5
1266 5
1267 6
1267 6
1268 $ try --optimize 'ancestors(6) and not ancestors(4)'
1268 $ try --optimize 'ancestors(6) and not ancestors(4)'
1269 (and
1269 (and
1270 (func
1270 (func
1271 ('symbol', 'ancestors')
1271 ('symbol', 'ancestors')
1272 ('symbol', '6'))
1272 ('symbol', '6'))
1273 (not
1273 (not
1274 (func
1274 (func
1275 ('symbol', 'ancestors')
1275 ('symbol', 'ancestors')
1276 ('symbol', '4'))))
1276 ('symbol', '4'))))
1277 * optimized:
1277 * optimized:
1278 (func
1278 (func
1279 ('symbol', 'only')
1279 ('symbol', 'only')
1280 (list
1280 (list
1281 ('symbol', '6')
1281 ('symbol', '6')
1282 ('symbol', '4')))
1282 ('symbol', '4')))
1283 * set:
1283 * set:
1284 <baseset+ [3, 5, 6]>
1284 <baseset+ [3, 5, 6]>
1285 3
1285 3
1286 5
1286 5
1287 6
1287 6
1288
1288
1289 no crash by empty group "()" while optimizing to "only()"
1289 no crash by empty group "()" while optimizing to "only()"
1290
1290
1291 $ try --optimize '::1 and ()'
1291 $ try --optimize '::1 and ()'
1292 (and
1292 (and
1293 (dagrangepre
1293 (dagrangepre
1294 ('symbol', '1'))
1294 ('symbol', '1'))
1295 (group
1295 (group
1296 None))
1296 None))
1297 * optimized:
1297 * optimized:
1298 (and
1298 (and
1299 None
1299 None
1300 (func
1300 (func
1301 ('symbol', 'ancestors')
1301 ('symbol', 'ancestors')
1302 ('symbol', '1')))
1302 ('symbol', '1')))
1303 hg: parse error: missing argument
1303 hg: parse error: missing argument
1304 [255]
1304 [255]
1305
1305
1306 we can use patterns when searching for tags
1306 we can use patterns when searching for tags
1307
1307
1308 $ log 'tag("1..*")'
1308 $ log 'tag("1..*")'
1309 abort: tag '1..*' does not exist!
1309 abort: tag '1..*' does not exist!
1310 [255]
1310 [255]
1311 $ log 'tag("re:1..*")'
1311 $ log 'tag("re:1..*")'
1312 6
1312 6
1313 $ log 'tag("re:[0-9].[0-9]")'
1313 $ log 'tag("re:[0-9].[0-9]")'
1314 6
1314 6
1315 $ log 'tag("literal:1.0")'
1315 $ log 'tag("literal:1.0")'
1316 6
1316 6
1317 $ log 'tag("re:0..*")'
1317 $ log 'tag("re:0..*")'
1318
1318
1319 $ log 'tag(unknown)'
1319 $ log 'tag(unknown)'
1320 abort: tag 'unknown' does not exist!
1320 abort: tag 'unknown' does not exist!
1321 [255]
1321 [255]
1322 $ log 'tag("re:unknown")'
1322 $ log 'tag("re:unknown")'
1323 $ log 'present(tag("unknown"))'
1323 $ log 'present(tag("unknown"))'
1324 $ log 'present(tag("re:unknown"))'
1324 $ log 'present(tag("re:unknown"))'
1325 $ log 'branch(unknown)'
1325 $ log 'branch(unknown)'
1326 abort: unknown revision 'unknown'!
1326 abort: unknown revision 'unknown'!
1327 [255]
1327 [255]
1328 $ log 'branch("re:unknown")'
1328 $ log 'branch("re:unknown")'
1329 $ log 'present(branch("unknown"))'
1329 $ log 'present(branch("unknown"))'
1330 $ log 'present(branch("re:unknown"))'
1330 $ log 'present(branch("re:unknown"))'
1331 $ log 'user(bob)'
1331 $ log 'user(bob)'
1332 2
1332 2
1333
1333
1334 $ log '4::8'
1334 $ log '4::8'
1335 4
1335 4
1336 8
1336 8
1337 $ log '4:8'
1337 $ log '4:8'
1338 4
1338 4
1339 5
1339 5
1340 6
1340 6
1341 7
1341 7
1342 8
1342 8
1343
1343
1344 $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
1344 $ log 'sort(!merge() & (modifies(b) | user(bob) | keyword(bug) | keyword(issue) & 1::9), "-date")'
1345 4
1345 4
1346 2
1346 2
1347 5
1347 5
1348
1348
1349 $ log 'not 0 and 0:2'
1349 $ log 'not 0 and 0:2'
1350 1
1350 1
1351 2
1351 2
1352 $ log 'not 1 and 0:2'
1352 $ log 'not 1 and 0:2'
1353 0
1353 0
1354 2
1354 2
1355 $ log 'not 2 and 0:2'
1355 $ log 'not 2 and 0:2'
1356 0
1356 0
1357 1
1357 1
1358 $ log '(1 and 2)::'
1358 $ log '(1 and 2)::'
1359 $ log '(1 and 2):'
1359 $ log '(1 and 2):'
1360 $ log '(1 and 2):3'
1360 $ log '(1 and 2):3'
1361 $ log 'sort(head(), -rev)'
1361 $ log 'sort(head(), -rev)'
1362 9
1362 9
1363 7
1363 7
1364 6
1364 6
1365 5
1365 5
1366 4
1366 4
1367 3
1367 3
1368 2
1368 2
1369 1
1369 1
1370 0
1370 0
1371 $ log '4::8 - 8'
1371 $ log '4::8 - 8'
1372 4
1372 4
1373 $ log 'matching(1 or 2 or 3) and (2 or 3 or 1)'
1373 $ log 'matching(1 or 2 or 3) and (2 or 3 or 1)'
1374 2
1374 2
1375 3
1375 3
1376 1
1376 1
1377
1377
1378 $ log 'named("unknown")'
1378 $ log 'named("unknown")'
1379 abort: namespace 'unknown' does not exist!
1379 abort: namespace 'unknown' does not exist!
1380 [255]
1380 [255]
1381 $ log 'named("re:unknown")'
1381 $ log 'named("re:unknown")'
1382 abort: no namespace exists that match 'unknown'!
1382 abort: no namespace exists that match 'unknown'!
1383 [255]
1383 [255]
1384 $ log 'present(named("unknown"))'
1384 $ log 'present(named("unknown"))'
1385 $ log 'present(named("re:unknown"))'
1385 $ log 'present(named("re:unknown"))'
1386
1386
1387 $ log 'tag()'
1387 $ log 'tag()'
1388 6
1388 6
1389 $ log 'named("tags")'
1389 $ log 'named("tags")'
1390 6
1390 6
1391
1391
1392 issue2437
1392 issue2437
1393
1393
1394 $ log '3 and p1(5)'
1394 $ log '3 and p1(5)'
1395 3
1395 3
1396 $ log '4 and p2(6)'
1396 $ log '4 and p2(6)'
1397 4
1397 4
1398 $ log '1 and parents(:2)'
1398 $ log '1 and parents(:2)'
1399 1
1399 1
1400 $ log '2 and children(1:)'
1400 $ log '2 and children(1:)'
1401 2
1401 2
1402 $ log 'roots(all()) or roots(all())'
1402 $ log 'roots(all()) or roots(all())'
1403 0
1403 0
1404 $ hg debugrevspec 'roots(all()) or roots(all())'
1404 $ hg debugrevspec 'roots(all()) or roots(all())'
1405 0
1405 0
1406 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
1406 $ log 'heads(branch(Γ©)) or heads(branch(Γ©))'
1407 9
1407 9
1408 $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(Γ©)))'
1408 $ log 'ancestors(8) and (heads(branch("-a-b-c-")) or heads(branch(Γ©)))'
1409 4
1409 4
1410
1410
1411 issue2654: report a parse error if the revset was not completely parsed
1411 issue2654: report a parse error if the revset was not completely parsed
1412
1412
1413 $ log '1 OR 2'
1413 $ log '1 OR 2'
1414 hg: parse error at 2: invalid token
1414 hg: parse error at 2: invalid token
1415 [255]
1415 [255]
1416
1416
1417 or operator should preserve ordering:
1417 or operator should preserve ordering:
1418 $ log 'reverse(2::4) or tip'
1418 $ log 'reverse(2::4) or tip'
1419 4
1419 4
1420 2
1420 2
1421 9
1421 9
1422
1422
1423 parentrevspec
1423 parentrevspec
1424
1424
1425 $ log 'merge()^0'
1425 $ log 'merge()^0'
1426 6
1426 6
1427 $ log 'merge()^'
1427 $ log 'merge()^'
1428 5
1428 5
1429 $ log 'merge()^1'
1429 $ log 'merge()^1'
1430 5
1430 5
1431 $ log 'merge()^2'
1431 $ log 'merge()^2'
1432 4
1432 4
1433 $ log 'merge()^^'
1433 $ log 'merge()^^'
1434 3
1434 3
1435 $ log 'merge()^1^'
1435 $ log 'merge()^1^'
1436 3
1436 3
1437 $ log 'merge()^^^'
1437 $ log 'merge()^^^'
1438 1
1438 1
1439
1439
1440 $ log 'merge()~0'
1440 $ log 'merge()~0'
1441 6
1441 6
1442 $ log 'merge()~1'
1442 $ log 'merge()~1'
1443 5
1443 5
1444 $ log 'merge()~2'
1444 $ log 'merge()~2'
1445 3
1445 3
1446 $ log 'merge()~2^1'
1446 $ log 'merge()~2^1'
1447 1
1447 1
1448 $ log 'merge()~3'
1448 $ log 'merge()~3'
1449 1
1449 1
1450
1450
1451 $ log '(-3:tip)^'
1451 $ log '(-3:tip)^'
1452 4
1452 4
1453 6
1453 6
1454 8
1454 8
1455
1455
1456 $ log 'tip^foo'
1456 $ log 'tip^foo'
1457 hg: parse error: ^ expects a number 0, 1, or 2
1457 hg: parse error: ^ expects a number 0, 1, or 2
1458 [255]
1458 [255]
1459
1459
1460 Bogus function gets suggestions
1460 Bogus function gets suggestions
1461 $ log 'add()'
1461 $ log 'add()'
1462 hg: parse error: unknown identifier: add
1462 hg: parse error: unknown identifier: add
1463 (did you mean 'adds'?)
1463 (did you mean 'adds'?)
1464 [255]
1464 [255]
1465 $ log 'added()'
1465 $ log 'added()'
1466 hg: parse error: unknown identifier: added
1466 hg: parse error: unknown identifier: added
1467 (did you mean 'adds'?)
1467 (did you mean 'adds'?)
1468 [255]
1468 [255]
1469 $ log 'remo()'
1469 $ log 'remo()'
1470 hg: parse error: unknown identifier: remo
1470 hg: parse error: unknown identifier: remo
1471 (did you mean one of remote, removes?)
1471 (did you mean one of remote, removes?)
1472 [255]
1472 [255]
1473 $ log 'babar()'
1473 $ log 'babar()'
1474 hg: parse error: unknown identifier: babar
1474 hg: parse error: unknown identifier: babar
1475 [255]
1475 [255]
1476
1476
1477 Bogus function with a similar internal name doesn't suggest the internal name
1477 Bogus function with a similar internal name doesn't suggest the internal name
1478 $ log 'matches()'
1478 $ log 'matches()'
1479 hg: parse error: unknown identifier: matches
1479 hg: parse error: unknown identifier: matches
1480 (did you mean 'matching'?)
1480 (did you mean 'matching'?)
1481 [255]
1481 [255]
1482
1482
1483 Undocumented functions aren't suggested as similar either
1483 Undocumented functions aren't suggested as similar either
1484 $ log 'wdir2()'
1484 $ log 'wdir2()'
1485 hg: parse error: unknown identifier: wdir2
1485 hg: parse error: unknown identifier: wdir2
1486 [255]
1486 [255]
1487
1487
1488 multiple revspecs
1488 multiple revspecs
1489
1489
1490 $ hg log -r 'tip~1:tip' -r 'tip~2:tip~1' --template '{rev}\n'
1490 $ hg log -r 'tip~1:tip' -r 'tip~2:tip~1' --template '{rev}\n'
1491 8
1491 8
1492 9
1492 9
1493 4
1493 4
1494 5
1494 5
1495 6
1495 6
1496 7
1496 7
1497
1497
1498 test usage in revpair (with "+")
1498 test usage in revpair (with "+")
1499
1499
1500 (real pair)
1500 (real pair)
1501
1501
1502 $ hg diff -r 'tip^^' -r 'tip'
1502 $ hg diff -r 'tip^^' -r 'tip'
1503 diff -r 2326846efdab -r 24286f4ae135 .hgtags
1503 diff -r 2326846efdab -r 24286f4ae135 .hgtags
1504 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1504 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1505 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
1505 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
1506 @@ -0,0 +1,1 @@
1506 @@ -0,0 +1,1 @@
1507 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
1507 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
1508 $ hg diff -r 'tip^^::tip'
1508 $ hg diff -r 'tip^^::tip'
1509 diff -r 2326846efdab -r 24286f4ae135 .hgtags
1509 diff -r 2326846efdab -r 24286f4ae135 .hgtags
1510 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1510 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1511 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
1511 +++ b/.hgtags Thu Jan 01 00:00:00 1970 +0000
1512 @@ -0,0 +1,1 @@
1512 @@ -0,0 +1,1 @@
1513 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
1513 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
1514
1514
1515 (single rev)
1515 (single rev)
1516
1516
1517 $ hg diff -r 'tip^' -r 'tip^'
1517 $ hg diff -r 'tip^' -r 'tip^'
1518 $ hg diff -r 'tip^:tip^'
1518 $ hg diff -r 'tip^:tip^'
1519
1519
1520 (single rev that does not looks like a range)
1520 (single rev that does not looks like a range)
1521
1521
1522 $ hg diff -r 'tip^::tip^ or tip^'
1522 $ hg diff -r 'tip^::tip^ or tip^'
1523 diff -r d5d0dcbdc4d9 .hgtags
1523 diff -r d5d0dcbdc4d9 .hgtags
1524 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1524 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1525 +++ b/.hgtags * (glob)
1525 +++ b/.hgtags * (glob)
1526 @@ -0,0 +1,1 @@
1526 @@ -0,0 +1,1 @@
1527 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
1527 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
1528 $ hg diff -r 'tip^ or tip^'
1528 $ hg diff -r 'tip^ or tip^'
1529 diff -r d5d0dcbdc4d9 .hgtags
1529 diff -r d5d0dcbdc4d9 .hgtags
1530 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1530 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1531 +++ b/.hgtags * (glob)
1531 +++ b/.hgtags * (glob)
1532 @@ -0,0 +1,1 @@
1532 @@ -0,0 +1,1 @@
1533 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
1533 +e0cc66ef77e8b6f711815af4e001a6594fde3ba5 1.0
1534
1534
1535 (no rev)
1535 (no rev)
1536
1536
1537 $ hg diff -r 'author("babar") or author("celeste")'
1537 $ hg diff -r 'author("babar") or author("celeste")'
1538 abort: empty revision range
1538 abort: empty revision range
1539 [255]
1539 [255]
1540
1540
1541 aliases:
1541 aliases:
1542
1542
1543 $ echo '[revsetalias]' >> .hg/hgrc
1543 $ echo '[revsetalias]' >> .hg/hgrc
1544 $ echo 'm = merge()' >> .hg/hgrc
1544 $ echo 'm = merge()' >> .hg/hgrc
1545 (revset aliases can override builtin revsets)
1545 (revset aliases can override builtin revsets)
1546 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
1546 $ echo 'p2($1) = p1($1)' >> .hg/hgrc
1547 $ echo 'sincem = descendants(m)' >> .hg/hgrc
1547 $ echo 'sincem = descendants(m)' >> .hg/hgrc
1548 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
1548 $ echo 'd($1) = reverse(sort($1, date))' >> .hg/hgrc
1549 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
1549 $ echo 'rs(ARG1, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
1550 $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
1550 $ echo 'rs4(ARG1, ARGA, ARGB, ARG2) = reverse(sort(ARG1, ARG2))' >> .hg/hgrc
1551
1551
1552 $ try m
1552 $ try m
1553 ('symbol', 'm')
1553 ('symbol', 'm')
1554 (func
1554 (func
1555 ('symbol', 'merge')
1555 ('symbol', 'merge')
1556 None)
1556 None)
1557 * set:
1557 * set:
1558 <filteredset
1558 <filteredset
1559 <fullreposet+ 0:9>>
1559 <fullreposet+ 0:9>>
1560 6
1560 6
1561
1561
1562 $ HGPLAIN=1
1562 $ HGPLAIN=1
1563 $ export HGPLAIN
1563 $ export HGPLAIN
1564 $ try m
1564 $ try m
1565 ('symbol', 'm')
1565 ('symbol', 'm')
1566 abort: unknown revision 'm'!
1566 abort: unknown revision 'm'!
1567 [255]
1567 [255]
1568
1568
1569 $ HGPLAINEXCEPT=revsetalias
1569 $ HGPLAINEXCEPT=revsetalias
1570 $ export HGPLAINEXCEPT
1570 $ export HGPLAINEXCEPT
1571 $ try m
1571 $ try m
1572 ('symbol', 'm')
1572 ('symbol', 'm')
1573 (func
1573 (func
1574 ('symbol', 'merge')
1574 ('symbol', 'merge')
1575 None)
1575 None)
1576 * set:
1576 * set:
1577 <filteredset
1577 <filteredset
1578 <fullreposet+ 0:9>>
1578 <fullreposet+ 0:9>>
1579 6
1579 6
1580
1580
1581 $ unset HGPLAIN
1581 $ unset HGPLAIN
1582 $ unset HGPLAINEXCEPT
1582 $ unset HGPLAINEXCEPT
1583
1583
1584 $ try 'p2(.)'
1584 $ try 'p2(.)'
1585 (func
1585 (func
1586 ('symbol', 'p2')
1586 ('symbol', 'p2')
1587 ('symbol', '.'))
1587 ('symbol', '.'))
1588 (func
1588 (func
1589 ('symbol', 'p1')
1589 ('symbol', 'p1')
1590 ('symbol', '.'))
1590 ('symbol', '.'))
1591 * set:
1591 * set:
1592 <baseset+ [8]>
1592 <baseset+ [8]>
1593 8
1593 8
1594
1594
1595 $ HGPLAIN=1
1595 $ HGPLAIN=1
1596 $ export HGPLAIN
1596 $ export HGPLAIN
1597 $ try 'p2(.)'
1597 $ try 'p2(.)'
1598 (func
1598 (func
1599 ('symbol', 'p2')
1599 ('symbol', 'p2')
1600 ('symbol', '.'))
1600 ('symbol', '.'))
1601 * set:
1601 * set:
1602 <baseset+ []>
1602 <baseset+ []>
1603
1603
1604 $ HGPLAINEXCEPT=revsetalias
1604 $ HGPLAINEXCEPT=revsetalias
1605 $ export HGPLAINEXCEPT
1605 $ export HGPLAINEXCEPT
1606 $ try 'p2(.)'
1606 $ try 'p2(.)'
1607 (func
1607 (func
1608 ('symbol', 'p2')
1608 ('symbol', 'p2')
1609 ('symbol', '.'))
1609 ('symbol', '.'))
1610 (func
1610 (func
1611 ('symbol', 'p1')
1611 ('symbol', 'p1')
1612 ('symbol', '.'))
1612 ('symbol', '.'))
1613 * set:
1613 * set:
1614 <baseset+ [8]>
1614 <baseset+ [8]>
1615 8
1615 8
1616
1616
1617 $ unset HGPLAIN
1617 $ unset HGPLAIN
1618 $ unset HGPLAINEXCEPT
1618 $ unset HGPLAINEXCEPT
1619
1619
1620 test alias recursion
1620 test alias recursion
1621
1621
1622 $ try sincem
1622 $ try sincem
1623 ('symbol', 'sincem')
1623 ('symbol', 'sincem')
1624 (func
1624 (func
1625 ('symbol', 'descendants')
1625 ('symbol', 'descendants')
1626 (func
1626 (func
1627 ('symbol', 'merge')
1627 ('symbol', 'merge')
1628 None))
1628 None))
1629 * set:
1629 * set:
1630 <addset+
1630 <addset+
1631 <filteredset
1631 <filteredset
1632 <fullreposet+ 0:9>>,
1632 <fullreposet+ 0:9>>,
1633 <generatorset+>>
1633 <generatorset+>>
1634 6
1634 6
1635 7
1635 7
1636
1636
1637 test infinite recursion
1637 test infinite recursion
1638
1638
1639 $ echo 'recurse1 = recurse2' >> .hg/hgrc
1639 $ echo 'recurse1 = recurse2' >> .hg/hgrc
1640 $ echo 'recurse2 = recurse1' >> .hg/hgrc
1640 $ echo 'recurse2 = recurse1' >> .hg/hgrc
1641 $ try recurse1
1641 $ try recurse1
1642 ('symbol', 'recurse1')
1642 ('symbol', 'recurse1')
1643 hg: parse error: infinite expansion of revset alias "recurse1" detected
1643 hg: parse error: infinite expansion of revset alias "recurse1" detected
1644 [255]
1644 [255]
1645
1645
1646 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
1646 $ echo 'level1($1, $2) = $1 or $2' >> .hg/hgrc
1647 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
1647 $ echo 'level2($1, $2) = level1($2, $1)' >> .hg/hgrc
1648 $ try "level2(level1(1, 2), 3)"
1648 $ try "level2(level1(1, 2), 3)"
1649 (func
1649 (func
1650 ('symbol', 'level2')
1650 ('symbol', 'level2')
1651 (list
1651 (list
1652 (func
1652 (func
1653 ('symbol', 'level1')
1653 ('symbol', 'level1')
1654 (list
1654 (list
1655 ('symbol', '1')
1655 ('symbol', '1')
1656 ('symbol', '2')))
1656 ('symbol', '2')))
1657 ('symbol', '3')))
1657 ('symbol', '3')))
1658 (or
1658 (or
1659 ('symbol', '3')
1659 ('symbol', '3')
1660 (or
1660 (or
1661 ('symbol', '1')
1661 ('symbol', '1')
1662 ('symbol', '2')))
1662 ('symbol', '2')))
1663 * set:
1663 * set:
1664 <addset
1664 <addset
1665 <baseset [3]>,
1665 <baseset [3]>,
1666 <baseset [1, 2]>>
1666 <baseset [1, 2]>>
1667 3
1667 3
1668 1
1668 1
1669 2
1669 2
1670
1670
1671 test nesting and variable passing
1671 test nesting and variable passing
1672
1672
1673 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
1673 $ echo 'nested($1) = nested2($1)' >> .hg/hgrc
1674 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
1674 $ echo 'nested2($1) = nested3($1)' >> .hg/hgrc
1675 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
1675 $ echo 'nested3($1) = max($1)' >> .hg/hgrc
1676 $ try 'nested(2:5)'
1676 $ try 'nested(2:5)'
1677 (func
1677 (func
1678 ('symbol', 'nested')
1678 ('symbol', 'nested')
1679 (range
1679 (range
1680 ('symbol', '2')
1680 ('symbol', '2')
1681 ('symbol', '5')))
1681 ('symbol', '5')))
1682 (func
1682 (func
1683 ('symbol', 'max')
1683 ('symbol', 'max')
1684 (range
1684 (range
1685 ('symbol', '2')
1685 ('symbol', '2')
1686 ('symbol', '5')))
1686 ('symbol', '5')))
1687 * set:
1687 * set:
1688 <baseset [5]>
1688 <baseset [5]>
1689 5
1689 5
1690
1690
1691 test chained `or` operations are flattened at parsing phase
1691 test chained `or` operations are flattened at parsing phase
1692
1692
1693 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
1693 $ echo 'chainedorops($1, $2, $3) = $1|$2|$3' >> .hg/hgrc
1694 $ try 'chainedorops(0:1, 1:2, 2:3)'
1694 $ try 'chainedorops(0:1, 1:2, 2:3)'
1695 (func
1695 (func
1696 ('symbol', 'chainedorops')
1696 ('symbol', 'chainedorops')
1697 (list
1697 (list
1698 (list
1698 (list
1699 (range
1699 (range
1700 ('symbol', '0')
1700 ('symbol', '0')
1701 ('symbol', '1'))
1701 ('symbol', '1'))
1702 (range
1702 (range
1703 ('symbol', '1')
1703 ('symbol', '1')
1704 ('symbol', '2')))
1704 ('symbol', '2')))
1705 (range
1705 (range
1706 ('symbol', '2')
1706 ('symbol', '2')
1707 ('symbol', '3'))))
1707 ('symbol', '3'))))
1708 (or
1708 (or
1709 (range
1709 (range
1710 ('symbol', '0')
1710 ('symbol', '0')
1711 ('symbol', '1'))
1711 ('symbol', '1'))
1712 (range
1712 (range
1713 ('symbol', '1')
1713 ('symbol', '1')
1714 ('symbol', '2'))
1714 ('symbol', '2'))
1715 (range
1715 (range
1716 ('symbol', '2')
1716 ('symbol', '2')
1717 ('symbol', '3')))
1717 ('symbol', '3')))
1718 * set:
1718 * set:
1719 <addset
1719 <addset
1720 <spanset+ 0:1>,
1720 <spanset+ 0:1>,
1721 <addset
1721 <addset
1722 <spanset+ 1:2>,
1722 <spanset+ 1:2>,
1723 <spanset+ 2:3>>>
1723 <spanset+ 2:3>>>
1724 0
1724 0
1725 1
1725 1
1726 2
1726 2
1727 3
1727 3
1728
1728
1729 test variable isolation, variable placeholders are rewritten as string
1729 test variable isolation, variable placeholders are rewritten as string
1730 then parsed and matched again as string. Check they do not leak too
1730 then parsed and matched again as string. Check they do not leak too
1731 far away.
1731 far away.
1732
1732
1733 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
1733 $ echo 'injectparamasstring = max("$1")' >> .hg/hgrc
1734 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
1734 $ echo 'callinjection($1) = descendants(injectparamasstring)' >> .hg/hgrc
1735 $ try 'callinjection(2:5)'
1735 $ try 'callinjection(2:5)'
1736 (func
1736 (func
1737 ('symbol', 'callinjection')
1737 ('symbol', 'callinjection')
1738 (range
1738 (range
1739 ('symbol', '2')
1739 ('symbol', '2')
1740 ('symbol', '5')))
1740 ('symbol', '5')))
1741 (func
1741 (func
1742 ('symbol', 'descendants')
1742 ('symbol', 'descendants')
1743 (func
1743 (func
1744 ('symbol', 'max')
1744 ('symbol', 'max')
1745 ('string', '$1')))
1745 ('string', '$1')))
1746 abort: unknown revision '$1'!
1746 abort: unknown revision '$1'!
1747 [255]
1747 [255]
1748
1748
1749 $ echo 'injectparamasstring2 = max(_aliasarg("$1"))' >> .hg/hgrc
1749 $ echo 'injectparamasstring2 = max(_aliasarg("$1"))' >> .hg/hgrc
1750 $ echo 'callinjection2($1) = descendants(injectparamasstring2)' >> .hg/hgrc
1750 $ echo 'callinjection2($1) = descendants(injectparamasstring2)' >> .hg/hgrc
1751 $ try 'callinjection2(2:5)'
1751 $ try 'callinjection2(2:5)'
1752 (func
1752 (func
1753 ('symbol', 'callinjection2')
1753 ('symbol', 'callinjection2')
1754 (range
1754 (range
1755 ('symbol', '2')
1755 ('symbol', '2')
1756 ('symbol', '5')))
1756 ('symbol', '5')))
1757 abort: failed to parse the definition of revset alias "injectparamasstring2": unknown identifier: _aliasarg
1757 abort: failed to parse the definition of revset alias "injectparamasstring2": unknown identifier: _aliasarg
1758 [255]
1758 [255]
1759 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
1759 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
1760 ('symbol', 'tip')
1760 ('symbol', 'tip')
1761 warning: failed to parse the definition of revset alias "anotherbadone": at 7: not a prefix: end
1761 warning: failed to parse the definition of revset alias "anotherbadone": at 7: not a prefix: end
1762 warning: failed to parse the definition of revset alias "injectparamasstring2": unknown identifier: _aliasarg
1762 warning: failed to parse the definition of revset alias "injectparamasstring2": unknown identifier: _aliasarg
1763 * set:
1763 * set:
1764 <baseset [9]>
1764 <baseset [9]>
1765 9
1765 9
1766 >>> data = file('.hg/hgrc', 'rb').read()
1766 >>> data = file('.hg/hgrc', 'rb').read()
1767 >>> file('.hg/hgrc', 'wb').write(data.replace('_aliasarg', ''))
1767 >>> file('.hg/hgrc', 'wb').write(data.replace('_aliasarg', ''))
1768
1768
1769 $ try 'tip'
1769 $ try 'tip'
1770 ('symbol', 'tip')
1770 ('symbol', 'tip')
1771 * set:
1771 * set:
1772 <baseset [9]>
1772 <baseset [9]>
1773 9
1773 9
1774
1774
1775 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
1775 $ hg debugrevspec --debug --config revsetalias.'bad name'='tip' "tip"
1776 ('symbol', 'tip')
1776 ('symbol', 'tip')
1777 warning: failed to parse the declaration of revset alias "bad name": at 4: invalid token
1777 warning: failed to parse the declaration of revset alias "bad name": at 4: invalid token
1778 * set:
1778 * set:
1779 <baseset [9]>
1779 <baseset [9]>
1780 9
1780 9
1781 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
1781 $ echo 'strictreplacing($1, $10) = $10 or desc("$1")' >> .hg/hgrc
1782 $ try 'strictreplacing("foo", tip)'
1782 $ try 'strictreplacing("foo", tip)'
1783 (func
1783 (func
1784 ('symbol', 'strictreplacing')
1784 ('symbol', 'strictreplacing')
1785 (list
1785 (list
1786 ('string', 'foo')
1786 ('string', 'foo')
1787 ('symbol', 'tip')))
1787 ('symbol', 'tip')))
1788 (or
1788 (or
1789 ('symbol', 'tip')
1789 ('symbol', 'tip')
1790 (func
1790 (func
1791 ('symbol', 'desc')
1791 ('symbol', 'desc')
1792 ('string', '$1')))
1792 ('string', '$1')))
1793 * set:
1793 * set:
1794 <addset
1794 <addset
1795 <baseset [9]>,
1795 <baseset [9]>,
1796 <filteredset
1796 <filteredset
1797 <fullreposet+ 0:9>>>
1797 <fullreposet+ 0:9>>>
1798 9
1798 9
1799
1799
1800 $ try 'd(2:5)'
1800 $ try 'd(2:5)'
1801 (func
1801 (func
1802 ('symbol', 'd')
1802 ('symbol', 'd')
1803 (range
1803 (range
1804 ('symbol', '2')
1804 ('symbol', '2')
1805 ('symbol', '5')))
1805 ('symbol', '5')))
1806 (func
1806 (func
1807 ('symbol', 'reverse')
1807 ('symbol', 'reverse')
1808 (func
1808 (func
1809 ('symbol', 'sort')
1809 ('symbol', 'sort')
1810 (list
1810 (list
1811 (range
1811 (range
1812 ('symbol', '2')
1812 ('symbol', '2')
1813 ('symbol', '5'))
1813 ('symbol', '5'))
1814 ('symbol', 'date'))))
1814 ('symbol', 'date'))))
1815 * set:
1815 * set:
1816 <baseset [4, 5, 3, 2]>
1816 <baseset [4, 5, 3, 2]>
1817 4
1817 4
1818 5
1818 5
1819 3
1819 3
1820 2
1820 2
1821 $ try 'rs(2 or 3, date)'
1821 $ try 'rs(2 or 3, date)'
1822 (func
1822 (func
1823 ('symbol', 'rs')
1823 ('symbol', 'rs')
1824 (list
1824 (list
1825 (or
1825 (or
1826 ('symbol', '2')
1826 ('symbol', '2')
1827 ('symbol', '3'))
1827 ('symbol', '3'))
1828 ('symbol', 'date')))
1828 ('symbol', 'date')))
1829 (func
1829 (func
1830 ('symbol', 'reverse')
1830 ('symbol', 'reverse')
1831 (func
1831 (func
1832 ('symbol', 'sort')
1832 ('symbol', 'sort')
1833 (list
1833 (list
1834 (or
1834 (or
1835 ('symbol', '2')
1835 ('symbol', '2')
1836 ('symbol', '3'))
1836 ('symbol', '3'))
1837 ('symbol', 'date'))))
1837 ('symbol', 'date'))))
1838 * set:
1838 * set:
1839 <baseset [3, 2]>
1839 <baseset [3, 2]>
1840 3
1840 3
1841 2
1841 2
1842 $ try 'rs()'
1842 $ try 'rs()'
1843 (func
1843 (func
1844 ('symbol', 'rs')
1844 ('symbol', 'rs')
1845 None)
1845 None)
1846 hg: parse error: invalid number of arguments: 0
1846 hg: parse error: invalid number of arguments: 0
1847 [255]
1847 [255]
1848 $ try 'rs(2)'
1848 $ try 'rs(2)'
1849 (func
1849 (func
1850 ('symbol', 'rs')
1850 ('symbol', 'rs')
1851 ('symbol', '2'))
1851 ('symbol', '2'))
1852 hg: parse error: invalid number of arguments: 1
1852 hg: parse error: invalid number of arguments: 1
1853 [255]
1853 [255]
1854 $ try 'rs(2, data, 7)'
1854 $ try 'rs(2, data, 7)'
1855 (func
1855 (func
1856 ('symbol', 'rs')
1856 ('symbol', 'rs')
1857 (list
1857 (list
1858 (list
1858 (list
1859 ('symbol', '2')
1859 ('symbol', '2')
1860 ('symbol', 'data'))
1860 ('symbol', 'data'))
1861 ('symbol', '7')))
1861 ('symbol', '7')))
1862 hg: parse error: invalid number of arguments: 3
1862 hg: parse error: invalid number of arguments: 3
1863 [255]
1863 [255]
1864 $ try 'rs4(2 or 3, x, x, date)'
1864 $ try 'rs4(2 or 3, x, x, date)'
1865 (func
1865 (func
1866 ('symbol', 'rs4')
1866 ('symbol', 'rs4')
1867 (list
1867 (list
1868 (list
1868 (list
1869 (list
1869 (list
1870 (or
1870 (or
1871 ('symbol', '2')
1871 ('symbol', '2')
1872 ('symbol', '3'))
1872 ('symbol', '3'))
1873 ('symbol', 'x'))
1873 ('symbol', 'x'))
1874 ('symbol', 'x'))
1874 ('symbol', 'x'))
1875 ('symbol', 'date')))
1875 ('symbol', 'date')))
1876 (func
1876 (func
1877 ('symbol', 'reverse')
1877 ('symbol', 'reverse')
1878 (func
1878 (func
1879 ('symbol', 'sort')
1879 ('symbol', 'sort')
1880 (list
1880 (list
1881 (or
1881 (or
1882 ('symbol', '2')
1882 ('symbol', '2')
1883 ('symbol', '3'))
1883 ('symbol', '3'))
1884 ('symbol', 'date'))))
1884 ('symbol', 'date'))))
1885 * set:
1885 * set:
1886 <baseset [3, 2]>
1886 <baseset [3, 2]>
1887 3
1887 3
1888 2
1888 2
1889
1889
1890 issue4553: check that revset aliases override existing hash prefix
1890 issue4553: check that revset aliases override existing hash prefix
1891
1891
1892 $ hg log -qr e
1892 $ hg log -qr e
1893 6:e0cc66ef77e8
1893 6:e0cc66ef77e8
1894
1894
1895 $ hg log -qr e --config revsetalias.e="all()"
1895 $ hg log -qr e --config revsetalias.e="all()"
1896 0:2785f51eece5
1896 0:2785f51eece5
1897 1:d75937da8da0
1897 1:d75937da8da0
1898 2:5ed5505e9f1c
1898 2:5ed5505e9f1c
1899 3:8528aa5637f2
1899 3:8528aa5637f2
1900 4:2326846efdab
1900 4:2326846efdab
1901 5:904fa392b941
1901 5:904fa392b941
1902 6:e0cc66ef77e8
1902 6:e0cc66ef77e8
1903 7:013af1973af4
1903 7:013af1973af4
1904 8:d5d0dcbdc4d9
1904 8:d5d0dcbdc4d9
1905 9:24286f4ae135
1905 9:24286f4ae135
1906
1906
1907 $ hg log -qr e: --config revsetalias.e="0"
1907 $ hg log -qr e: --config revsetalias.e="0"
1908 0:2785f51eece5
1908 0:2785f51eece5
1909 1:d75937da8da0
1909 1:d75937da8da0
1910 2:5ed5505e9f1c
1910 2:5ed5505e9f1c
1911 3:8528aa5637f2
1911 3:8528aa5637f2
1912 4:2326846efdab
1912 4:2326846efdab
1913 5:904fa392b941
1913 5:904fa392b941
1914 6:e0cc66ef77e8
1914 6:e0cc66ef77e8
1915 7:013af1973af4
1915 7:013af1973af4
1916 8:d5d0dcbdc4d9
1916 8:d5d0dcbdc4d9
1917 9:24286f4ae135
1917 9:24286f4ae135
1918
1918
1919 $ hg log -qr :e --config revsetalias.e="9"
1919 $ hg log -qr :e --config revsetalias.e="9"
1920 0:2785f51eece5
1920 0:2785f51eece5
1921 1:d75937da8da0
1921 1:d75937da8da0
1922 2:5ed5505e9f1c
1922 2:5ed5505e9f1c
1923 3:8528aa5637f2
1923 3:8528aa5637f2
1924 4:2326846efdab
1924 4:2326846efdab
1925 5:904fa392b941
1925 5:904fa392b941
1926 6:e0cc66ef77e8
1926 6:e0cc66ef77e8
1927 7:013af1973af4
1927 7:013af1973af4
1928 8:d5d0dcbdc4d9
1928 8:d5d0dcbdc4d9
1929 9:24286f4ae135
1929 9:24286f4ae135
1930
1930
1931 $ hg log -qr e:
1931 $ hg log -qr e:
1932 6:e0cc66ef77e8
1932 6:e0cc66ef77e8
1933 7:013af1973af4
1933 7:013af1973af4
1934 8:d5d0dcbdc4d9
1934 8:d5d0dcbdc4d9
1935 9:24286f4ae135
1935 9:24286f4ae135
1936
1936
1937 $ hg log -qr :e
1937 $ hg log -qr :e
1938 0:2785f51eece5
1938 0:2785f51eece5
1939 1:d75937da8da0
1939 1:d75937da8da0
1940 2:5ed5505e9f1c
1940 2:5ed5505e9f1c
1941 3:8528aa5637f2
1941 3:8528aa5637f2
1942 4:2326846efdab
1942 4:2326846efdab
1943 5:904fa392b941
1943 5:904fa392b941
1944 6:e0cc66ef77e8
1944 6:e0cc66ef77e8
1945
1945
1946 issue2549 - correct optimizations
1946 issue2549 - correct optimizations
1947
1947
1948 $ log 'limit(1 or 2 or 3, 2) and not 2'
1948 $ log 'limit(1 or 2 or 3, 2) and not 2'
1949 1
1949 1
1950 $ log 'max(1 or 2) and not 2'
1950 $ log 'max(1 or 2) and not 2'
1951 $ log 'min(1 or 2) and not 1'
1951 $ log 'min(1 or 2) and not 1'
1952 $ log 'last(1 or 2, 1) and not 2'
1952 $ log 'last(1 or 2, 1) and not 2'
1953
1953
1954 issue4289 - ordering of built-ins
1954 issue4289 - ordering of built-ins
1955 $ hg log -M -q -r 3:2
1955 $ hg log -M -q -r 3:2
1956 3:8528aa5637f2
1956 3:8528aa5637f2
1957 2:5ed5505e9f1c
1957 2:5ed5505e9f1c
1958
1958
1959 test revsets started with 40-chars hash (issue3669)
1959 test revsets started with 40-chars hash (issue3669)
1960
1960
1961 $ ISSUE3669_TIP=`hg tip --template '{node}'`
1961 $ ISSUE3669_TIP=`hg tip --template '{node}'`
1962 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
1962 $ hg log -r "${ISSUE3669_TIP}" --template '{rev}\n'
1963 9
1963 9
1964 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
1964 $ hg log -r "${ISSUE3669_TIP}^" --template '{rev}\n'
1965 8
1965 8
1966
1966
1967 test or-ed indirect predicates (issue3775)
1967 test or-ed indirect predicates (issue3775)
1968
1968
1969 $ log '6 or 6^1' | sort
1969 $ log '6 or 6^1' | sort
1970 5
1970 5
1971 6
1971 6
1972 $ log '6^1 or 6' | sort
1972 $ log '6^1 or 6' | sort
1973 5
1973 5
1974 6
1974 6
1975 $ log '4 or 4~1' | sort
1975 $ log '4 or 4~1' | sort
1976 2
1976 2
1977 4
1977 4
1978 $ log '4~1 or 4' | sort
1978 $ log '4~1 or 4' | sort
1979 2
1979 2
1980 4
1980 4
1981 $ log '(0 or 2):(4 or 6) or 0 or 6' | sort
1981 $ log '(0 or 2):(4 or 6) or 0 or 6' | sort
1982 0
1982 0
1983 1
1983 1
1984 2
1984 2
1985 3
1985 3
1986 4
1986 4
1987 5
1987 5
1988 6
1988 6
1989 $ log '0 or 6 or (0 or 2):(4 or 6)' | sort
1989 $ log '0 or 6 or (0 or 2):(4 or 6)' | sort
1990 0
1990 0
1991 1
1991 1
1992 2
1992 2
1993 3
1993 3
1994 4
1994 4
1995 5
1995 5
1996 6
1996 6
1997
1997
1998 tests for 'remote()' predicate:
1998 tests for 'remote()' predicate:
1999 #. (csets in remote) (id) (remote)
1999 #. (csets in remote) (id) (remote)
2000 1. less than local current branch "default"
2000 1. less than local current branch "default"
2001 2. same with local specified "default"
2001 2. same with local specified "default"
2002 3. more than local specified specified
2002 3. more than local specified specified
2003
2003
2004 $ hg clone --quiet -U . ../remote3
2004 $ hg clone --quiet -U . ../remote3
2005 $ cd ../remote3
2005 $ cd ../remote3
2006 $ hg update -q 7
2006 $ hg update -q 7
2007 $ echo r > r
2007 $ echo r > r
2008 $ hg ci -Aqm 10
2008 $ hg ci -Aqm 10
2009 $ log 'remote()'
2009 $ log 'remote()'
2010 7
2010 7
2011 $ log 'remote("a-b-c-")'
2011 $ log 'remote("a-b-c-")'
2012 2
2012 2
2013 $ cd ../repo
2013 $ cd ../repo
2014 $ log 'remote(".a.b.c.", "../remote3")'
2014 $ log 'remote(".a.b.c.", "../remote3")'
2015
2015
2016 tests for concatenation of strings/symbols by "##"
2016 tests for concatenation of strings/symbols by "##"
2017
2017
2018 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
2018 $ try "278 ## '5f5' ## 1ee ## 'ce5'"
2019 (_concat
2019 (_concat
2020 (_concat
2020 (_concat
2021 (_concat
2021 (_concat
2022 ('symbol', '278')
2022 ('symbol', '278')
2023 ('string', '5f5'))
2023 ('string', '5f5'))
2024 ('symbol', '1ee'))
2024 ('symbol', '1ee'))
2025 ('string', 'ce5'))
2025 ('string', 'ce5'))
2026 ('string', '2785f51eece5')
2026 ('string', '2785f51eece5')
2027 * set:
2027 * set:
2028 <baseset [0]>
2028 <baseset [0]>
2029 0
2029 0
2030
2030
2031 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
2031 $ echo 'cat4($1, $2, $3, $4) = $1 ## $2 ## $3 ## $4' >> .hg/hgrc
2032 $ try "cat4(278, '5f5', 1ee, 'ce5')"
2032 $ try "cat4(278, '5f5', 1ee, 'ce5')"
2033 (func
2033 (func
2034 ('symbol', 'cat4')
2034 ('symbol', 'cat4')
2035 (list
2035 (list
2036 (list
2036 (list
2037 (list
2037 (list
2038 ('symbol', '278')
2038 ('symbol', '278')
2039 ('string', '5f5'))
2039 ('string', '5f5'))
2040 ('symbol', '1ee'))
2040 ('symbol', '1ee'))
2041 ('string', 'ce5')))
2041 ('string', 'ce5')))
2042 (_concat
2042 (_concat
2043 (_concat
2043 (_concat
2044 (_concat
2044 (_concat
2045 ('symbol', '278')
2045 ('symbol', '278')
2046 ('string', '5f5'))
2046 ('string', '5f5'))
2047 ('symbol', '1ee'))
2047 ('symbol', '1ee'))
2048 ('string', 'ce5'))
2048 ('string', 'ce5'))
2049 ('string', '2785f51eece5')
2049 ('string', '2785f51eece5')
2050 * set:
2050 * set:
2051 <baseset [0]>
2051 <baseset [0]>
2052 0
2052 0
2053
2053
2054 (check concatenation in alias nesting)
2054 (check concatenation in alias nesting)
2055
2055
2056 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
2056 $ echo 'cat2($1, $2) = $1 ## $2' >> .hg/hgrc
2057 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
2057 $ echo 'cat2x2($1, $2, $3, $4) = cat2($1 ## $2, $3 ## $4)' >> .hg/hgrc
2058 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
2058 $ log "cat2x2(278, '5f5', 1ee, 'ce5')"
2059 0
2059 0
2060
2060
2061 (check operator priority)
2061 (check operator priority)
2062
2062
2063 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
2063 $ echo 'cat2n2($1, $2, $3, $4) = $1 ## $2 or $3 ## $4~2' >> .hg/hgrc
2064 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
2064 $ log "cat2n2(2785f5, 1eece5, 24286f, 4ae135)"
2065 0
2065 0
2066 4
2066 4
2067
2067
2068 $ cd ..
2068 $ cd ..
2069
2069
2070 prepare repository that has "default" branches of multiple roots
2070 prepare repository that has "default" branches of multiple roots
2071
2071
2072 $ hg init namedbranch
2072 $ hg init namedbranch
2073 $ cd namedbranch
2073 $ cd namedbranch
2074
2074
2075 $ echo default0 >> a
2075 $ echo default0 >> a
2076 $ hg ci -Aqm0
2076 $ hg ci -Aqm0
2077 $ echo default1 >> a
2077 $ echo default1 >> a
2078 $ hg ci -m1
2078 $ hg ci -m1
2079
2079
2080 $ hg branch -q stable
2080 $ hg branch -q stable
2081 $ echo stable2 >> a
2081 $ echo stable2 >> a
2082 $ hg ci -m2
2082 $ hg ci -m2
2083 $ echo stable3 >> a
2083 $ echo stable3 >> a
2084 $ hg ci -m3
2084 $ hg ci -m3
2085
2085
2086 $ hg update -q null
2086 $ hg update -q null
2087 $ echo default4 >> a
2087 $ echo default4 >> a
2088 $ hg ci -Aqm4
2088 $ hg ci -Aqm4
2089 $ echo default5 >> a
2089 $ echo default5 >> a
2090 $ hg ci -m5
2090 $ hg ci -m5
2091
2091
2092 "null" revision belongs to "default" branch (issue4683)
2092 "null" revision belongs to "default" branch (issue4683)
2093
2093
2094 $ log 'branch(null)'
2094 $ log 'branch(null)'
2095 0
2095 0
2096 1
2096 1
2097 4
2097 4
2098 5
2098 5
2099
2099
2100 "null" revision belongs to "default" branch, but it shouldn't appear in set
2100 "null" revision belongs to "default" branch, but it shouldn't appear in set
2101 unless explicitly specified (issue4682)
2101 unless explicitly specified (issue4682)
2102
2102
2103 $ log 'children(branch(default))'
2103 $ log 'children(branch(default))'
2104 1
2104 1
2105 2
2105 2
2106 5
2106 5
2107
2107
2108 $ cd ..
2108 $ cd ..
2109
2109
2110 test author/desc/keyword in problematic encoding
2110 test author/desc/keyword in problematic encoding
2111 # unicode: cp932:
2111 # unicode: cp932:
2112 # u30A2 0x83 0x41(= 'A')
2112 # u30A2 0x83 0x41(= 'A')
2113 # u30C2 0x83 0x61(= 'a')
2113 # u30C2 0x83 0x61(= 'a')
2114
2114
2115 $ hg init problematicencoding
2115 $ hg init problematicencoding
2116 $ cd problematicencoding
2116 $ cd problematicencoding
2117
2117
2118 $ python > setup.sh <<EOF
2118 $ python > setup.sh <<EOF
2119 > print u'''
2119 > print u'''
2120 > echo a > text
2120 > echo a > text
2121 > hg add text
2121 > hg add text
2122 > hg --encoding utf-8 commit -u '\u30A2' -m none
2122 > hg --encoding utf-8 commit -u '\u30A2' -m none
2123 > echo b > text
2123 > echo b > text
2124 > hg --encoding utf-8 commit -u '\u30C2' -m none
2124 > hg --encoding utf-8 commit -u '\u30C2' -m none
2125 > echo c > text
2125 > echo c > text
2126 > hg --encoding utf-8 commit -u none -m '\u30A2'
2126 > hg --encoding utf-8 commit -u none -m '\u30A2'
2127 > echo d > text
2127 > echo d > text
2128 > hg --encoding utf-8 commit -u none -m '\u30C2'
2128 > hg --encoding utf-8 commit -u none -m '\u30C2'
2129 > '''.encode('utf-8')
2129 > '''.encode('utf-8')
2130 > EOF
2130 > EOF
2131 $ sh < setup.sh
2131 $ sh < setup.sh
2132
2132
2133 test in problematic encoding
2133 test in problematic encoding
2134 $ python > test.sh <<EOF
2134 $ python > test.sh <<EOF
2135 > print u'''
2135 > print u'''
2136 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
2136 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30A2)'
2137 > echo ====
2137 > echo ====
2138 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
2138 > hg --encoding cp932 log --template '{rev}\\n' -r 'author(\u30C2)'
2139 > echo ====
2139 > echo ====
2140 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
2140 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30A2)'
2141 > echo ====
2141 > echo ====
2142 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
2142 > hg --encoding cp932 log --template '{rev}\\n' -r 'desc(\u30C2)'
2143 > echo ====
2143 > echo ====
2144 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
2144 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30A2)'
2145 > echo ====
2145 > echo ====
2146 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
2146 > hg --encoding cp932 log --template '{rev}\\n' -r 'keyword(\u30C2)'
2147 > '''.encode('cp932')
2147 > '''.encode('cp932')
2148 > EOF
2148 > EOF
2149 $ sh < test.sh
2149 $ sh < test.sh
2150 0
2150 0
2151 ====
2151 ====
2152 1
2152 1
2153 ====
2153 ====
2154 2
2154 2
2155 ====
2155 ====
2156 3
2156 3
2157 ====
2157 ====
2158 0
2158 0
2159 2
2159 2
2160 ====
2160 ====
2161 1
2161 1
2162 3
2162 3
2163
2163
2164 test error message of bad revset
2164 test error message of bad revset
2165 $ hg log -r 'foo\\'
2165 $ hg log -r 'foo\\'
2166 hg: parse error at 3: syntax error in revset 'foo\\'
2166 hg: parse error at 3: syntax error in revset 'foo\\'
2167 [255]
2167 [255]
2168
2168
2169 $ cd ..
2169 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now