# HG changeset patch # User Brendan Cully # Date 1183217483 25200 # Node ID 544a5e3d7d1c6afa90dc829f371bff380e2abd9b # Parent 778bab992732b7280a752e38ff0d2e661b99e140# Parent cc7a43af709d8ac5296439140bd7ab1932b3bf4e Merge with Adam Spiers diff --git a/contrib/win32/mercurial.ini b/contrib/win32/mercurial.ini --- a/contrib/win32/mercurial.ini +++ b/contrib/win32/mercurial.ini @@ -1,41 +1,41 @@ -; System-wide Mercurial config file. To override these settings on a -; per-user basis, please edit the following file instead, where -; USERNAME is your Windows user name: -; C:\Documents and Settings\USERNAME\Mercurial.ini - -[ui] -editor = notepad - -; By default, we try to encode and decode all files that do not -; contain ASCII NUL characters. What this means is that we try to set -; line endings to Windows style on update, and to Unix style on -; commit. This lets us cooperate with Linux and Unix users, so -; everybody sees files with their native line endings. - -[extensions] -; The win32text extension is available and installed by default. It -; provides built-in Python hooks to perform line ending conversions. -; This is normally much faster than running an external program. -hgext.win32text = - - -[encode] -; Encode files that don't contain NUL characters. - -; ** = cleverencode: - -; Alternatively, you can explicitly specify each file extension that -; you want encoded (any you omit will be left untouched), like this: - -; *.txt = dumbencode: - - -[decode] -; Decode files that don't contain NUL characters. - -; ** = cleverdecode: - -; Alternatively, you can explicitly specify each file extension that -; you want decoded (any you omit will be left untouched), like this: - -; **.txt = dumbdecode: +; System-wide Mercurial config file. To override these settings on a +; per-user basis, please edit the following file instead, where +; USERNAME is your Windows user name: +; C:\Documents and Settings\USERNAME\Mercurial.ini + +[ui] +editor = notepad + +; By default, we try to encode and decode all files that do not +; contain ASCII NUL characters. What this means is that we try to set +; line endings to Windows style on update, and to Unix style on +; commit. This lets us cooperate with Linux and Unix users, so +; everybody sees files with their native line endings. + +[extensions] +; The win32text extension is available and installed by default. It +; provides built-in Python hooks to perform line ending conversions. +; This is normally much faster than running an external program. +hgext.win32text = + + +[encode] +; Encode files that don't contain NUL characters. + +; ** = cleverencode: + +; Alternatively, you can explicitly specify each file extension that +; you want encoded (any you omit will be left untouched), like this: + +; *.txt = dumbencode: + + +[decode] +; Decode files that don't contain NUL characters. + +; ** = cleverdecode: + +; Alternatively, you can explicitly specify each file extension that +; you want decoded (any you omit will be left untouched), like this: + +; **.txt = dumbdecode: diff --git a/hgext/extdiff.py b/hgext/extdiff.py --- a/hgext/extdiff.py +++ b/hgext/extdiff.py @@ -189,4 +189,4 @@ def uisetup(ui): return mydiff cmdtable[cmd] = (save(cmd, path, diffopts), cmdtable['extdiff'][1][1:], - _('hg %s [OPT]... [FILE]...') % cmd) + _('hg %s [OPTION]... [FILE]...') % cmd) diff --git a/hgext/fetch.py b/hgext/fetch.py --- a/hgext/fetch.py +++ b/hgext/fetch.py @@ -85,14 +85,14 @@ def fetch(ui, repo, source='default', ** cmdtable = { 'fetch': - (fetch, - [('e', 'ssh', '', _('specify ssh command to use')), - ('m', 'message', '', _('use as commit message')), - ('l', 'logfile', '', _('read the commit message from ')), - ('d', 'date', '', _('record datecode as commit date')), - ('u', 'user', '', _('record user as commiter')), - ('r', 'rev', [], _('a specific revision you would like to pull')), - ('f', 'force-editor', None, _('edit commit message')), - ('', 'remotecmd', '', _('hg command to run on the remote side'))], - 'hg fetch [SOURCE]'), - } + (fetch, + [('e', 'ssh', '', _('specify ssh command to use')), + ('m', 'message', '', _('use as commit message')), + ('l', 'logfile', '', _('read the commit message from ')), + ('d', 'date', '', _('record datecode as commit date')), + ('u', 'user', '', _('record user as commiter')), + ('r', 'rev', [], _('a specific revision you would like to pull')), + ('f', 'force-editor', None, _('edit commit message')), + ('', 'remotecmd', '', _('hg command to run on the remote side'))], + _('hg fetch [SOURCE]')), +} diff --git a/hgext/gpg.py b/hgext/gpg.py --- a/hgext/gpg.py +++ b/hgext/gpg.py @@ -266,14 +266,14 @@ def node2txt(repo, node, ver): cmdtable = { "sign": (sign, - [('l', 'local', None, _("make the signature local")), - ('f', 'force', None, _("sign even if the sigfile is modified")), - ('', 'no-commit', None, _("do not commit the sigfile after signing")), - ('m', 'message', "", _("commit message")), - ('d', 'date', "", _("date code")), - ('u', 'user', "", _("user")), - ('k', 'key', "", _("the key id to sign with"))], - _("hg sign [OPTION]... [REVISION]...")), + [('l', 'local', None, _('make the signature local')), + ('f', 'force', None, _('sign even if the sigfile is modified')), + ('', 'no-commit', None, _('do not commit the sigfile after signing')), + ('m', 'message', '', _('commit message')), + ('d', 'date', '', _('date code')), + ('u', 'user', '', _('user')), + ('k', 'key', '', _('the key id to sign with'))], + _('hg sign [OPTION]... [REVISION]...')), "sigcheck": (check, [], _('hg sigcheck REVISION')), "sigs": (sigs, [], _('hg sigs')), } diff --git a/hgext/graphlog.py b/hgext/graphlog.py --- a/hgext/graphlog.py +++ b/hgext/graphlog.py @@ -141,7 +141,7 @@ def get_revs(repo, rev_opt): else: return (repo.changelog.count() - 1, 0) -def graphlog(ui, repo, *args, **opts): +def graphlog(ui, repo, **opts): """show revision history alongside an ASCII revision graph Print a revision history alongside a revision graph drawn with @@ -255,11 +255,11 @@ def graphlog(ui, repo, *args, **opts): cmdtable = { "glog": - (graphlog, - [("l", "limit", "", _("limit number of changes displayed")), - ("p", "patch", False, _("show patch")), - ("r", "rev", [], _("show the specified revision or range")), - ("", "style", "", _("display using template map file")), - ("", "template", "", _("display with template"))], - "hg glog [OPTIONS]"), + (graphlog, + [('l', 'limit', '', _('limit number of changes displayed')), + ('p', 'patch', False, _('show patch')), + ('r', 'rev', [], _('show the specified revision or range')), + ('', 'style', '', _('display using template map file')), + ('', 'template', '', _('display with template'))], + _('hg glog [OPTION]...')), } diff --git a/hgext/hgk.py b/hgext/hgk.py --- a/hgext/hgk.py +++ b/hgext/hgk.py @@ -275,25 +275,34 @@ def view(ui, repo, *etc, **opts): util.system(cmd) cmdtable = { - "^view": (view, - [('l', 'limit', '', 'limit number of changes displayed')], - 'hg view [-l LIMIT] [REVRANGE]'), - "debug-diff-tree": (difftree, [('p', 'patch', None, 'generate patch'), - ('r', 'recursive', None, 'recursive'), - ('P', 'pretty', None, 'pretty'), - ('s', 'stdin', None, 'stdin'), - ('C', 'copy', None, 'detect copies'), - ('S', 'search', "", 'search')], - "hg git-diff-tree [options] node1 node2 [files...]"), - "debug-cat-file": (catfile, [('s', 'stdin', None, 'stdin')], - "hg debug-cat-file [options] type file"), - "debug-merge-base": (base, [], "hg debug-merge-base node node"), - 'debug-rev-parse': (revparse, - [('', 'default', '', 'ignored')], - "hg debug-rev-parse rev"), - "debug-rev-list": (revlist, [('H', 'header', None, 'header'), - ('t', 'topo-order', None, 'topo-order'), - ('p', 'parents', None, 'parents'), - ('n', 'max-count', 0, 'max-count')], - "hg debug-rev-list [options] revs"), + "^view": + (view, + [('l', 'limit', '', 'limit number of changes displayed')], + 'hg view [-l LIMIT] [REVRANGE]'), + "debug-diff-tree": + (difftree, + [('p', 'patch', None, 'generate patch'), + ('r', 'recursive', None, 'recursive'), + ('P', 'pretty', None, 'pretty'), + ('s', 'stdin', None, 'stdin'), + ('C', 'copy', None, 'detect copies'), + ('S', 'search', "", 'search')], + 'hg git-diff-tree [OPTION]... NODE1 NODE2 [FILE]...'), + "debug-cat-file": + (catfile, + [('s', 'stdin', None, 'stdin')], + 'hg debug-cat-file [OPTION]... TYPE FILE'), + "debug-merge-base": + (base, [], 'hg debug-merge-base node node'), + "debug-rev-parse": + (revparse, + [('', 'default', '', 'ignored')], + 'hg debug-rev-parse REV'), + "debug-rev-list": + (revlist, + [('H', 'header', None, 'header'), + ('t', 'topo-order', None, 'topo-order'), + ('p', 'parents', None, 'parents'), + ('n', 'max-count', 0, 'max-count')], + 'hg debug-rev-list [options] revs'), } diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -532,6 +532,10 @@ class queue: return (err, n) def delete(self, repo, patches, opts): + if not patches and not opts.get('rev'): + raise util.Abort(_('qdelete requires at least one revision or ' + 'patch name')) + realpatches = [] for patch in patches: patch = self.lookup(patch, strict=True) @@ -1380,11 +1384,13 @@ class queue: def delete(ui, repo, *patches, **opts): """remove patches from queue - With --rev, mq will stop managing the named revisions. The - patches must be applied and at the base of the stack. This option - is useful when the patches have been applied upstream. + The patches must not be applied, unless they are arguments to + the --rev parameter. At least one patch or revision is required. - Otherwise, the patches must not be applied. + With --rev, mq will stop managing the named revisions (converting + them to regular mercurial changesets). The patches must be applied + and at the base of the stack. This option is useful when the patches + have been applied upstream. With --keep, the patch files are preserved in the patch directory.""" q = repo.mq @@ -2080,44 +2086,49 @@ def reposetup(ui, repo): seriesopts = [('s', 'summary', None, _('print first line of patch header'))] cmdtable = { - "qapplied": (applied, [] + seriesopts, 'hg qapplied [-s] [PATCH]'), - "qclone": (clone, - [('', 'pull', None, _('use pull protocol to copy metadata')), - ('U', 'noupdate', None, _('do not update the new working directories')), - ('', 'uncompressed', None, - _('use uncompressed transfer (fast over LAN)')), - ('e', 'ssh', '', _('specify ssh command to use')), - ('p', 'patches', '', _('location of source patch repo')), - ('', 'remotecmd', '', - _('specify hg command to run on the remote side'))], - 'hg qclone [OPTION]... SOURCE [DEST]'), + "qapplied": (applied, [] + seriesopts, _('hg qapplied [-s] [PATCH]')), + "qclone": + (clone, + [('', 'pull', None, _('use pull protocol to copy metadata')), + ('U', 'noupdate', None, _('do not update the new working directories')), + ('', 'uncompressed', None, + _('use uncompressed transfer (fast over LAN)')), + ('e', 'ssh', '', _('specify ssh command to use')), + ('p', 'patches', '', _('location of source patch repo')), + ('', 'remotecmd', '', + _('specify hg command to run on the remote side'))], + _('hg qclone [OPTION]... SOURCE [DEST]')), "qcommit|qci": (commit, commands.table["^commit|ci"][1], - 'hg qcommit [OPTION]... [FILE]...'), - "^qdiff": (diff, - [('g', 'git', None, _('use git extended diff format')), - ('I', 'include', [], _('include names matching the given patterns')), - ('X', 'exclude', [], _('exclude names matching the given patterns'))], - 'hg qdiff [-I] [-X] [FILE]...'), + _('hg qcommit [OPTION]... [FILE]...')), + "^qdiff": + (diff, + [('g', 'git', None, _('use git extended diff format')), + ('I', 'include', [], _('include names matching the given patterns')), + ('X', 'exclude', [], _('exclude names matching the given patterns'))], + _('hg qdiff [-I] [-X] [-g] [FILE]...')), "qdelete|qremove|qrm": (delete, [('k', 'keep', None, _('keep patch file')), ('r', 'rev', [], _('stop managing a revision'))], - 'hg qdelete [-k] [-r REV]... PATCH...'), + _('hg qdelete [-k] [-r REV]... [PATCH]...')), 'qfold': (fold, [('e', 'edit', None, _('edit patch header')), - ('k', 'keep', None, _('keep folded patch files')) - ] + commands.commitopts, - 'hg qfold [-e] [-m ] [-l = argcount: # ignore and let getopt report an error if there is no value - if candidate < valuepos: - valuepos = candidate - except ValueError: - pass - if valuepos < argcount: - values.append(args[valuepos]) - pos = valuepos + break + del args[pos] + values.append(args.pop(pos)) + argcount -= 2 + elif args[pos][:2] in shortopts: + # short option can have no following space, e.g. hg log -Rfoo + values.append(args.pop(pos)[2:]) + argcount -= 1 + else: + pos += 1 return values def dispatch(ui, args, argv0=None): @@ -313,6 +318,15 @@ def dispatch(ui, args, argv0=None): fullargs = args cmd, func, args, options, cmdoptions = parse(ui, args) + if options["config"]: + raise util.Abort(_("Option --config may not be abbreviated!")) + if options["cwd"]: + raise util.Abort(_("Option --cwd may not be abbreviated!")) + if options["repository"]: + raise util.Abort(_( + "Option -R has to be separated from other options (i.e. not -qR) " + "and --repository may only be abbreviated as --repo!")) + if options["encoding"]: util._encoding = options["encoding"] if options["encodingmode"]: diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -169,6 +169,9 @@ def backout(ui, repo, node=None, rev=Non if not rev: rev = node + if not rev: + raise util.Abort(_("please specify a revision to backout")) + cmdutil.bail_if_changed(repo) op1, op2 = repo.dirstate.parents() if op2 != nullid: @@ -1392,6 +1395,8 @@ def help_(ui, name=None, with_version=Fa try: ct = mod.cmdtable except AttributeError: + ct = None + if not ct: ui.status(_('no commands defined\n')) return @@ -2765,14 +2770,16 @@ table = { ('r', 'rev', '', _('revision to backout')), ] + walkopts + commitopts, _('hg backout [OPTION]... [-r] REV')), - "branch": (branch, - [('f', 'force', None, - _('set branch name even if it shadows an existing branch'))], - _('hg branch [NAME]')), - "branches": (branches, - [('a', 'active', False, - _("show only branches that have unmerged heads"))], - _('hg branches [-a]')), + "branch": + (branch, + [('f', 'force', None, + _('set branch name even if it shadows an existing branch'))], + _('hg branch [NAME]')), + "branches": + (branches, + [('a', 'active', False, + _('show only branches that have unmerged heads'))], + _('hg branches [-a]')), "bundle": (bundle, [('f', 'force', None, @@ -2834,9 +2841,10 @@ table = { "debugdata": (debugdata, [], _('debugdata FILE REV')), "debugindex": (debugindex, [], _('debugindex FILE')), "debugindexdot": (debugindexdot, [], _('debugindexdot FILE')), - "debugrename": (debugrename, - [('r', 'rev', '', _('revision to debug'))], - _('debugrename [-r REV] FILE')), + "debugrename": + (debugrename, + [('r', 'rev', '', _('revision to debug'))], + _('debugrename [-r REV] FILE')), "debugwalk": (debugwalk, walkopts, _('debugwalk [OPTION]... [FILE]...')), "^diff": (diff, diff --git a/mercurial/httprepo.py b/mercurial/httprepo.py --- a/mercurial/httprepo.py +++ b/mercurial/httprepo.py @@ -288,6 +288,7 @@ class httprepository(remoterepository): if not (proto.startswith('application/mercurial-') or proto.startswith('text/plain') or proto.startswith('application/hg-changegroup')): + self.ui.debug(_("Requested URL: '%s'\n") % cu) raise hg.RepoError(_("'%s' does not appear to be an hg repository") % self._url) diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -237,7 +237,7 @@ class ui(object): try: func = getattr(cdata, funcname) return func(section, name) - except ConfigParser.InterpolationError, inst: + except (ConfigParser.InterpolationError, ValueError), inst: msg = _("Error in configuration section [%s] " "parameter '%s':\n%s") % (section, name, inst) if abort: diff --git a/tests/test-backout b/tests/test-backout --- a/tests/test-backout +++ b/tests/test-backout @@ -2,9 +2,14 @@ HGMERGE=true; export HGMERGE -echo '# basic operation' hg init basic cd basic + +echo '# should complain' +hg backout +hg backout -r 0 0 + +echo '# basic operation' echo a > a hg commit -d '0 0' -A -m a echo b >> a diff --git a/tests/test-backout.out b/tests/test-backout.out --- a/tests/test-backout.out +++ b/tests/test-backout.out @@ -1,3 +1,6 @@ +# should complain +abort: please specify a revision to backout +abort: please specify just one revision # basic operation adding a reverting a diff --git a/tests/test-extdiff.out b/tests/test-extdiff.out --- a/tests/test-extdiff.out +++ b/tests/test-extdiff.out @@ -5,7 +5,7 @@ Only in a: a making snapshot of 0 files from rev 000000000000 making snapshot of 1 files from working dir diffing a.000000000000 a -hg falabala [OPT]... [FILE]... +hg falabala [OPTION]... [FILE]... use 'echo' to diff repository (or selected files) diff --git a/tests/test-extension b/tests/test-extension --- a/tests/test-extension +++ b/tests/test-extension @@ -53,3 +53,14 @@ echo '[extensions]' > $HGRCPATH echo "barfoo = $barfoopath" >> $HGRCPATH cd a hg foo + +cd .. +cat > empty.py < $HGRCPATH +echo "empty = $emptypath" >> $HGRCPATH +hg help empty diff --git a/tests/test-extension.out b/tests/test-extension.out --- a/tests/test-extension.out +++ b/tests/test-extension.out @@ -19,3 +19,6 @@ ui.parentui isnot None reposetup called for a ui == repo.ui Foo +empty extension - empty cmdtable + +no commands defined diff --git a/tests/test-globalopts b/tests/test-globalopts --- a/tests/test-globalopts +++ b/tests/test-globalopts @@ -28,6 +28,21 @@ hg --repository b tip echo %% abbrev of long option hg --repo c tip +echo "%% earlygetopt with duplicate options (36d23de02da1)" +hg --cwd a --cwd b --cwd c tip +hg --repo c --repository b -R a tip + +echo "%% earlygetopt short option without following space" +hg -q -Rb tip + +echo "%% earlygetopt with illegal abbreviations" +hg --confi "foo.bar=baz" +hg --cw a tip +hg --rep a tip +hg --repositor a tip +hg -qR a tip +hg -qRa tip + echo %% --cwd hg --cwd a parents diff --git a/tests/test-globalopts.out b/tests/test-globalopts.out --- a/tests/test-globalopts.out +++ b/tests/test-globalopts.out @@ -32,6 +32,29 @@ user: test date: Thu Jan 01 00:00:01 1970 +0000 summary: b +%% earlygetopt with duplicate options (36d23de02da1) +changeset: 1:b6c483daf290 +tag: tip +parent: -1:000000000000 +user: test +date: Thu Jan 01 00:00:01 1970 +0000 +summary: b + +changeset: 0:8580ff50825a +tag: tip +user: test +date: Thu Jan 01 00:00:01 1970 +0000 +summary: a + +%% earlygetopt short option without following space +0:b6c483daf290 +%% earlygetopt with illegal abbreviations +abort: Option --config may not be abbreviated! +abort: Option --cwd may not be abbreviated! +abort: Option -R has to be separated from other options (i.e. not -qR) and --repository may only be abbreviated as --repo! +abort: Option -R has to be separated from other options (i.e. not -qR) and --repository may only be abbreviated as --repo! +abort: Option -R has to be separated from other options (i.e. not -qR) and --repository may only be abbreviated as --repo! +abort: Option -R has to be separated from other options (i.e. not -qR) and --repository may only be abbreviated as --repo! %% --cwd changeset: 0:8580ff50825a tag: tip diff --git a/tests/test-glog b/tests/test-glog --- a/tests/test-glog +++ b/tests/test-glog @@ -138,3 +138,6 @@ hg glog -q echo % glog hg glog + +echo % unused arguments +hg glog -q foo || echo failed diff --git a/tests/test-glog.out b/tests/test-glog.out --- a/tests/test-glog.out +++ b/tests/test-glog.out @@ -307,3 +307,9 @@ o changeset: 0:7aa22e58e8c1 date: Thu Jan 01 00:00:00 1970 +0000 summary: (0) root +% unused arguments +hg glog: invalid arguments +hg glog [OPTION]... + +show revision history alongside an ASCII revision graph +failed diff --git a/tests/test-mq-qdelete b/tests/test-mq-qdelete --- a/tests/test-mq-qdelete +++ b/tests/test-mq-qdelete @@ -13,6 +13,8 @@ hg qnew a hg qnew b hg qnew c +hg qdel + hg qdel c hg qpop hg qdel c diff --git a/tests/test-mq-qdelete.out b/tests/test-mq-qdelete.out --- a/tests/test-mq-qdelete.out +++ b/tests/test-mq-qdelete.out @@ -1,4 +1,5 @@ adding base +abort: qdelete requires at least one revision or patch name abort: cannot delete applied patch c Now at: b a diff --git a/tests/test-ui-config b/tests/test-ui-config --- a/tests/test-ui-config +++ b/tests/test-ui-config @@ -34,8 +34,8 @@ print repr(testui.config('values', 'unkn print "---" try: print repr(testui.configbool('values', 'string')) -except ValueError, why: - print why +except util.Abort, inst: + print inst print repr(testui.configbool('values', 'bool1')) print repr(testui.configbool('values', 'bool2')) print repr(testui.configbool('values', 'bool2', True)) diff --git a/tests/test-ui-config.out b/tests/test-ui-config.out --- a/tests/test-ui-config.out +++ b/tests/test-ui-config.out @@ -8,6 +8,7 @@ Error in configuration section [interpol 'false' None --- +Error in configuration section [values] parameter 'string': Not a boolean: string value True False