Show More
This diff has been collapsed as it changes many lines, (730 lines changed) Show them Hide them | |||||
@@ -174,6 +174,322 b' def func(repo, subset, a, b):' | |||||
174 |
|
174 | |||
175 | # functions |
|
175 | # functions | |
176 |
|
176 | |||
|
177 | def adds(repo, subset, x): | |||
|
178 | """``adds(pattern)`` | |||
|
179 | Changesets that add a file matching pattern. | |||
|
180 | """ | |||
|
181 | # i18n: "adds" is a keyword | |||
|
182 | pat = getstring(x, _("adds requires a pattern")) | |||
|
183 | return checkstatus(repo, subset, pat, 1) | |||
|
184 | ||||
|
185 | def ancestor(repo, subset, x): | |||
|
186 | """``ancestor(single, single)`` | |||
|
187 | Greatest common ancestor of the two changesets. | |||
|
188 | """ | |||
|
189 | # i18n: "ancestor" is a keyword | |||
|
190 | l = getargs(x, 2, 2, _("ancestor requires two arguments")) | |||
|
191 | r = range(len(repo)) | |||
|
192 | a = getset(repo, r, l[0]) | |||
|
193 | b = getset(repo, r, l[1]) | |||
|
194 | if len(a) != 1 or len(b) != 1: | |||
|
195 | # i18n: "ancestor" is a keyword | |||
|
196 | raise error.ParseError(_("ancestor arguments must be single revisions")) | |||
|
197 | an = [repo[a[0]].ancestor(repo[b[0]]).rev()] | |||
|
198 | ||||
|
199 | return [r for r in an if r in subset] | |||
|
200 | ||||
|
201 | def ancestors(repo, subset, x): | |||
|
202 | """``ancestors(set)`` | |||
|
203 | Changesets that are ancestors of a changeset in set. | |||
|
204 | """ | |||
|
205 | args = getset(repo, range(len(repo)), x) | |||
|
206 | if not args: | |||
|
207 | return [] | |||
|
208 | s = set(repo.changelog.ancestors(*args)) | set(args) | |||
|
209 | return [r for r in subset if r in s] | |||
|
210 | ||||
|
211 | def author(repo, subset, x): | |||
|
212 | """``author(string)`` | |||
|
213 | Alias for ``user(string)``. | |||
|
214 | """ | |||
|
215 | # i18n: "author" is a keyword | |||
|
216 | n = getstring(x, _("author requires a string")).lower() | |||
|
217 | return [r for r in subset if n in repo[r].user().lower()] | |||
|
218 | ||||
|
219 | def bisected(repo, subset, x): | |||
|
220 | """``bisected(string)`` | |||
|
221 | Changesets marked in the specified bisect state (good, bad, skip). | |||
|
222 | """ | |||
|
223 | state = getstring(x, _("bisect requires a string")).lower() | |||
|
224 | if state not in ('good', 'bad', 'skip', 'unknown'): | |||
|
225 | raise ParseError(_('invalid bisect state')) | |||
|
226 | marked = set(repo.changelog.rev(n) for n in hbisect.load_state(repo)[state]) | |||
|
227 | return [r for r in subset if r in marked] | |||
|
228 | ||||
|
229 | def bookmark(repo, subset, x): | |||
|
230 | """``bookmark([name])`` | |||
|
231 | The named bookmark or all bookmarks. | |||
|
232 | """ | |||
|
233 | # i18n: "bookmark" is a keyword | |||
|
234 | args = getargs(x, 0, 1, _('bookmark takes one or no arguments')) | |||
|
235 | if args: | |||
|
236 | bm = getstring(args[0], | |||
|
237 | # i18n: "bookmark" is a keyword | |||
|
238 | _('the argument to bookmark must be a string')) | |||
|
239 | bmrev = bookmarksmod.listbookmarks(repo).get(bm, None) | |||
|
240 | if not bmrev: | |||
|
241 | raise util.Abort(_("bookmark '%s' does not exist") % bm) | |||
|
242 | bmrev = repo[bmrev].rev() | |||
|
243 | return [r for r in subset if r == bmrev] | |||
|
244 | bms = set([repo[r].rev() | |||
|
245 | for r in bookmarksmod.listbookmarks(repo).values()]) | |||
|
246 | return [r for r in subset if r in bms] | |||
|
247 | ||||
|
248 | def branch(repo, subset, x): | |||
|
249 | """``branch(string or set)`` | |||
|
250 | All changesets belonging to the given branch or the branches of the given | |||
|
251 | changesets. | |||
|
252 | """ | |||
|
253 | try: | |||
|
254 | b = getstring(x, '') | |||
|
255 | if b in repo.branchmap(): | |||
|
256 | return [r for r in subset if repo[r].branch() == b] | |||
|
257 | except error.ParseError: | |||
|
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] | |||
|
267 | ||||
|
268 | def checkstatus(repo, subset, pat, field): | |||
|
269 | m = matchmod.match(repo.root, repo.getcwd(), [pat]) | |||
|
270 | s = [] | |||
|
271 | fast = (m.files() == [pat]) | |||
|
272 | for r in subset: | |||
|
273 | c = repo[r] | |||
|
274 | if fast: | |||
|
275 | if pat not in c.files(): | |||
|
276 | continue | |||
|
277 | else: | |||
|
278 | for f in c.files(): | |||
|
279 | if m(f): | |||
|
280 | break | |||
|
281 | else: | |||
|
282 | continue | |||
|
283 | files = repo.status(c.p1().node(), c.node())[field] | |||
|
284 | if fast: | |||
|
285 | if pat in files: | |||
|
286 | s.append(r) | |||
|
287 | else: | |||
|
288 | for f in files: | |||
|
289 | if m(f): | |||
|
290 | s.append(r) | |||
|
291 | break | |||
|
292 | return s | |||
|
293 | ||||
|
294 | def children(repo, subset, x): | |||
|
295 | """``children(set)`` | |||
|
296 | Child changesets of changesets in set. | |||
|
297 | """ | |||
|
298 | cs = set() | |||
|
299 | cl = repo.changelog | |||
|
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] | |||
|
306 | ||||
|
307 | def closed(repo, subset, x): | |||
|
308 | """``closed()`` | |||
|
309 | Changeset is closed. | |||
|
310 | """ | |||
|
311 | # i18n: "closed" is a keyword | |||
|
312 | getargs(x, 0, 0, _("closed takes no arguments")) | |||
|
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 | |||
|
405 | ||||
|
406 | def head(repo, subset, x): | |||
|
407 | """``head()`` | |||
|
408 | Changeset is a named branch head. | |||
|
409 | """ | |||
|
410 | # i18n: "head" is a keyword | |||
|
411 | getargs(x, 0, 0, _("head takes no arguments")) | |||
|
412 | hs = set() | |||
|
413 | for b, ls in repo.branchmap().iteritems(): | |||
|
414 | hs.update(repo[h].rev() for h in ls) | |||
|
415 | return [r for r in subset if r in hs] | |||
|
416 | ||||
|
417 | def heads(repo, subset, x): | |||
|
418 | """``heads(set)`` | |||
|
419 | Members of set with no children in set. | |||
|
420 | """ | |||
|
421 | s = getset(repo, subset, x) | |||
|
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) | |||
|
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 | ||||
177 | def node(repo, subset, x): |
|
493 | def node(repo, subset, x): | |
178 | """``id(string)`` |
|
494 | """``id(string)`` | |
179 | Revision non-ambiguously specified by the given hex string prefix. |
|
495 | Revision non-ambiguously specified by the given hex string prefix. | |
@@ -188,19 +504,28 b' def node(repo, subset, x):' | |||||
188 | rn = repo.changelog.rev(repo.changelog._partialmatch(n)) |
|
504 | rn = repo.changelog.rev(repo.changelog._partialmatch(n)) | |
189 | return [r for r in subset if r == rn] |
|
505 | return [r for r in subset if r == rn] | |
190 |
|
506 | |||
191 |
def |
|
507 | def outgoing(repo, subset, x): | |
192 | """``rev(number)`` |
|
508 | """``outgoing([path])`` | |
193 | Revision with the given numeric identifier. |
|
509 | Changesets not found in the specified destination repository, or the | |
|
510 | default push location. | |||
194 | """ |
|
511 | """ | |
195 | # i18n: "rev" is a keyword |
|
512 | import hg # avoid start-up nasties | |
196 | l = getargs(x, 1, 1, _("rev requires one argument")) |
|
513 | # i18n: "outgoing" is a keyword | |
197 | try: |
|
514 | l = getargs(x, 0, 1, _("outgoing requires a repository path")) | |
198 |
|
|
515 | # i18n: "outgoing" is a keyword | |
199 |
|
|
516 | dest = l and getstring(l[0], _("outgoing requires a repository path")) or '' | |
200 | except ValueError: |
|
517 | dest = repo.ui.expandpath(dest or 'default-push', dest or 'default') | |
201 | # i18n: "rev" is a keyword |
|
518 | dest, branches = hg.parseurl(dest) | |
202 | raise error.ParseError(_("rev expects a number")) |
|
519 | revs, checkout = hg.addbranchrevs(repo, repo, branches, []) | |
203 | return [r for r in subset if r == l] |
|
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] | |||
204 |
|
529 | |||
205 | def p1(repo, subset, x): |
|
530 | def p1(repo, subset, x): | |
206 | """``p1([set])`` |
|
531 | """``p1([set])`` | |
@@ -248,254 +573,15 b' def parents(repo, subset, x):' | |||||
248 | ps.update(cl.parentrevs(r)) |
|
573 | ps.update(cl.parentrevs(r)) | |
249 | return [r for r in subset if r in ps] |
|
574 | return [r for r in subset if r in ps] | |
250 |
|
575 | |||
251 |
def |
|
576 | def present(repo, subset, x): | |
252 |
"""`` |
|
577 | """``present(set)`` | |
253 | Changeset with highest revision number in set. |
|
578 | An empty set, if any revision in set isn't found; otherwise, | |
254 | """ |
|
579 | all revisions in set. | |
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 | """ |
|
580 | """ | |
305 | try: |
|
581 | try: | |
306 | b = getstring(x, '') |
|
582 | return getset(repo, subset, x) | |
307 | if b in repo.branchmap(): |
|
583 | except error.RepoLookupError: | |
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 |
|
||||
320 | def ancestor(repo, subset, x): |
|
|||
321 | """``ancestor(single, single)`` |
|
|||
322 | Greatest common ancestor of the two changesets. |
|
|||
323 | """ |
|
|||
324 | # i18n: "ancestor" is a keyword |
|
|||
325 | l = getargs(x, 2, 2, _("ancestor requires two arguments")) |
|
|||
326 | r = range(len(repo)) |
|
|||
327 | a = getset(repo, r, l[0]) |
|
|||
328 | b = getset(repo, r, l[1]) |
|
|||
329 | if len(a) != 1 or len(b) != 1: |
|
|||
330 | # i18n: "ancestor" is a keyword |
|
|||
331 | raise error.ParseError(_("ancestor arguments must be single revisions")) |
|
|||
332 | an = [repo[a[0]].ancestor(repo[b[0]]).rev()] |
|
|||
333 |
|
||||
334 | return [r for r in an if r in subset] |
|
|||
335 |
|
||||
336 | def ancestors(repo, subset, x): |
|
|||
337 | """``ancestors(set)`` |
|
|||
338 | Changesets that are ancestors of a changeset in set. |
|
|||
339 | """ |
|
|||
340 | args = getset(repo, range(len(repo)), x) |
|
|||
341 | if not args: |
|
|||
342 | return [] |
|
|||
343 | s = set(repo.changelog.ancestors(*args)) | set(args) |
|
|||
344 | return [r for r in subset if r in s] |
|
|||
345 |
|
||||
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 [] |
|
584 | 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): |
|
|||
410 | """``author(string)`` |
|
|||
411 | Alias for ``user(string)``. |
|
|||
412 | """ |
|
|||
413 | # i18n: "author" is a keyword |
|
|||
414 | n = getstring(x, _("author requires a string")).lower() |
|
|||
415 | return [r for r in subset if n in repo[r].user().lower()] |
|
|||
416 |
|
||||
417 | def user(repo, subset, x): |
|
|||
418 | """``user(string)`` |
|
|||
419 | User name is string. |
|
|||
420 | """ |
|
|||
421 | return author(repo, subset, x) |
|
|||
422 |
|
||||
423 | def hasfile(repo, subset, x): |
|
|||
424 | """``file(pattern)`` |
|
|||
425 | Changesets affecting files matched by pattern. |
|
|||
426 | """ |
|
|||
427 | # i18n: "file" is a keyword |
|
|||
428 | pat = getstring(x, _("file requires a pattern")) |
|
|||
429 | m = matchmod.match(repo.root, repo.getcwd(), [pat]) |
|
|||
430 | s = [] |
|
|||
431 | for r in subset: |
|
|||
432 | for f in repo[r].files(): |
|
|||
433 | if m(f): |
|
|||
434 | s.append(r) |
|
|||
435 | break |
|
|||
436 | return s |
|
|||
437 |
|
||||
438 | def contains(repo, subset, x): |
|
|||
439 | """``contains(pattern)`` |
|
|||
440 | Revision contains pattern. |
|
|||
441 | """ |
|
|||
442 | # i18n: "contains" is a keyword |
|
|||
443 | pat = getstring(x, _("contains requires a pattern")) |
|
|||
444 | m = matchmod.match(repo.root, repo.getcwd(), [pat]) |
|
|||
445 | s = [] |
|
|||
446 | if m.files() == [pat]: |
|
|||
447 | for r in subset: |
|
|||
448 | if pat in repo[r]: |
|
|||
449 | s.append(r) |
|
|||
450 | else: |
|
|||
451 | for r in subset: |
|
|||
452 | for f in repo[r].manifest(): |
|
|||
453 | if m(f): |
|
|||
454 | s.append(r) |
|
|||
455 | break |
|
|||
456 | return s |
|
|||
457 |
|
||||
458 | def checkstatus(repo, subset, pat, field): |
|
|||
459 | m = matchmod.match(repo.root, repo.getcwd(), [pat]) |
|
|||
460 | s = [] |
|
|||
461 | fast = (m.files() == [pat]) |
|
|||
462 | for r in subset: |
|
|||
463 | c = repo[r] |
|
|||
464 | if fast: |
|
|||
465 | if pat not in c.files(): |
|
|||
466 | continue |
|
|||
467 | else: |
|
|||
468 | for f in c.files(): |
|
|||
469 | if m(f): |
|
|||
470 | break |
|
|||
471 | else: |
|
|||
472 | continue |
|
|||
473 | files = repo.status(c.p1().node(), c.node())[field] |
|
|||
474 | if fast: |
|
|||
475 | if pat in files: |
|
|||
476 | s.append(r) |
|
|||
477 | else: |
|
|||
478 | for f in files: |
|
|||
479 | if m(f): |
|
|||
480 | s.append(r) |
|
|||
481 | break |
|
|||
482 | return s |
|
|||
483 |
|
||||
484 | def modifies(repo, subset, x): |
|
|||
485 | """``modifies(pattern)`` |
|
|||
486 | Changesets modifying files matched by pattern. |
|
|||
487 | """ |
|
|||
488 | # i18n: "modifies" is a keyword |
|
|||
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 |
|
585 | |||
500 | def removes(repo, subset, x): |
|
586 | def removes(repo, subset, x): | |
501 | """``removes(pattern)`` |
|
587 | """``removes(pattern)`` | |
@@ -505,33 +591,19 b' def removes(repo, subset, x):' | |||||
505 | pat = getstring(x, _("removes requires a pattern")) |
|
591 | pat = getstring(x, _("removes requires a pattern")) | |
506 | return checkstatus(repo, subset, pat, 2) |
|
592 | return checkstatus(repo, subset, pat, 2) | |
507 |
|
593 | |||
508 |
def |
|
594 | def rev(repo, subset, x): | |
509 |
"""`` |
|
595 | """``rev(number)`` | |
510 | Changeset is a merge changeset. |
|
596 | Revision with the given numeric identifier. | |
511 | """ |
|
|||
512 | # i18n: "merge" is a keyword |
|
|||
513 | getargs(x, 0, 0, _("merge takes no arguments")) |
|
|||
514 | cl = repo.changelog |
|
|||
515 | return [r for r in subset if cl.parentrevs(r)[1] != -1] |
|
|||
516 |
|
||||
517 | def closed(repo, subset, x): |
|
|||
518 | """``closed()`` |
|
|||
519 | Changeset is closed. |
|
|||
520 | """ |
|
597 | """ | |
521 |
# i18n: " |
|
598 | # i18n: "rev" is a keyword | |
522 |
getargs(x, |
|
599 | l = getargs(x, 1, 1, _("rev requires one argument")) | |
523 | return [r for r in subset if repo[r].extra().get('close')] |
|
600 | try: | |
524 |
|
601 | # i18n: "rev" is a keyword | ||
525 | def head(repo, subset, x): |
|
602 | l = int(getstring(l[0], _("rev requires a number"))) | |
526 | """``head()`` |
|
603 | except ValueError: | |
527 | Changeset is a named branch head. |
|
604 | # i18n: "rev" is a keyword | |
528 | """ |
|
605 | raise error.ParseError(_("rev expects a number")) | |
529 | # i18n: "head" is a keyword |
|
606 | return [r for r in subset if r == l] | |
530 | getargs(x, 0, 0, _("head takes no arguments")) |
|
|||
531 | hs = set() |
|
|||
532 | for b, ls in repo.branchmap().iteritems(): |
|
|||
533 | hs.update(repo[h].rev() for h in ls) |
|
|||
534 | return [r for r in subset if r in hs] |
|
|||
535 |
|
607 | |||
536 | def reverse(repo, subset, x): |
|
608 | def reverse(repo, subset, x): | |
537 | """``reverse(set)`` |
|
609 | """``reverse(set)`` | |
@@ -541,15 +613,13 b' def reverse(repo, subset, x):' | |||||
541 | l.reverse() |
|
613 | l.reverse() | |
542 | return l |
|
614 | return l | |
543 |
|
615 | |||
544 |
def |
|
616 | def roots(repo, subset, x): | |
545 |
"""`` |
|
617 | """``roots(set)`` | |
546 | An empty set, if any revision in set isn't found; otherwise, |
|
618 | Changesets with no parent changeset in set. | |
547 | all revisions in set. |
|
|||
548 | """ |
|
619 | """ | |
549 | try: |
|
620 | s = getset(repo, subset, x) | |
550 |
|
|
621 | cs = set(children(repo, subset, x)) | |
551 | except error.RepoLookupError: |
|
622 | return [r for r in s if r not in cs] | |
552 | return [] |
|
|||
553 |
|
623 | |||
554 | def sort(repo, subset, x): |
|
624 | def sort(repo, subset, x): | |
555 | """``sort(set[, [-]key...])`` |
|
625 | """``sort(set[, [-]key...])`` | |
@@ -606,53 +676,6 b' def sort(repo, subset, x):' | |||||
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. | |
@@ -674,34 +697,11 b' def tag(repo, subset, x):' | |||||
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 |
|
700 | def user(repo, subset, x): | |
678 |
"""`` |
|
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, |
General Comments 0
You need to be logged in to leave comments.
Login now