comparison hglib/client.py @ 123:cdde1656346f

client: add 'hidden' property to show hidden changesets. This enables interactions with the obsolete changesets in the repository: - add the attribute in client class - add the keyword to the relevant commands - enable log without hidden changesets even when self.hidden is True - add a few tests with the hidden keyword This changeset mirrors the behavior of the mercurial global command --hidden: an attribute is added to the client library. If set at True, adds the hidden keyword to all command which can use it to show hidden changesets. The alternative would be to add the keyword in rawcommand, but the hidden flag is not relevant for commands such as add or branch.
author Paul Tonelli <paul.tonelli@logilab.fr>
date Thu, 22 May 2014 15:23:12 +0200
parents e05b0cf920bb
children 8d9a9da3e7b4
comparison
equal deleted inserted replaced
122:e05b0cf920bb 123:cdde1656346f
52 if encoding: 52 if encoding:
53 self._env['HGENCODING'] = encoding 53 self._env['HGENCODING'] = encoding
54 54
55 self.server = None 55 self.server = None
56 self._version = None 56 self._version = None
57 #include the hidden changesets if True
58 self.hidden = None
57 59
58 if connect: 60 if connect:
59 self.open() 61 self.open()
60 62
61 def __enter__(self): 63 def __enter__(self):
280 if not isinstance(files, list): 282 if not isinstance(files, list):
281 files = [files] 283 files = [files]
282 284
283 args = cmdbuilder('annotate', r=rev, no_follow=nofollow, a=text, 285 args = cmdbuilder('annotate', r=rev, no_follow=nofollow, a=text,
284 u=user, f=file, d=date, n=number, c=changeset, 286 u=user, f=file, d=date, n=number, c=changeset,
285 l=line, v=verbose, I=include, X=exclude, *files) 287 l=line, v=verbose, I=include, X=exclude,
288 hidden=self.hidden, *files)
286 289
287 out = self.rawcommand(args) 290 out = self.rawcommand(args)
288 291
289 for line in out.splitlines(): 292 for line in out.splitlines():
290 yield tuple(line.split(': ', 1)) 293 yield tuple(line.split(': ', 1))
322 subrepos - recurse into subrepositories 325 subrepos - recurse into subrepositories
323 include - include names matching the given patterns 326 include - include names matching the given patterns
324 exclude - exclude names matching the given patterns 327 exclude - exclude names matching the given patterns
325 """ 328 """
326 args = cmdbuilder('archive', dest, r=rev, no_decode=nodecode, p=prefix, 329 args = cmdbuilder('archive', dest, r=rev, no_decode=nodecode, p=prefix,
327 t=type, S=subrepos, I=include, X=exclude) 330 t=type, S=subrepos, I=include, X=exclude,
331 hidden=self.hidden)
328 332
329 self.rawcommand(args) 333 self.rawcommand(args)
330 334
331 def backout(self, rev, merge=False, parent=None, tool=None, message=None, 335 def backout(self, rev, merge=False, parent=None, tool=None, message=None,
332 logfile=None, date=None, user=None): 336 logfile=None, date=None, user=None):
349 """ 353 """
350 if message and logfile: 354 if message and logfile:
351 raise ValueError("cannot specify both a message and a logfile") 355 raise ValueError("cannot specify both a message and a logfile")
352 356
353 args = cmdbuilder('backout', r=rev, merge=merge, parent=parent, t=tool, 357 args = cmdbuilder('backout', r=rev, merge=merge, parent=parent, t=tool,
354 m=message, l=logfile, d=date, u=user) 358 m=message, l=logfile, d=date, u=user,
359 hidden=self.hidden)
355 360
356 self.rawcommand(args) 361 self.rawcommand(args)
357 362
358 def bookmark(self, name, rev=None, force=False, delete=False, inactive=False, 363 def bookmark(self, name, rev=None, force=False, delete=False, inactive=False,
359 rename=None): 364 rename=None):
378 Return the bookmarks as a list of (name, rev, node) and the index of the 383 Return the bookmarks as a list of (name, rev, node) and the index of the
379 current one. 384 current one.
380 385
381 If there isn't a current one, -1 is returned as the index. 386 If there isn't a current one, -1 is returned as the index.
382 """ 387 """
383 out = self.rawcommand(['bookmarks']) 388 args = cmdbuilder('bookmarks', hidden=self.hidden)
389 out = self.rawcommand(args)
384 390
385 bms = [] 391 bms = []
386 current = -1 392 current = -1
387 if out.rstrip() != 'no bookmarks set': 393 if out.rstrip() != 'no bookmarks set':
388 for line in out.splitlines(): 394 for line in out.splitlines():
427 Returns the repository's named branches as a list of (name, rev, node). 433 Returns the repository's named branches as a list of (name, rev, node).
428 434
429 active - show only branches that have unmerged heads 435 active - show only branches that have unmerged heads
430 closed - show normal and closed branches 436 closed - show normal and closed branches
431 """ 437 """
432 args = cmdbuilder('branches', a=active, c=closed) 438 args = cmdbuilder('branches', a=active, c=closed, hidden=self.hidden)
433 out = self.rawcommand(args) 439 out = self.rawcommand(args)
434 440
435 branches = [] 441 branches = []
436 for line in out.rstrip().splitlines(): 442 for line in out.rstrip().splitlines():
437 namerev, node = line.rsplit(':', 1) 443 namerev, node = line.rsplit(':', 1)
467 473
468 Return True if a bundle was created, False if no changes were found. 474 Return True if a bundle was created, False if no changes were found.
469 """ 475 """
470 args = cmdbuilder('bundle', file, destrepo, f=force, r=rev, b=branch, 476 args = cmdbuilder('bundle', file, destrepo, f=force, r=rev, b=branch,
471 base=base, a=all, t=type, e=ssh, remotecmd=remotecmd, 477 base=base, a=all, t=type, e=ssh, remotecmd=remotecmd,
472 insecure=insecure) 478 insecure=insecure, hidden=self.hidden)
473 479
474 eh = util.reterrorhandler(args) 480 eh = util.reterrorhandler(args)
475 self.rawcommand(args, eh=eh) 481 self.rawcommand(args, eh=eh)
476 482
477 return bool(eh) 483 return bool(eh)
488 494
489 "%s" basename of file being printed 495 "%s" basename of file being printed
490 "%d" dirname of file being printed, or '.' if in repository root 496 "%d" dirname of file being printed, or '.' if in repository root
491 "%p" root-relative path name of file being printed 497 "%p" root-relative path name of file being printed
492 """ 498 """
493 args = cmdbuilder('cat', r=rev, o=output, *files) 499 args = cmdbuilder('cat', r=rev, o=output, hidden=self.hidden, *files)
494 out = self.rawcommand(args) 500 out = self.rawcommand(args)
495 501
496 if not output: 502 if not output:
497 return out 503 return out
498 504
641 args = cmdbuilder('diff', r=revs, c=change, 647 args = cmdbuilder('diff', r=revs, c=change,
642 a=text, g=git, nodates=nodates, 648 a=text, g=git, nodates=nodates,
643 p=showfunction, reverse=reverse, 649 p=showfunction, reverse=reverse,
644 w=ignoreallspace, b=ignorespacechange, 650 w=ignoreallspace, b=ignorespacechange,
645 B=ignoreblanklines, U=unified, stat=stat, 651 B=ignoreblanklines, U=unified, stat=stat,
646 S=subrepos, I=include, X=exclude, *files) 652 S=subrepos, I=include, X=exclude, hidden=self.hidden,
653 *files)
647 654
648 return self.rawcommand(args) 655 return self.rawcommand(args)
649 656
650 def export(self, revs, output=None, switchparent=False, text=False, git=False, 657 def export(self, revs, output=None, switchparent=False, text=False, git=False,
651 nodates=False): 658 nodates=False):
671 nodates - omit dates from diff headers 678 nodates - omit dates from diff headers
672 """ 679 """
673 if not isinstance(revs, list): 680 if not isinstance(revs, list):
674 revs = [revs] 681 revs = [revs]
675 args = cmdbuilder('export', o=output, switch_parent=switchparent, 682 args = cmdbuilder('export', o=output, switch_parent=switchparent,
676 a=text, g=git, nodates=nodates, *revs) 683 a=text, g=git, nodates=nodates, hidden=self.hidden,
684 *revs)
677 685
678 out = self.rawcommand(args) 686 out = self.rawcommand(args)
679 687
680 if output is None: 688 if output is None:
681 return out 689 return out
730 if not isinstance(files, list): 738 if not isinstance(files, list):
731 files = [files] 739 files = [files]
732 740
733 args = cmdbuilder('grep', all=all, a=text, f=follow, i=ignorecase, 741 args = cmdbuilder('grep', all=all, a=text, f=follow, i=ignorecase,
734 l=fileswithmatches, n=line, u=user, d=date, 742 l=fileswithmatches, n=line, u=user, d=date,
735 I=include, X=exclude, *[pattern] + files) 743 I=include, X=exclude, hidden=self.hidden,
744 *[pattern] + files)
736 args.append('-0') 745 args.append('-0')
737 746
738 def eh(ret, out, err): 747 def eh(ret, out, err):
739 if ret != 1: 748 if ret != 1:
740 raise error.CommandError(args, ret, out, err) 749 raise error.CommandError(args, ret, out, err)
771 """ 780 """
772 if not isinstance(rev, list): 781 if not isinstance(rev, list):
773 rev = [rev] 782 rev = [rev]
774 783
775 args = cmdbuilder('heads', r=startrev, t=topological, c=closed, 784 args = cmdbuilder('heads', r=startrev, t=topological, c=closed,
776 template=templates.changeset, *rev) 785 template=templates.changeset, hidden=self.hidden,
786 *rev)
777 787
778 def eh(ret, out, err): 788 def eh(ret, out, err):
779 if ret != 1: 789 if ret != 1:
780 raise error.CommandError(args, ret, out, err) 790 raise error.CommandError(args, ret, out, err)
781 return '' 791 return ''
802 branch - show branch 812 branch - show branch
803 tags - show tags 813 tags - show tags
804 bookmarks - show bookmarks 814 bookmarks - show bookmarks
805 """ 815 """
806 args = cmdbuilder('identify', source, r=rev, n=num, i=id, b=branch, t=tags, 816 args = cmdbuilder('identify', source, r=rev, n=num, i=id, b=branch, t=tags,
807 B=bookmarks) 817 B=bookmarks, hidden=self.hidden)
808 818
809 return self.rawcommand(args) 819 return self.rawcommand(args)
810 820
811 def import_(self, patches, strip=None, force=False, nocommit=False, 821 def import_(self, patches, strip=None, force=False, nocommit=False,
812 bypass=False, exact=False, importbranch=False, message=None, 822 bypass=False, exact=False, importbranch=False, message=None,
900 out = out.split('\0')[:-1] 910 out = out.split('\0')[:-1]
901 return self._parserevs(out) 911 return self._parserevs(out)
902 912
903 def log(self, revrange=None, files=[], follow=False, followfirst=False, 913 def log(self, revrange=None, files=[], follow=False, followfirst=False,
904 date=None, copies=False, keyword=None, removed=False, onlymerges=False, 914 date=None, copies=False, keyword=None, removed=False, onlymerges=False,
905 user=None, branch=None, prune=None, hidden=False, limit=None, 915 user=None, branch=None, prune=None, hidden=None, limit=None,
906 nomerges=False, include=None, exclude=None): 916 nomerges=False, include=None, exclude=None):
907 """ 917 """
908 Return the revision history of the specified files or the entire project. 918 Return the revision history of the specified files or the entire project.
909 919
910 File history is shown without following rename or copy history of files. 920 File history is shown without following rename or copy history of files.
939 limit - limit number of changes displayed 949 limit - limit number of changes displayed
940 nomerges - do not show merges 950 nomerges - do not show merges
941 include - include names matching the given patterns 951 include - include names matching the given patterns
942 exclude - exclude names matching the given patterns 952 exclude - exclude names matching the given patterns
943 """ 953 """
954 if hidden is None:
955 hidden = self.hidden
944 args = cmdbuilder('log', template=templates.changeset, 956 args = cmdbuilder('log', template=templates.changeset,
945 r=revrange, f=follow, follow_first=followfirst, 957 r=revrange, f=follow, follow_first=followfirst,
946 d=date, C=copies, k=keyword, removed=removed, 958 d=date, C=copies, k=keyword, removed=removed,
947 m=onlymerges, u=user, b=branch, P=prune, hidden=hidden, 959 m=onlymerges, u=user, b=branch, P=prune,
948 l=limit, M=nomerges, I=include, X=exclude, *files) 960 l=limit, M=nomerges, I=include, X=exclude,
961 hidden=hidden, *files)
949 962
950 out = self.rawcommand(args) 963 out = self.rawcommand(args)
951 out = out.split('\0')[:-1] 964 out = out.split('\0')[:-1]
952 965
953 return self._parserevs(out) 966 return self._parserevs(out)
960 no revision is checked out. 973 no revision is checked out.
961 974
962 When all is True, all files from all revisions are yielded (just the name). 975 When all is True, all files from all revisions are yielded (just the name).
963 This includes deleted and renamed files. 976 This includes deleted and renamed files.
964 """ 977 """
965 args = cmdbuilder('manifest', r=rev, all=all, debug=True) 978 args = cmdbuilder('manifest', r=rev, all=all, debug=True,
979 hidden=self.hidden)
966 980
967 out = self.rawcommand(args) 981 out = self.rawcommand(args)
968 982
969 if all: 983 if all:
970 for line in out.splitlines(): 984 for line in out.splitlines():
1092 Return the working directory's parent revisions. If rev is given, the 1106 Return the working directory's parent revisions. If rev is given, the
1093 parent of that revision will be printed. If file is given, the revision 1107 parent of that revision will be printed. If file is given, the revision
1094 in which the file was last changed (before the working directory revision 1108 in which the file was last changed (before the working directory revision
1095 or the revision specified by rev) is returned. 1109 or the revision specified by rev) is returned.
1096 """ 1110 """
1097 args = cmdbuilder('parents', file, template=templates.changeset, r=rev) 1111 args = cmdbuilder('parents', file, template=templates.changeset, r=rev,
1112 hidden=self.hidden)
1098 1113
1099 out = self.rawcommand(args) 1114 out = self.rawcommand(args)
1100 if not out: 1115 if not out:
1101 return 1116 return
1102 1117
1275 if not isinstance(files, list): 1290 if not isinstance(files, list):
1276 files = [files] 1291 files = [files]
1277 1292
1278 args = cmdbuilder('revert', r=rev, a=all, d=date, 1293 args = cmdbuilder('revert', r=rev, a=all, d=date,
1279 no_backup=nobackup, n=dryrun, I=include, X=exclude, 1294 no_backup=nobackup, n=dryrun, I=include, X=exclude,
1280 *files) 1295 hidden=self.hidden, *files)
1281 1296
1282 eh = util.reterrorhandler(args) 1297 eh = util.reterrorhandler(args)
1283 self.rawcommand(args, eh=eh) 1298 self.rawcommand(args, eh=eh)
1284 1299
1285 return bool(eh) 1300 return bool(eh)
1325 if rev and change: 1340 if rev and change:
1326 raise ValueError('cannot specify both rev and change') 1341 raise ValueError('cannot specify both rev and change')
1327 1342
1328 args = cmdbuilder('status', rev=rev, change=change, A=all, m=modified, 1343 args = cmdbuilder('status', rev=rev, change=change, A=all, m=modified,
1329 a=added, r=removed, d=deleted, c=clean, u=unknown, 1344 a=added, r=removed, d=deleted, c=clean, u=unknown,
1330 i=ignored, C=copies, S=subrepos, I=include, X=exclude) 1345 i=ignored, C=copies, S=subrepos, I=include,
1346 X=exclude, hidden=self.hidden)
1331 1347
1332 args.append('-0') 1348 args.append('-0')
1333 1349
1334 out = self.rawcommand(args) 1350 out = self.rawcommand(args)
1335 l = [] 1351 l = []
1364 """ 1380 """
1365 if not isinstance(names, list): 1381 if not isinstance(names, list):
1366 names = [names] 1382 names = [names]
1367 1383
1368 args = cmdbuilder('tag', r=rev, m=message, f=force, l=local, 1384 args = cmdbuilder('tag', r=rev, m=message, f=force, l=local,
1369 remove=remove, d=date, u=user, *names) 1385 remove=remove, d=date, u=user, hidden=self.hidden,
1386 *names)
1370 1387
1371 self.rawcommand(args) 1388 self.rawcommand(args)
1372 1389
1373 def tags(self): 1390 def tags(self):
1374 """ 1391 """
1400 ['remote' : (in, in bookmarks, out, out bookmarks),] 1417 ['remote' : (in, in bookmarks, out, out bookmarks),]
1401 ['mq': (applied, unapplied) mq patches,] 1418 ['mq': (applied, unapplied) mq patches,]
1402 1419
1403 unparsed entries will be of them form key : value 1420 unparsed entries will be of them form key : value
1404 """ 1421 """
1405 args = cmdbuilder('summary', remote=remote) 1422 args = cmdbuilder('summary', remote=remote, hidden=self.hidden)
1406 1423
1407 out = self.rawcommand(args).splitlines() 1424 out = self.rawcommand(args).splitlines()
1408 1425
1409 d = {} 1426 d = {}
1410 while out: 1427 while out:
1472 """ 1489 """
1473 Return the tip revision (usually just called the tip) which is the 1490 Return the tip revision (usually just called the tip) which is the
1474 changeset most recently added to the repository (and therefore the most 1491 changeset most recently added to the repository (and therefore the most
1475 recently changed head). 1492 recently changed head).
1476 """ 1493 """
1477 args = cmdbuilder('tip', template=templates.changeset) 1494 args = cmdbuilder('tip', template=templates.changeset,
1495 hidden=self.hidden)
1478 out = self.rawcommand(args) 1496 out = self.rawcommand(args)
1479 out = out.split('\0') 1497 out = out.split('\0')
1480 1498
1481 return self._parserevs(out)[0] 1499 return self._parserevs(out)[0]
1482 1500
1492 date - tipmost revision matching date 1510 date - tipmost revision matching date
1493 """ 1511 """
1494 if clean and check: 1512 if clean and check:
1495 raise ValueError('clean and check cannot both be True') 1513 raise ValueError('clean and check cannot both be True')
1496 1514
1497 args = cmdbuilder('update', r=rev, C=clean, c=check, d=date) 1515 args = cmdbuilder('update', r=rev, C=clean, c=check, d=date,
1516 hidden=self.hidden)
1498 1517
1499 def eh(ret, out, err): 1518 def eh(ret, out, err):
1500 if ret == 1: 1519 if ret == 1:
1501 return out 1520 return out
1502 1521