comparison mercurial/revset.py @ 13915:8f81d6f4047f

revset: rearrange code so functions are sorted alphabetically
author Idan Kamara <idankk86@gmail.com>
date Fri, 08 Apr 2011 17:47:58 +0300
parents 27573f2ddfb9
children 34f577007ffe
comparison
equal deleted inserted replaced
13914:27573f2ddfb9 13915:8f81d6f4047f
172 return symbols[a[1]](repo, subset, b) 172 return symbols[a[1]](repo, subset, b)
173 raise error.ParseError(_("not a function: %s") % a[1]) 173 raise error.ParseError(_("not a function: %s") % a[1])
174 174
175 # functions 175 # functions
176 176
177 def node(repo, subset, x): 177 def adds(repo, subset, x):
178 """``id(string)`` 178 """``adds(pattern)``
179 Revision non-ambiguously specified by the given hex string prefix. 179 Changesets that add a file matching pattern.
180 """ 180 """
181 # i18n: "id" is a keyword 181 # i18n: "adds" is a keyword
182 l = getargs(x, 1, 1, _("id requires one argument")) 182 pat = getstring(x, _("adds requires a pattern"))
183 # i18n: "id" is a keyword 183 return checkstatus(repo, subset, pat, 1)
184 n = getstring(l[0], _("id requires a string"))
185 if len(n) == 40:
186 rn = repo[n].rev()
187 else:
188 rn = repo.changelog.rev(repo.changelog._partialmatch(n))
189 return [r for r in subset if r == rn]
190
191 def rev(repo, subset, x):
192 """``rev(number)``
193 Revision with the given numeric identifier.
194 """
195 # i18n: "rev" is a keyword
196 l = getargs(x, 1, 1, _("rev requires one argument"))
197 try:
198 # i18n: "rev" is a keyword
199 l = int(getstring(l[0], _("rev requires a number")))
200 except ValueError:
201 # i18n: "rev" is a keyword
202 raise error.ParseError(_("rev expects a number"))
203 return [r for r in subset if r == l]
204
205 def p1(repo, subset, x):
206 """``p1([set])``
207 First parent of changesets in set, or the working directory.
208 """
209 if x is None:
210 p = repo[x].p1().rev()
211 return [r for r in subset if r == p]
212
213 ps = set()
214 cl = repo.changelog
215 for r in getset(repo, range(len(repo)), x):
216 ps.add(cl.parentrevs(r)[0])
217 return [r for r in subset if r in ps]
218
219 def p2(repo, subset, x):
220 """``p2([set])``
221 Second parent of changesets in set, or the working directory.
222 """
223 if x is None:
224 ps = repo[x].parents()
225 try:
226 p = ps[1].rev()
227 return [r for r in subset if r == p]
228 except IndexError:
229 return []
230
231 ps = set()
232 cl = repo.changelog
233 for r in getset(repo, range(len(repo)), x):
234 ps.add(cl.parentrevs(r)[1])
235 return [r for r in subset if r in ps]
236
237 def parents(repo, subset, x):
238 """``parents([set])``
239 The set of all parents for all changesets in set, or the working directory.
240 """
241 if x is None:
242 ps = tuple(p.rev() for p in repo[x].parents())
243 return [r for r in subset if r in ps]
244
245 ps = set()
246 cl = repo.changelog
247 for r in getset(repo, range(len(repo)), x):
248 ps.update(cl.parentrevs(r))
249 return [r for r in subset if r in ps]
250
251 def maxrev(repo, subset, x):
252 """``max(set)``
253 Changeset with highest revision number in set.
254 """
255 s = getset(repo, subset, x)
256 if s:
257 m = max(s)
258 if m in subset:
259 return [m]
260 return []
261
262 def minrev(repo, subset, x):
263 """``min(set)``
264 Changeset with lowest revision number in set.
265 """
266 s = getset(repo, subset, x)
267 if s:
268 m = min(s)
269 if m in subset:
270 return [m]
271 return []
272
273 def limit(repo, subset, x):
274 """``limit(set, n)``
275 First n members of set.
276 """
277 # i18n: "limit" is a keyword
278 l = getargs(x, 2, 2, _("limit requires two arguments"))
279 try:
280 # i18n: "limit" is a keyword
281 lim = int(getstring(l[1], _("limit requires a number")))
282 except ValueError:
283 # i18n: "limit" is a keyword
284 raise error.ParseError(_("limit expects a number"))
285 return getset(repo, subset, l[0])[:lim]
286
287 def children(repo, subset, x):
288 """``children(set)``
289 Child changesets of changesets in set.
290 """
291 cs = set()
292 cl = repo.changelog
293 s = set(getset(repo, range(len(repo)), x))
294 for r in xrange(0, len(repo)):
295 for p in cl.parentrevs(r):
296 if p in s:
297 cs.add(r)
298 return [r for r in subset if r in cs]
299
300 def branch(repo, subset, x):
301 """``branch(string or set)``
302 All changesets belonging to the given branch or the branches of the given
303 changesets.
304 """
305 try:
306 b = getstring(x, '')
307 if b in repo.branchmap():
308 return [r for r in subset if repo[r].branch() == b]
309 except error.ParseError:
310 # not a string, but another revspec, e.g. tip()
311 pass
312
313 s = getset(repo, range(len(repo)), x)
314 b = set()
315 for r in s:
316 b.add(repo[r].branch())
317 s = set(s)
318 return [r for r in subset if r in s or repo[r].branch() in b]
319 184
320 def ancestor(repo, subset, x): 185 def ancestor(repo, subset, x):
321 """``ancestor(single, single)`` 186 """``ancestor(single, single)``
322 Greatest common ancestor of the two changesets. 187 Greatest common ancestor of the two changesets.
323 """ 188 """
341 if not args: 206 if not args:
342 return [] 207 return []
343 s = set(repo.changelog.ancestors(*args)) | set(args) 208 s = set(repo.changelog.ancestors(*args)) | set(args)
344 return [r for r in subset if r in s] 209 return [r for r in subset if r in s]
345 210
346 def descendants(repo, subset, x):
347 """``descendants(set)``
348 Changesets which are descendants of changesets in set.
349 """
350 args = getset(repo, range(len(repo)), x)
351 if not args:
352 return []
353 s = set(repo.changelog.descendants(*args)) | set(args)
354 return [r for r in subset if r in s]
355
356 def follow(repo, subset, x):
357 """``follow()``
358 An alias for ``::.`` (ancestors of the working copy's first parent).
359 """
360 # i18n: "follow" is a keyword
361 getargs(x, 0, 0, _("follow takes no arguments"))
362 p = repo['.'].rev()
363 s = set(repo.changelog.ancestors(p)) | set([p])
364 return [r for r in subset if r in s]
365
366 def date(repo, subset, x):
367 """``date(interval)``
368 Changesets within the interval, see :hg:`help dates`.
369 """
370 # i18n: "date" is a keyword
371 ds = getstring(x, _("date requires a string"))
372 dm = util.matchdate(ds)
373 return [r for r in subset if dm(repo[r].date()[0])]
374
375 def keyword(repo, subset, x):
376 """``keyword(string)``
377 Search commit message, user name, and names of changed files for
378 string.
379 """
380 # i18n: "keyword" is a keyword
381 kw = getstring(x, _("keyword requires a string")).lower()
382 l = []
383 for r in subset:
384 c = repo[r]
385 t = " ".join(c.files() + [c.user(), c.description()])
386 if kw in t.lower():
387 l.append(r)
388 return l
389
390 def grep(repo, subset, x):
391 """``grep(regex)``
392 Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
393 to ensure special escape characters are handled correctly.
394 """
395 try:
396 # i18n: "grep" is a keyword
397 gr = re.compile(getstring(x, _("grep requires a string")))
398 except re.error, e:
399 raise error.ParseError(_('invalid match pattern: %s') % e)
400 l = []
401 for r in subset:
402 c = repo[r]
403 for e in c.files() + [c.user(), c.description()]:
404 if gr.search(e):
405 l.append(r)
406 break
407 return l
408
409 def author(repo, subset, x): 211 def author(repo, subset, x):
410 """``author(string)`` 212 """``author(string)``
411 Alias for ``user(string)``. 213 Alias for ``user(string)``.
412 """ 214 """
413 # i18n: "author" is a keyword 215 # i18n: "author" is a keyword
414 n = getstring(x, _("author requires a string")).lower() 216 n = getstring(x, _("author requires a string")).lower()
415 return [r for r in subset if n in repo[r].user().lower()] 217 return [r for r in subset if n in repo[r].user().lower()]
416 218
417 def user(repo, subset, x): 219 def bisected(repo, subset, x):
418 """``user(string)`` 220 """``bisected(string)``
419 User name is string. 221 Changesets marked in the specified bisect state (good, bad, skip).
420 """ 222 """
421 return author(repo, subset, x) 223 state = getstring(x, _("bisect requires a string")).lower()
422 224 if state not in ('good', 'bad', 'skip', 'unknown'):
423 def hasfile(repo, subset, x): 225 raise ParseError(_('invalid bisect state'))
424 """``file(pattern)`` 226 marked = set(repo.changelog.rev(n) for n in hbisect.load_state(repo)[state])
425 Changesets affecting files matched by pattern. 227 return [r for r in subset if r in marked]
426 """ 228
427 # i18n: "file" is a keyword 229 def bookmark(repo, subset, x):
428 pat = getstring(x, _("file requires a pattern")) 230 """``bookmark([name])``
429 m = matchmod.match(repo.root, repo.getcwd(), [pat]) 231 The named bookmark or all bookmarks.
430 s = [] 232 """
431 for r in subset: 233 # i18n: "bookmark" is a keyword
432 for f in repo[r].files(): 234 args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
433 if m(f): 235 if args:
434 s.append(r) 236 bm = getstring(args[0],
435 break 237 # i18n: "bookmark" is a keyword
436 return s 238 _('the argument to bookmark must be a string'))
437 239 bmrev = bookmarksmod.listbookmarks(repo).get(bm, None)
438 def contains(repo, subset, x): 240 if not bmrev:
439 """``contains(pattern)`` 241 raise util.Abort(_("bookmark '%s' does not exist") % bm)
440 Revision contains pattern. 242 bmrev = repo[bmrev].rev()
441 """ 243 return [r for r in subset if r == bmrev]
442 # i18n: "contains" is a keyword 244 bms = set([repo[r].rev()
443 pat = getstring(x, _("contains requires a pattern")) 245 for r in bookmarksmod.listbookmarks(repo).values()])
444 m = matchmod.match(repo.root, repo.getcwd(), [pat]) 246 return [r for r in subset if r in bms]
445 s = [] 247
446 if m.files() == [pat]: 248 def branch(repo, subset, x):
447 for r in subset: 249 """``branch(string or set)``
448 if pat in repo[r]: 250 All changesets belonging to the given branch or the branches of the given
449 s.append(r) 251 changesets.
450 else: 252 """
451 for r in subset: 253 try:
452 for f in repo[r].manifest(): 254 b = getstring(x, '')
453 if m(f): 255 if b in repo.branchmap():
454 s.append(r) 256 return [r for r in subset if repo[r].branch() == b]
455 break 257 except error.ParseError:
456 return s 258 # not a string, but another revspec, e.g. tip()
259 pass
260
261 s = getset(repo, range(len(repo)), x)
262 b = set()
263 for r in s:
264 b.add(repo[r].branch())
265 s = set(s)
266 return [r for r in subset if r in s or repo[r].branch() in b]
457 267
458 def checkstatus(repo, subset, pat, field): 268 def checkstatus(repo, subset, pat, field):
459 m = matchmod.match(repo.root, repo.getcwd(), [pat]) 269 m = matchmod.match(repo.root, repo.getcwd(), [pat])
460 s = [] 270 s = []
461 fast = (m.files() == [pat]) 271 fast = (m.files() == [pat])
479 if m(f): 289 if m(f):
480 s.append(r) 290 s.append(r)
481 break 291 break
482 return s 292 return s
483 293
484 def modifies(repo, subset, x): 294 def children(repo, subset, x):
485 """``modifies(pattern)`` 295 """``children(set)``
486 Changesets modifying files matched by pattern. 296 Child changesets of changesets in set.
487 """ 297 """
488 # i18n: "modifies" is a keyword 298 cs = set()
489 pat = getstring(x, _("modifies requires a pattern"))
490 return checkstatus(repo, subset, pat, 0)
491
492 def adds(repo, subset, x):
493 """``adds(pattern)``
494 Changesets that add a file matching pattern.
495 """
496 # i18n: "adds" is a keyword
497 pat = getstring(x, _("adds requires a pattern"))
498 return checkstatus(repo, subset, pat, 1)
499
500 def removes(repo, subset, x):
501 """``removes(pattern)``
502 Changesets which remove files matching pattern.
503 """
504 # i18n: "removes" is a keyword
505 pat = getstring(x, _("removes requires a pattern"))
506 return checkstatus(repo, subset, pat, 2)
507
508 def merge(repo, subset, x):
509 """``merge()``
510 Changeset is a merge changeset.
511 """
512 # i18n: "merge" is a keyword
513 getargs(x, 0, 0, _("merge takes no arguments"))
514 cl = repo.changelog 299 cl = repo.changelog
515 return [r for r in subset if cl.parentrevs(r)[1] != -1] 300 s = set(getset(repo, range(len(repo)), x))
301 for r in xrange(0, len(repo)):
302 for p in cl.parentrevs(r):
303 if p in s:
304 cs.add(r)
305 return [r for r in subset if r in cs]
516 306
517 def closed(repo, subset, x): 307 def closed(repo, subset, x):
518 """``closed()`` 308 """``closed()``
519 Changeset is closed. 309 Changeset is closed.
520 """ 310 """
521 # i18n: "closed" is a keyword 311 # i18n: "closed" is a keyword
522 getargs(x, 0, 0, _("closed takes no arguments")) 312 getargs(x, 0, 0, _("closed takes no arguments"))
523 return [r for r in subset if repo[r].extra().get('close')] 313 return [r for r in subset if repo[r].extra().get('close')]
314
315 def contains(repo, subset, x):
316 """``contains(pattern)``
317 Revision contains pattern.
318 """
319 # i18n: "contains" is a keyword
320 pat = getstring(x, _("contains requires a pattern"))
321 m = matchmod.match(repo.root, repo.getcwd(), [pat])
322 s = []
323 if m.files() == [pat]:
324 for r in subset:
325 if pat in repo[r]:
326 s.append(r)
327 else:
328 for r in subset:
329 for f in repo[r].manifest():
330 if m(f):
331 s.append(r)
332 break
333 return s
334
335 def date(repo, subset, x):
336 """``date(interval)``
337 Changesets within the interval, see :hg:`help dates`.
338 """
339 # i18n: "date" is a keyword
340 ds = getstring(x, _("date requires a string"))
341 dm = util.matchdate(ds)
342 return [r for r in subset if dm(repo[r].date()[0])]
343
344 def descendants(repo, subset, x):
345 """``descendants(set)``
346 Changesets which are descendants of changesets in set.
347 """
348 args = getset(repo, range(len(repo)), x)
349 if not args:
350 return []
351 s = set(repo.changelog.descendants(*args)) | set(args)
352 return [r for r in subset if r in s]
353
354 def follow(repo, subset, x):
355 """``follow()``
356 An alias for ``::.`` (ancestors of the working copy's first parent).
357 """
358 # i18n: "follow" is a keyword
359 getargs(x, 0, 0, _("follow takes no arguments"))
360 p = repo['.'].rev()
361 s = set(repo.changelog.ancestors(p)) | set([p])
362 return [r for r in subset if r in s]
363
364 def getall(repo, subset, x):
365 """``all()``
366 All changesets, the same as ``0:tip``.
367 """
368 # i18n: "all" is a keyword
369 getargs(x, 0, 0, _("all takes no arguments"))
370 return subset
371
372 def grep(repo, subset, x):
373 """``grep(regex)``
374 Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
375 to ensure special escape characters are handled correctly.
376 """
377 try:
378 # i18n: "grep" is a keyword
379 gr = re.compile(getstring(x, _("grep requires a string")))
380 except re.error, e:
381 raise error.ParseError(_('invalid match pattern: %s') % e)
382 l = []
383 for r in subset:
384 c = repo[r]
385 for e in c.files() + [c.user(), c.description()]:
386 if gr.search(e):
387 l.append(r)
388 break
389 return l
390
391 def hasfile(repo, subset, x):
392 """``file(pattern)``
393 Changesets affecting files matched by pattern.
394 """
395 # i18n: "file" is a keyword
396 pat = getstring(x, _("file requires a pattern"))
397 m = matchmod.match(repo.root, repo.getcwd(), [pat])
398 s = []
399 for r in subset:
400 for f in repo[r].files():
401 if m(f):
402 s.append(r)
403 break
404 return s
524 405
525 def head(repo, subset, x): 406 def head(repo, subset, x):
526 """``head()`` 407 """``head()``
527 Changeset is a named branch head. 408 Changeset is a named branch head.
528 """ 409 """
531 hs = set() 412 hs = set()
532 for b, ls in repo.branchmap().iteritems(): 413 for b, ls in repo.branchmap().iteritems():
533 hs.update(repo[h].rev() for h in ls) 414 hs.update(repo[h].rev() for h in ls)
534 return [r for r in subset if r in hs] 415 return [r for r in subset if r in hs]
535 416
536 def reverse(repo, subset, x): 417 def heads(repo, subset, x):
537 """``reverse(set)`` 418 """``heads(set)``
538 Reverse order of set. 419 Members of set with no children in set.
539 """ 420 """
540 l = getset(repo, subset, x) 421 s = getset(repo, subset, x)
541 l.reverse() 422 ps = set(parents(repo, subset, x))
423 return [r for r in s if r not in ps]
424
425 def keyword(repo, subset, x):
426 """``keyword(string)``
427 Search commit message, user name, and names of changed files for
428 string.
429 """
430 # i18n: "keyword" is a keyword
431 kw = getstring(x, _("keyword requires a string")).lower()
432 l = []
433 for r in subset:
434 c = repo[r]
435 t = " ".join(c.files() + [c.user(), c.description()])
436 if kw in t.lower():
437 l.append(r)
542 return l 438 return l
439
440 def limit(repo, subset, x):
441 """``limit(set, n)``
442 First n members of set.
443 """
444 # i18n: "limit" is a keyword
445 l = getargs(x, 2, 2, _("limit requires two arguments"))
446 try:
447 # i18n: "limit" is a keyword
448 lim = int(getstring(l[1], _("limit requires a number")))
449 except ValueError:
450 # i18n: "limit" is a keyword
451 raise error.ParseError(_("limit expects a number"))
452 return getset(repo, subset, l[0])[:lim]
453
454 def maxrev(repo, subset, x):
455 """``max(set)``
456 Changeset with highest revision number in set.
457 """
458 s = getset(repo, subset, x)
459 if s:
460 m = max(s)
461 if m in subset:
462 return [m]
463 return []
464
465 def merge(repo, subset, x):
466 """``merge()``
467 Changeset is a merge changeset.
468 """
469 # i18n: "merge" is a keyword
470 getargs(x, 0, 0, _("merge takes no arguments"))
471 cl = repo.changelog
472 return [r for r in subset if cl.parentrevs(r)[1] != -1]
473
474 def minrev(repo, subset, x):
475 """``min(set)``
476 Changeset with lowest revision number in set.
477 """
478 s = getset(repo, subset, x)
479 if s:
480 m = min(s)
481 if m in subset:
482 return [m]
483 return []
484
485 def modifies(repo, subset, x):
486 """``modifies(pattern)``
487 Changesets modifying files matched by pattern.
488 """
489 # i18n: "modifies" is a keyword
490 pat = getstring(x, _("modifies requires a pattern"))
491 return checkstatus(repo, subset, pat, 0)
492
493 def node(repo, subset, x):
494 """``id(string)``
495 Revision non-ambiguously specified by the given hex string prefix.
496 """
497 # i18n: "id" is a keyword
498 l = getargs(x, 1, 1, _("id requires one argument"))
499 # i18n: "id" is a keyword
500 n = getstring(l[0], _("id requires a string"))
501 if len(n) == 40:
502 rn = repo[n].rev()
503 else:
504 rn = repo.changelog.rev(repo.changelog._partialmatch(n))
505 return [r for r in subset if r == rn]
506
507 def outgoing(repo, subset, x):
508 """``outgoing([path])``
509 Changesets not found in the specified destination repository, or the
510 default push location.
511 """
512 import hg # avoid start-up nasties
513 # i18n: "outgoing" is a keyword
514 l = getargs(x, 0, 1, _("outgoing requires a repository path"))
515 # i18n: "outgoing" is a keyword
516 dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
517 dest = repo.ui.expandpath(dest or 'default-push', dest or 'default')
518 dest, branches = hg.parseurl(dest)
519 revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
520 if revs:
521 revs = [repo.lookup(rev) for rev in revs]
522 other = hg.repository(hg.remoteui(repo, {}), dest)
523 repo.ui.pushbuffer()
524 o = discovery.findoutgoing(repo, other)
525 repo.ui.popbuffer()
526 cl = repo.changelog
527 o = set([cl.rev(r) for r in repo.changelog.nodesbetween(o, revs)[0]])
528 return [r for r in subset if r in o]
529
530 def p1(repo, subset, x):
531 """``p1([set])``
532 First parent of changesets in set, or the working directory.
533 """
534 if x is None:
535 p = repo[x].p1().rev()
536 return [r for r in subset if r == p]
537
538 ps = set()
539 cl = repo.changelog
540 for r in getset(repo, range(len(repo)), x):
541 ps.add(cl.parentrevs(r)[0])
542 return [r for r in subset if r in ps]
543
544 def p2(repo, subset, x):
545 """``p2([set])``
546 Second parent of changesets in set, or the working directory.
547 """
548 if x is None:
549 ps = repo[x].parents()
550 try:
551 p = ps[1].rev()
552 return [r for r in subset if r == p]
553 except IndexError:
554 return []
555
556 ps = set()
557 cl = repo.changelog
558 for r in getset(repo, range(len(repo)), x):
559 ps.add(cl.parentrevs(r)[1])
560 return [r for r in subset if r in ps]
561
562 def parents(repo, subset, x):
563 """``parents([set])``
564 The set of all parents for all changesets in set, or the working directory.
565 """
566 if x is None:
567 ps = tuple(p.rev() for p in repo[x].parents())
568 return [r for r in subset if r in ps]
569
570 ps = set()
571 cl = repo.changelog
572 for r in getset(repo, range(len(repo)), x):
573 ps.update(cl.parentrevs(r))
574 return [r for r in subset if r in ps]
543 575
544 def present(repo, subset, x): 576 def present(repo, subset, x):
545 """``present(set)`` 577 """``present(set)``
546 An empty set, if any revision in set isn't found; otherwise, 578 An empty set, if any revision in set isn't found; otherwise,
547 all revisions in set. 579 all revisions in set.
548 """ 580 """
549 try: 581 try:
550 return getset(repo, subset, x) 582 return getset(repo, subset, x)
551 except error.RepoLookupError: 583 except error.RepoLookupError:
552 return [] 584 return []
585
586 def removes(repo, subset, x):
587 """``removes(pattern)``
588 Changesets which remove files matching pattern.
589 """
590 # i18n: "removes" is a keyword
591 pat = getstring(x, _("removes requires a pattern"))
592 return checkstatus(repo, subset, pat, 2)
593
594 def rev(repo, subset, x):
595 """``rev(number)``
596 Revision with the given numeric identifier.
597 """
598 # i18n: "rev" is a keyword
599 l = getargs(x, 1, 1, _("rev requires one argument"))
600 try:
601 # i18n: "rev" is a keyword
602 l = int(getstring(l[0], _("rev requires a number")))
603 except ValueError:
604 # i18n: "rev" is a keyword
605 raise error.ParseError(_("rev expects a number"))
606 return [r for r in subset if r == l]
607
608 def reverse(repo, subset, x):
609 """``reverse(set)``
610 Reverse order of set.
611 """
612 l = getset(repo, subset, x)
613 l.reverse()
614 return l
615
616 def roots(repo, subset, x):
617 """``roots(set)``
618 Changesets with no parent changeset in set.
619 """
620 s = getset(repo, subset, x)
621 cs = set(children(repo, subset, x))
622 return [r for r in s if r not in cs]
553 623
554 def sort(repo, subset, x): 624 def sort(repo, subset, x):
555 """``sort(set[, [-]key...])`` 625 """``sort(set[, [-]key...])``
556 Sort set by keys. The default sort order is ascending, specify a key 626 Sort set by keys. The default sort order is ascending, specify a key
557 as ``-key`` to sort in descending order. 627 as ``-key`` to sort in descending order.
604 e.append(r) 674 e.append(r)
605 l.append(e) 675 l.append(e)
606 l.sort() 676 l.sort()
607 return [e[-1] for e in l] 677 return [e[-1] for e in l]
608 678
609 def getall(repo, subset, x):
610 """``all()``
611 All changesets, the same as ``0:tip``.
612 """
613 # i18n: "all" is a keyword
614 getargs(x, 0, 0, _("all takes no arguments"))
615 return subset
616
617 def heads(repo, subset, x):
618 """``heads(set)``
619 Members of set with no children in set.
620 """
621 s = getset(repo, subset, x)
622 ps = set(parents(repo, subset, x))
623 return [r for r in s if r not in ps]
624
625 def roots(repo, subset, x):
626 """``roots(set)``
627 Changesets with no parent changeset in set.
628 """
629 s = getset(repo, subset, x)
630 cs = set(children(repo, subset, x))
631 return [r for r in s if r not in cs]
632
633 def outgoing(repo, subset, x):
634 """``outgoing([path])``
635 Changesets not found in the specified destination repository, or the
636 default push location.
637 """
638 import hg # avoid start-up nasties
639 # i18n: "outgoing" is a keyword
640 l = getargs(x, 0, 1, _("outgoing requires a repository path"))
641 # i18n: "outgoing" is a keyword
642 dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
643 dest = repo.ui.expandpath(dest or 'default-push', dest or 'default')
644 dest, branches = hg.parseurl(dest)
645 revs, checkout = hg.addbranchrevs(repo, repo, branches, [])
646 if revs:
647 revs = [repo.lookup(rev) for rev in revs]
648 other = hg.repository(hg.remoteui(repo, {}), dest)
649 repo.ui.pushbuffer()
650 o = discovery.findoutgoing(repo, other)
651 repo.ui.popbuffer()
652 cl = repo.changelog
653 o = set([cl.rev(r) for r in repo.changelog.nodesbetween(o, revs)[0]])
654 return [r for r in subset if r in o]
655
656 def tag(repo, subset, x): 679 def tag(repo, subset, x):
657 """``tag(name)`` 680 """``tag(name)``
658 The specified tag by name, or all tagged revisions if no name is given. 681 The specified tag by name, or all tagged revisions if no name is given.
659 """ 682 """
660 # i18n: "tag" is a keyword 683 # i18n: "tag" is a keyword
672 return [r for r in subset if r in s] 695 return [r for r in subset if r in s]
673 696
674 def tagged(repo, subset, x): 697 def tagged(repo, subset, x):
675 return tag(repo, subset, x) 698 return tag(repo, subset, x)
676 699
677 def bookmark(repo, subset, x): 700 def user(repo, subset, x):
678 """``bookmark([name])`` 701 """``user(string)``
679 The named bookmark or all bookmarks. 702 User name is string.
680 """ 703 """
681 # i18n: "bookmark" is a keyword 704 return author(repo, subset, x)
682 args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
683 if args:
684 bm = getstring(args[0],
685 # i18n: "bookmark" is a keyword
686 _('the argument to bookmark must be a string'))
687 bmrev = bookmarksmod.listbookmarks(repo).get(bm, None)
688 if not bmrev:
689 raise util.Abort(_("bookmark '%s' does not exist") % bm)
690 bmrev = repo[bmrev].rev()
691 return [r for r in subset if r == bmrev]
692 bms = set([repo[r].rev()
693 for r in bookmarksmod.listbookmarks(repo).values()])
694 return [r for r in subset if r in bms]
695
696 def bisected(repo, subset, x):
697 """``bisected(string)``
698 Changesets marked in the specified bisect state (good, bad, skip).
699 """
700 state = getstring(x, _("bisect requires a string")).lower()
701 if state not in ('good', 'bad', 'skip', 'unknown'):
702 raise ParseError(_('invalid bisect state'))
703 marked = set(repo.changelog.rev(n) for n in hbisect.load_state(repo)[state])
704 return [r for r in subset if r in marked]
705 705
706 symbols = { 706 symbols = {
707 "adds": adds, 707 "adds": adds,
708 "all": getall, 708 "all": getall,
709 "ancestor": ancestor, 709 "ancestor": ancestor,