Show More
@@ -73,7 +73,7 b' table = {}' | |||
|
73 | 73 | table.update(debugcommandsmod.command._table) |
|
74 | 74 | |
|
75 | 75 | command = registrar.command(table) |
|
76 | readonly = registrar.command.readonly | |
|
76 | INTENT_READONLY = registrar.INTENT_READONLY | |
|
77 | 77 | |
|
78 | 78 | # common command options |
|
79 | 79 | |
@@ -1083,7 +1083,8 b' def branch(ui, repo, label=None, **opts)' | |||
|
1083 | 1083 | _('show only branches that have unmerged heads (DEPRECATED)')), |
|
1084 | 1084 | ('c', 'closed', False, _('show normal and closed branches')), |
|
1085 | 1085 | ] + formatteropts, |
|
1086 |
_('[-c]'), |
|
|
1086 | _('[-c]'), | |
|
1087 | intents={INTENT_READONLY}) | |
|
1087 | 1088 | def branches(ui, repo, active=False, closed=False, **opts): |
|
1088 | 1089 | """list repository named branches |
|
1089 | 1090 | |
@@ -1282,7 +1283,8 b' def bundle(ui, repo, fname, dest=None, *' | |||
|
1282 | 1283 | ('', 'decode', None, _('apply any matching decode filter')), |
|
1283 | 1284 | ] + walkopts + formatteropts, |
|
1284 | 1285 | _('[OPTION]... FILE...'), |
|
1285 |
inferrepo=True, |
|
|
1286 | inferrepo=True, | |
|
1287 | intents={INTENT_READONLY}) | |
|
1286 | 1288 | def cat(ui, repo, file1, *pats, **opts): |
|
1287 | 1289 | """output the current or given revision of files |
|
1288 | 1290 | |
@@ -1633,7 +1635,8 b' def _docommit(ui, repo, *pats, **opts):' | |||
|
1633 | 1635 | ('l', 'local', None, _('edit repository config')), |
|
1634 | 1636 | ('g', 'global', None, _('edit global config'))] + formatteropts, |
|
1635 | 1637 | _('[-u] [NAME]...'), |
|
1636 |
optionalrepo=True, |
|
|
1638 | optionalrepo=True, | |
|
1639 | intents={INTENT_READONLY}) | |
|
1637 | 1640 | def config(ui, repo, *values, **opts): |
|
1638 | 1641 | """show combined config settings from all hgrc files |
|
1639 | 1642 | |
@@ -1802,7 +1805,8 b" def debugcomplete(ui, cmd='', **opts):" | |||
|
1802 | 1805 | ('c', 'change', '', _('change made by revision'), _('REV')) |
|
1803 | 1806 | ] + diffopts + diffopts2 + walkopts + subrepoopts, |
|
1804 | 1807 | _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'), |
|
1805 |
inferrepo=True, |
|
|
1808 | inferrepo=True, | |
|
1809 | intents={INTENT_READONLY}) | |
|
1806 | 1810 | def diff(ui, repo, *pats, **opts): |
|
1807 | 1811 | """diff repository (or selected files) |
|
1808 | 1812 | |
@@ -1895,7 +1899,8 b' def diff(ui, repo, *pats, **opts):' | |||
|
1895 | 1899 | ('', 'switch-parent', None, _('diff against the second parent')), |
|
1896 | 1900 | ('r', 'rev', [], _('revisions to export'), _('REV')), |
|
1897 | 1901 | ] + diffopts + formatteropts, |
|
1898 |
_('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'), |
|
|
1902 | _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'), | |
|
1903 | intents={INTENT_READONLY}) | |
|
1899 | 1904 | def export(ui, repo, *changesets, **opts): |
|
1900 | 1905 | """dump the header and diffs for one or more changesets |
|
1901 | 1906 | |
@@ -1990,7 +1995,8 b' def export(ui, repo, *changesets, **opts' | |||
|
1990 | 1995 | [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')), |
|
1991 | 1996 | ('0', 'print0', None, _('end filenames with NUL, for use with xargs')), |
|
1992 | 1997 | ] + walkopts + formatteropts + subrepoopts, |
|
1993 |
_('[OPTION]... [FILE]...'), |
|
|
1998 | _('[OPTION]... [FILE]...'), | |
|
1999 | intents={INTENT_READONLY}) | |
|
1994 | 2000 | def files(ui, repo, *pats, **opts): |
|
1995 | 2001 | """list tracked files |
|
1996 | 2002 | |
@@ -2371,7 +2377,8 b' def _dograft(ui, repo, *revs, **opts):' | |||
|
2371 | 2377 | ('d', 'date', None, _('list the date (short with -q)')), |
|
2372 | 2378 | ] + formatteropts + walkopts, |
|
2373 | 2379 | _('[OPTION]... PATTERN [FILE]...'), |
|
2374 |
inferrepo=True, |
|
|
2380 | inferrepo=True, | |
|
2381 | intents={INTENT_READONLY}) | |
|
2375 | 2382 | def grep(ui, repo, pattern, *pats, **opts): |
|
2376 | 2383 | """search revision history for a pattern in specified files |
|
2377 | 2384 | |
@@ -2617,7 +2624,8 b' def grep(ui, repo, pattern, *pats, **opt' | |||
|
2617 | 2624 | ('a', 'active', False, _('show active branchheads only (DEPRECATED)')), |
|
2618 | 2625 | ('c', 'closed', False, _('show normal and closed branch heads')), |
|
2619 | 2626 | ] + templateopts, |
|
2620 |
_('[-ct] [-r STARTREV] [REV]...'), |
|
|
2627 | _('[-ct] [-r STARTREV] [REV]...'), | |
|
2628 | intents={INTENT_READONLY}) | |
|
2621 | 2629 | def heads(ui, repo, *branchrevs, **opts): |
|
2622 | 2630 | """show branch heads |
|
2623 | 2631 | |
@@ -2693,7 +2701,8 b' def heads(ui, repo, *branchrevs, **opts)' | |||
|
2693 | 2701 | ('s', 'system', [], _('show help for specific platform(s)')), |
|
2694 | 2702 | ], |
|
2695 | 2703 | _('[-ecks] [TOPIC]'), |
|
2696 |
norepo=True, |
|
|
2704 | norepo=True, | |
|
2705 | intents={INTENT_READONLY}) | |
|
2697 | 2706 | def help_(ui, name=None, **opts): |
|
2698 | 2707 | """show help for a given topic or a help overview |
|
2699 | 2708 | |
@@ -2735,7 +2744,8 b' def help_(ui, name=None, **opts):' | |||
|
2735 | 2744 | ('B', 'bookmarks', None, _('show bookmarks')), |
|
2736 | 2745 | ] + remoteopts + formatteropts, |
|
2737 | 2746 | _('[-nibtB] [-r REV] [SOURCE]'), |
|
2738 |
optionalrepo=True, |
|
|
2747 | optionalrepo=True, | |
|
2748 | intents={INTENT_READONLY}) | |
|
2739 | 2749 | def identify(ui, repo, source=None, rev=None, |
|
2740 | 2750 | num=None, id=None, branch=None, tags=None, bookmarks=None, **opts): |
|
2741 | 2751 | """identify the working directory or specified revision |
@@ -3312,7 +3322,8 b' def locate(ui, repo, *pats, **opts):' | |||
|
3312 | 3322 | _('do not display revision or any of its ancestors'), _('REV')), |
|
3313 | 3323 | ] + logopts + walkopts, |
|
3314 | 3324 | _('[OPTION]... [FILE]'), |
|
3315 |
inferrepo=True, |
|
|
3325 | inferrepo=True, | |
|
3326 | intents={INTENT_READONLY}) | |
|
3316 | 3327 | def log(ui, repo, *pats, **opts): |
|
3317 | 3328 | """show revision history of entire repository or files |
|
3318 | 3329 | |
@@ -3480,7 +3491,8 b' def log(ui, repo, *pats, **opts):' | |||
|
3480 | 3491 | [('r', 'rev', '', _('revision to display'), _('REV')), |
|
3481 | 3492 | ('', 'all', False, _("list files from all revisions"))] |
|
3482 | 3493 | + formatteropts, |
|
3483 |
_('[-r REV]'), |
|
|
3494 | _('[-r REV]'), | |
|
3495 | intents={INTENT_READONLY}) | |
|
3484 | 3496 | def manifest(ui, repo, node=None, rev=None, **opts): |
|
3485 | 3497 | """output the current or given revision of the project manifest |
|
3486 | 3498 | |
@@ -3758,7 +3770,7 b' def parents(ui, repo, file_=None, **opts' | |||
|
3758 | 3770 | displayer.close() |
|
3759 | 3771 | |
|
3760 | 3772 | @command('paths', formatteropts, _('[NAME]'), optionalrepo=True, |
|
3761 | cmdtype=readonly) | |
|
3773 | intents={INTENT_READONLY}) | |
|
3762 | 3774 | def paths(ui, repo, search=None, **opts): |
|
3763 | 3775 | """show aliases for remote repositories |
|
3764 | 3776 | |
@@ -4696,7 +4708,7 b' def rollback(ui, repo, **opts):' | |||
|
4696 | 4708 | return repo.rollback(dryrun=opts.get(r'dry_run'), |
|
4697 | 4709 | force=opts.get(r'force')) |
|
4698 | 4710 | |
|
4699 | @command('root', [], cmdtype=readonly) | |
|
4711 | @command('root', [], intents={INTENT_READONLY}) | |
|
4700 | 4712 | def root(ui, repo): |
|
4701 | 4713 | """print the root (top) of the current working directory |
|
4702 | 4714 | |
@@ -4790,7 +4802,8 b' def serve(ui, repo, **opts):' | |||
|
4790 | 4802 | ('', 'change', '', _('list the changed files of a revision'), _('REV')), |
|
4791 | 4803 | ] + walkopts + subrepoopts + formatteropts, |
|
4792 | 4804 | _('[OPTION]... [FILE]...'), |
|
4793 |
inferrepo=True, |
|
|
4805 | inferrepo=True, | |
|
4806 | intents={INTENT_READONLY}) | |
|
4794 | 4807 | def status(ui, repo, *pats, **opts): |
|
4795 | 4808 | """show changed files in the working directory |
|
4796 | 4809 | |
@@ -4958,7 +4971,8 b' def status(ui, repo, *pats, **opts):' | |||
|
4958 | 4971 | |
|
4959 | 4972 | @command('^summary|sum', |
|
4960 | 4973 | [('', 'remote', None, _('check for push and pull'))], |
|
4961 |
'[--remote]', |
|
|
4974 | '[--remote]', | |
|
4975 | intents={INTENT_READONLY}) | |
|
4962 | 4976 | def summary(ui, repo, **opts): |
|
4963 | 4977 | """summarize working directory state |
|
4964 | 4978 | |
@@ -5359,7 +5373,7 b' def tag(ui, repo, name1, *names, **opts)' | |||
|
5359 | 5373 | finally: |
|
5360 | 5374 | release(lock, wlock) |
|
5361 | 5375 | |
|
5362 |
@command('tags', formatteropts, '', |
|
|
5376 | @command('tags', formatteropts, '', intents={INTENT_READONLY}) | |
|
5363 | 5377 | def tags(ui, repo, **opts): |
|
5364 | 5378 | """list repository tags |
|
5365 | 5379 | |
@@ -5596,7 +5610,8 b' def verify(ui, repo):' | |||
|
5596 | 5610 | """ |
|
5597 | 5611 | return hg.verify(repo) |
|
5598 | 5612 | |
|
5599 |
@command('version', [] + formatteropts, norepo=True, |
|
|
5613 | @command('version', [] + formatteropts, norepo=True, | |
|
5614 | intents={INTENT_READONLY}) | |
|
5600 | 5615 | def version_(ui, **opts): |
|
5601 | 5616 | """output version and copyright information""" |
|
5602 | 5617 | opts = pycompat.byteskwargs(opts) |
@@ -35,7 +35,6 b' from . import (' | |||
|
35 | 35 | hook, |
|
36 | 36 | profiling, |
|
37 | 37 | pycompat, |
|
38 | registrar, | |
|
39 | 38 | scmutil, |
|
40 | 39 | ui as uimod, |
|
41 | 40 | util, |
@@ -46,8 +45,6 b' from .utils import (' | |||
|
46 | 45 | stringutil, |
|
47 | 46 | ) |
|
48 | 47 | |
|
49 | unrecoverablewrite = registrar.command.unrecoverablewrite | |
|
50 | ||
|
51 | 48 | class request(object): |
|
52 | 49 | def __init__(self, args, ui=None, repo=None, fin=None, fout=None, |
|
53 | 50 | ferr=None, prereposetups=None): |
@@ -562,7 +559,7 b' class cmdalias(object):' | |||
|
562 | 559 | return aliasargs(self.fn, args) |
|
563 | 560 | |
|
564 | 561 | def __getattr__(self, name): |
|
565 |
adefaults = {r'norepo': True, r' |
|
|
562 | adefaults = {r'norepo': True, r'intents': set(), | |
|
566 | 563 | r'optionalrepo': False, r'inferrepo': False} |
|
567 | 564 | if name not in adefaults: |
|
568 | 565 | raise AttributeError(name) |
@@ -138,15 +138,18 b' class command(_funcregistrarbase):' | |||
|
138 | 138 | potential repository locations. See ``findrepo()``. If a repository is |
|
139 | 139 | found, it will be used and passed to the decorated function. |
|
140 | 140 | |
|
141 | There are three constants in the class which tells what type of the command | |
|
142 | that is. That information will be helpful at various places. It will be also | |
|
143 | be used to decide what level of access the command has on hidden commits. | |
|
144 | The constants are: | |
|
141 | The `intents` argument defines a set of intended actions or capabilities | |
|
142 | the command is taking. These intents can be used to affect the construction | |
|
143 | of the repository object passed to the command. For example, commands | |
|
144 | declaring that they are read-only could receive a repository that doesn't | |
|
145 | have any methods allowing repository mutation. Other intents could be used | |
|
146 | to prevent the command from running if the requested intent could not be | |
|
147 | fulfilled. | |
|
145 | 148 | |
|
146 | `unrecoverablewrite` is for those write commands which can't be recovered | |
|
147 | like push. | |
|
148 | `recoverablewrite` is for write commands which can be recovered like commit. | |
|
149 | `readonly` is for commands which are read only. | |
|
149 | The following intents are defined: | |
|
150 | ||
|
151 | readonly | |
|
152 | The command is read-only | |
|
150 | 153 | |
|
151 | 154 | The signature of the decorated function looks like this: |
|
152 | 155 | def cmd(ui[, repo] [, <args>] [, <options>]) |
@@ -161,29 +164,22 b' class command(_funcregistrarbase):' | |||
|
161 | 164 | descriptions and examples. |
|
162 | 165 | """ |
|
163 | 166 | |
|
164 | unrecoverablewrite = "unrecoverable" | |
|
165 | recoverablewrite = "recoverable" | |
|
166 | readonly = "readonly" | |
|
167 | ||
|
168 | possiblecmdtypes = {unrecoverablewrite, recoverablewrite, readonly} | |
|
169 | ||
|
170 | 167 | def _doregister(self, func, name, options=(), synopsis=None, |
|
171 | 168 | norepo=False, optionalrepo=False, inferrepo=False, |
|
172 |
|
|
|
169 | intents=None): | |
|
173 | 170 | |
|
174 | if cmdtype not in self.possiblecmdtypes: | |
|
175 | raise error.ProgrammingError("unknown cmdtype value '%s' for " | |
|
176 | "'%s' command" % (cmdtype, name)) | |
|
177 | 171 | func.norepo = norepo |
|
178 | 172 | func.optionalrepo = optionalrepo |
|
179 | 173 | func.inferrepo = inferrepo |
|
180 | func.cmdtype = cmdtype | |
|
174 | func.intents = intents or set() | |
|
181 | 175 | if synopsis: |
|
182 | 176 | self._table[name] = func, list(options), synopsis |
|
183 | 177 | else: |
|
184 | 178 | self._table[name] = func, list(options) |
|
185 | 179 | return func |
|
186 | 180 | |
|
181 | INTENT_READONLY = b'readonly' | |
|
182 | ||
|
187 | 183 | class revsetpredicate(_funcregistrarbase): |
|
188 | 184 | """Decorator to register revset predicate |
|
189 | 185 |
@@ -192,7 +192,7 b' Test special hash/rev' | |||
|
192 | 192 | $ hg log -qr 'null:wdir() & 2147483647' |
|
193 | 193 | 2147483647:ffffffffffff |
|
194 | 194 | |
|
195 |
Commands with undefined |
|
|
195 | Commands with undefined intent should not work right now | |
|
196 | 196 | |
|
197 | 197 | $ hg phase -r 28ad74 |
|
198 | 198 | abort: hidden revision '28ad74' was rewritten as: 2443a0e66469! |
General Comments 0
You need to be logged in to leave comments.
Login now