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, |