Mercurial > hg-stable
changeset 35184:ee64e677c3cf
merge with stable
author | Augie Fackler <augie@google.com> |
---|---|
date | Thu, 30 Nov 2017 15:48:42 -0500 |
parents | bdd2e18b54c5 (current diff) 62539b425347 (diff) |
children | 6864c405f023 |
files | mercurial/cmdutil.py mercurial/commands.py mercurial/configitems.py mercurial/dispatch.py mercurial/localrepo.py mercurial/subrepo.py tests/test-amend.t tests/test-bookmarks-pushpull.t tests/test-setdiscovery.t |
diffstat | 19 files changed, 810 insertions(+), 234 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/convert/__init__.py Wed Nov 22 22:18:06 2017 +0800 +++ b/hgext/convert/__init__.py Thu Nov 30 15:48:42 2017 -0500 @@ -28,103 +28,6 @@ # leave the attribute unspecified. testedwith = 'ships-with-hg-core' -configtable = {} -configitem = registrar.configitem(configtable) - -configitem('convert', 'cvsps.cache', - default=True, -) -configitem('convert', 'cvsps.fuzz', - default=60, -) -configitem('convert', 'cvsps.logencoding', - default=None, -) -configitem('convert', 'cvsps.mergefrom', - default=None, -) -configitem('convert', 'cvsps.mergeto', - default=None, -) -configitem('convert', 'git.committeractions', - default=lambda: ['messagedifferent'], -) -configitem('convert', 'git.extrakeys', - default=list, -) -configitem('convert', 'git.findcopiesharder', - default=False, -) -configitem('convert', 'git.remoteprefix', - default='remote', -) -configitem('convert', 'git.renamelimit', - default=400, -) -configitem('convert', 'git.saverev', - default=True, -) -configitem('convert', 'git.similarity', - default=50, -) -configitem('convert', 'git.skipsubmodules', - default=False, -) -configitem('convert', 'hg.clonebranches', - default=False, -) -configitem('convert', 'hg.ignoreerrors', - default=False, -) -configitem('convert', 'hg.revs', - default=None, -) -configitem('convert', 'hg.saverev', - default=False, -) -configitem('convert', 'hg.sourcename', - default=None, -) -configitem('convert', 'hg.startrev', - default=None, -) -configitem('convert', 'hg.tagsbranch', - default='default', -) -configitem('convert', 'hg.usebranchnames', - default=True, -) -configitem('convert', 'ignoreancestorcheck', - default=False, -) -configitem('convert', 'localtimezone', - default=False, -) -configitem('convert', 'p4.encoding', - default=lambda: convcmd.orig_encoding, -) -configitem('convert', 'p4.startrev', - default=0, -) -configitem('convert', 'skiptags', - default=False, -) -configitem('convert', 'svn.debugsvnlog', - default=True, -) -configitem('convert', 'svn.trunk', - default=None, -) -configitem('convert', 'svn.tags', - default=None, -) -configitem('convert', 'svn.branches', - default=None, -) -configitem('convert', 'svn.startrev', - default=0, -) - # Commands definition was moved elsewhere to ease demandload job. @command('convert',
--- a/hgext/convert/p4.py Wed Nov 22 22:18:06 2017 +0800 +++ b/hgext/convert/p4.py Thu Nov 30 15:48:42 2017 -0500 @@ -44,6 +44,9 @@ class p4_source(common.converter_source): def __init__(self, ui, path, revs=None): + # avoid import cycle + from . import convcmd + super(p4_source, self).__init__(ui, path, revs=revs) if "/" in path and not path.startswith('//'): @@ -53,7 +56,8 @@ common.checktool('p4', abort=False) self.revmap = {} - self.encoding = self.ui.config('convert', 'p4.encoding') + self.encoding = self.ui.config('convert', 'p4.encoding', + convcmd.orig_encoding) self.re_type = re.compile( "([a-z]+)?(text|binary|symlink|apple|resource|unicode|utf\d+)" "(\+\w+)?$")
--- a/i18n/pt_BR.po Wed Nov 22 22:18:06 2017 +0800 +++ b/i18n/pt_BR.po Thu Nov 30 15:48:42 2017 -0500 @@ -1512,10 +1512,10 @@ msgstr " Por favor use :hg:`log`::" msgid "" -" hg children => hg log -r \"children()\"\n" +" hg children => hg log -r \"children(.)\"\n" " hg children -r REV => hg log -r \"children(REV)\"" msgstr "" -" hg children => hg log -r \"children()\"\n" +" hg children => hg log -r \"children(.)\"\n" " hg children -r REV => hg log -r \"children(REV)\"" msgid " See :hg:`help log` and :hg:`help revsets.children`." @@ -5510,7 +5510,7 @@ #. i18n: column positioning for "hg summary" #, python-format msgid "hist: %s (histedit --continue)\n" -msgstr "hist: %s (histedit --continue)\n" +msgstr "histedit: %s (histedit --continue)\n" #, python-format msgid "%d remaining" @@ -6527,16 +6527,16 @@ #. i18n: column positioning for "hg summary" msgid "largefiles: (no remote repo)\n" -msgstr "largefiles: (nenhum repositório remoto)\n" +msgstr "largefiles: (nenhum repositório remoto)\n" #. i18n: column positioning for "hg summary" msgid "largefiles: (no files to upload)\n" -msgstr "largefiles: (nenhum arquivo a ser enviado)\n" +msgstr "largefiles: (nenhum arquivo a ser enviado)\n" #. i18n: column positioning for "hg summary" #, python-format msgid "largefiles: %d entities for %d files to upload\n" -msgstr "largefiles: %d entidades para %d arquivos a serem enviados\n" +msgstr "largefiles: %d entidades para %d arquivos a serem enviados\n" #, python-format msgid "largefile %s is not in cache and could not be downloaded" @@ -8265,11 +8265,11 @@ #. i18n: column positioning for "hg summary" #, python-format msgid "mq: %s\n" -msgstr "mq: %s\n" +msgstr "mq: %s\n" #. i18n: column positioning for "hg summary" msgid "mq: (empty queue)\n" -msgstr "mq: (fila vazia)\n" +msgstr "mq: (fila vazia)\n" msgid "" "``mq()``\n" @@ -9799,12 +9799,12 @@ #. i18n: column positioning for "hg summary" msgid "rebase: (use \"hg rebase --abort\" to clear broken state)\n" -msgstr "rebase: (use \"hg rebase --abort\" para limpar o estado quebrado)\n" +msgstr "rebase: (use \"hg rebase --abort\" para limpar o estado quebrado)\n" #. i18n: column positioning for "hg summary" #, python-format msgid "rebase: %s, %s (rebase --continue)\n" -msgstr "rebase: %s, %s (rebase --continue)\n" +msgstr "rebase: %s, %s (rebase --continue)\n" #, python-format msgid "%d rebased" @@ -10492,7 +10492,7 @@ " caminho ou URL pedida em :hg:`clone` for idêntico a um repositório\n" " que tenha sido clonado anteriormente." -msgid " The default naming mode is \"identity.\"\n" +msgid " The default naming mode is \"identity\".\n" msgstr " O modo de nomeação padrão é \"identity\".\n" msgid "do not create a working directory" @@ -12157,7 +12157,7 @@ #. i18n: column positioning for "hg summary" #, python-format msgid "remote: %s\n" -msgstr "remoto: %s\n" +msgstr "remoto: %s\n" msgid "push failed:" msgstr "o push falhou:" @@ -15012,7 +15012,7 @@ msgid "" " If --force is specified, revisions will be grafted even if they\n" -" are already ancestors of or have been grafted to the destination.\n" +" are already ancestors of, or have been grafted to, the destination.\n" " This is useful when the revisions have since been backed out." msgstr "" " Se --force for especificado, as revisões serão enxertadas mesmo\n" @@ -15705,11 +15705,12 @@ msgid "" " Show new changesets found in the specified path/URL or the default\n" " pull location. These are the changesets that would have been pulled\n" -" if a pull at the time you issued this command." +" by :hg:`pull` at the time you issued this command." msgstr "" " Mostra novas revisões encontradas no caminho/URL especificado\n" " ou na localização de pull padrão. Estas são as revisões que\n" -" seriam trazidas se um pull fosse executado." +" seriam trazidas por :hg:`pull` no momento da execução deste\n" +" comando." msgid " See pull for valid source format details." msgstr " Veja pull para detalhes sobre formatos válidos da origem." @@ -16442,8 +16443,8 @@ " secreta, respectivamente." msgid "" -" Unless -f/--force is specified, :hg:`phase` won't move changeset from a\n" -" lower phase to an higher phase. Phases are ordered as follows::" +" Unless -f/--force is specified, :hg:`phase` won't move changesets from a\n" +" lower phase to a higher phase. Phases are ordered as follows::" msgstr "" " A não ser que -f/--force seja especificado, :hg:`phase` não\n" " moverá revisões de uma fase mais baixa para uma mais alta. As\n" @@ -17449,13 +17450,14 @@ " 'i' 'ignorado' e 'c' 'limpo'." msgid "" -" It abbreviates only those statuses which are passed. Note that ignored\n" -" files are not displayed with '--terse i' unless the -i/--ignored option is\n" -" also used." +" It abbreviates only those statuses which are passed. Note that clean and\n" +" ignored files are not displayed with '--terse ic' unless the -c/--clean\n" +" and -i/--ignored options are also used." msgstr "" " A saída será abreviada apenas para os status que forem passados.\n" -" Note que arquivos ignorados não serão mostrados com '--terse i'\n" -" a não ser que a opção -i/--ignored também seja usada." +" Note que arquivos limpos ou ignorados não serão mostrados com\n" +" '--terse ic' a não ser que as opções -c/--clean e -i/--ignored\n" +" também sejam usadas." msgid "" " The -v/--verbose option shows information when the repository is in an\n" @@ -17554,7 +17556,7 @@ #. i18n: column positioning for "hg summary" #, python-format msgid "parent: %d:%s " -msgstr "pai: %d:%s " +msgstr "pai: %d:%s " msgid " (empty repository)" msgstr " (repositório vazio)" @@ -17568,11 +17570,11 @@ #. i18n: column positioning for "hg summary" #, python-format msgid "branch: %s\n" -msgstr "ramo: %s\n" +msgstr "ramo: %s\n" #. i18n: column positioning for "hg summary" msgid "bookmarks:" -msgstr "marcadores: " +msgstr "marcadores: " #, python-format msgid "%d modified" @@ -17634,21 +17636,21 @@ #. i18n: column positioning for "hg summary" #, python-format msgid "commit: %s\n" -msgstr "consolidação: %s\n" +msgstr "consolidação: %s\n" #. i18n: column positioning for "hg summary" msgid "update: (current)\n" -msgstr "atualizações: (atual)\n" +msgstr "atualizações: (atual)\n" #. i18n: column positioning for "hg summary" #, python-format msgid "update: %d new changesets (update)\n" -msgstr "atualizações: %d novas revisões (update)\n" +msgstr "atualizações: %d novas revisões (update)\n" #. i18n: column positioning for "hg summary" #, python-format msgid "update: %d new changesets, %d branch heads (merge)\n" -msgstr "atualizações: %d novas revisões, %d cabeças de ramo (merge)\n" +msgstr "atualizações: %d novas revisões, %d cabeças de ramo (merge)\n" #, python-format msgid "%d draft" @@ -17660,7 +17662,7 @@ #, python-format msgid "phases: %s\n" -msgstr "fases: %s\n" +msgstr "fases: %s\n" #, python-format msgid "orphan: %d changesets" @@ -17691,7 +17693,7 @@ #. i18n: column positioning for "hg summary" msgid "remote: (synced)\n" -msgstr "remoto: (sincronizado)\n" +msgstr "remoto: (sincronizado)\n" msgid "force tag" msgstr "força a mudança da etiqueta" @@ -20935,6 +20937,9 @@ msgid "Changegroups" msgstr "Changegroups" +msgid "Config Registrar" +msgstr "Registrador de Configurações" + msgid "Repository Requirements" msgstr "Requisitos do Repositório" @@ -23843,25 +23848,31 @@ " Run right before a phase change is actually finalized. Any repository change\n" " will be visible to the hook program. This lets you validate the transaction\n" " content or change it. Exit status 0 allows the commit to proceed. A non-zero\n" -" status will cause the transaction to be rolled back.\n" +" status will cause the transaction to be rolled back. The hook is called\n" +" multiple times, once for each revision affected by a phase change.\n" " The affected node is available in ``$HG_NODE``, the phase in ``$HG_PHASE``\n" " while the previous ``$HG_OLDPHASE``. In case of new node, ``$HG_OLDPHASE``\n" " will be empty. In addition, the reason for the transaction opening will be in\n" " ``$HG_TXNNAME``, and a unique identifier for the transaction will be in\n" -" ``HG_TXNID``." -msgstr "" -"``pretxnclose``\n" +" ``HG_TXNID``. The hook is also run for newly added revisions. In this case\n" +" the ``$HG_OLDPHASE`` entry will be empty." +msgstr "" +"``pretxnclose-phase``\n" " Executado imediatamente antes de uma mudança de fase ser finalizada.\n" " Qualquer mudança do repositório será visível para o gancho.\n" " Isto permite que o conteúdo da transação seja validado ou alterado.\n" " O status de saída 0 permite que a consolidação prossiga. Um status\n" " de saída diferente de zero fará com que a transação seja desfeita.\n" +" O gancho é chamado diversas vezes, uma para cada revisão afetada\n" +" pela mudança de fase.\n" " O nó afetado será passado em ``$HG_NODE``, a nova fase em ``$HG_PHASE``\n" " e a anterior em ``$HG_OLDPHASE``.\n" " No caso de um novo nó, ``$HG_OLDPHASE`` estará vazia.\n" " Adicionalmente, a razão da abertura da transação será passada em\n" " ``$HG_TXNNAME``, e um identificador único para a transação será\n" -" passado em ``HG_TXNID``." +" passado em ``HG_TXNID``.\n" +" O gancho também será executado para revisões novas; nesse caso,\n" +" ``$HG_OLDPHASE`` estará vazia." msgid "" "``txnclose``\n" @@ -25832,6 +25843,105 @@ "As regras são aplicadas na ordem de definição." msgid "" +"``subrepos``\n" +"------------" +msgstr "" +"``subrepos``\n" +"------------" + +msgid "" +"This section contains options that control the behavior of the\n" +"subrepositories feature. See also :hg:`help subrepos`." +msgstr "" +"Esta seção contém opções que controlam o comportamento\n" +"da funcionalidade de sub-repositórios.\n" +"Veja também :hg:`help subrepos`." + +msgid "" +"Security note: auditing in Mercurial is known to be insufficient to\n" +"prevent clone-time code execution with carefully constructed Git\n" +"subrepos. It is unknown if a similar detect is present in Subversion\n" +"subrepos. Both Git and Subversion subrepos are disabled by default\n" +"out of security concerns. These subrepo types can be enabled using\n" +"the respective options below." +msgstr "" +"Aviso de segurança: sabe-se que a auditoria no Mercurial é\n" +"insuficiente para impedir execução de código no momento da\n" +"clonagem com repositórios Git construídos maliciosamente.\n" +"Não se sabe se esse problema afeta repositórios do Subversion.\n" +"Tanto sub-repositórios do Git como do Subversion são por padrão\n" +"desabilitados por razões de segurança.\n" +"Esses tipos de sub-repositórios podem ser habilitados usando as\n" +"respectivas opções abaixo." + +msgid "" +"``allowed``\n" +" Whether subrepositories are allowed in the working directory." +msgstr "" +"``allowed``\n" +" Define se sub-repositórios são permitidos no diretório\n" +" de trabalho." + +msgid "" +" When false, commands involving subrepositories (like :hg:`update`)\n" +" will fail for all subrepository types.\n" +" (default: true)" +msgstr "" +" Se False, comandos envolvendo sub-repositórios (como :hg:`update`)\n" +" falharão para todos os tipos de sub-repositório.\n" +" (padrão: True)" + +msgid "" +"``hg:allowed``\n" +" Whether Mercurial subrepositories are allowed in the working\n" +" directory. This option only has an effect if ``subrepos.allowed``\n" +" is true.\n" +" (default: true)" +msgstr "" +"``hg:allowed``\n" +" Se sub-repositórios do Mercurial são permitidos no diretório\n" +" de trabalho.\n" +" Esta opção tem efeito apenas se ``subrepos.allowed`` for True.\n" +" (padrão: True)" + +msgid "" +"``git:allowed``\n" +" Whether Git subrepositories are allowed in the working directory.\n" +" This option only has an effect if ``subrepos.allowed`` is true." +msgstr "" +"``git:allowed``\n" +" Se sub-repositórios do Git são permitidos no diretório\n" +" de trabalho.\n" +" Esta opção tem efeito apenas se ``subrepos.allowed`` for True." + +msgid "" +" See the security note above before enabling Git subrepos.\n" +" (default: false)" +msgstr "" +" Veja o aviso de segurança acima antes de habilitar\n" +" sub-repositórios do Git.\n" +" (padrão: False)" + +msgid "" +"``svn:allowed``\n" +" Whether Subversion subrepositories are allowed in the working\n" +" directory. This option only has an effect if ``subrepos.allowed``\n" +" is true." +msgstr "" +"``svn:allowed``\n" +" Se sub-repositórios do Subversion são permitidos no diretório\n" +" de trabalho.\n" +" Esta opção tem efeito apenas se ``subrepos.allowed`` for True." + +msgid "" +" See the security note above before enabling Subversion subrepos.\n" +" (default: false)" +msgstr "" +" Veja o aviso de segurança acima antes de habilitar\n" +" sub-repositórios do Subversion.\n" +" (padrão: False)" + +msgid "" "``templatealias``\n" "-----------------" msgstr "" @@ -29958,7 +30068,7 @@ msgid "" " After selecting a merge program, Mercurial will by default attempt\n" " to merge the files using a simple merge algorithm first. Only if it doesn't\n" -" succeed because of conflicting changes Mercurial will actually execute the\n" +" succeed because of conflicting changes will Mercurial actually execute the\n" " merge program. Whether to use the simple merge algorithm first can be\n" " controlled by the premerge setting of the merge tool. Premerge is enabled by\n" " default unless the file is binary or a symlink." @@ -30334,7 +30444,7 @@ "Veja :hg:`help -v phase` para alguns exemplos." msgid "" -"To make yours commits secret by default, put this in your\n" +"To make your commits secret by default, put this in your\n" "configuration file::" msgstr "" "Para colocar suas consolidações na fase secret por padrão,\n" @@ -30453,7 +30563,7 @@ msgid " hg phase --force --draft ." msgstr " hg phase --force --draft ." -msgid " - show a list of changeset revision and phase::" +msgid " - show a list of changeset revisions and each corresponding phase::" msgstr " - mostra uma lista de números de revisão e suas respectivas fases::" msgid " hg log --template \"{rev} {phase}\\n\"" @@ -30755,7 +30865,7 @@ msgid "" "For example, ``tag(r're:(?i)release')`` matches \"release\" or \"RELEASE\"\n" -"or \"Release\", etc" +"or \"Release\", etc." msgstr "" "Por exemplo, ``tag(r're:(?i)release')`` corresponde a \"release\"\n" "ou \"RELEASE\" ou \"Release\", etc." @@ -30886,7 +30996,7 @@ " hg log -r \"(keyword(bug) or keyword(issue)) and not ancestors(tag())\"" msgid "" -"- Update to commit that bookmark @ is pointing too, without activating the\n" +"- Update to the commit that bookmark @ is pointing to, without activating the\n" " bookmark (this works because the last revision of the revset is used)::" msgstr "" "- Atualiza para a revisão que o marcador @ está apontando, sem ativar\n" @@ -33530,12 +33640,12 @@ #. i18n: column positioning for "hg log" #, python-format msgid "bookmark: %s\n" -msgstr "marcador: %s\n" +msgstr "marcador: %s\n" #. i18n: column positioning for "hg log" #, python-format msgid "tag: %s\n" -msgstr "etiqueta: %s\n" +msgstr "etiqueta: %s\n" #, python-format msgid "no such name: %s" @@ -36031,6 +36141,20 @@ msgstr "aviso: removendo 'hgrc' potencialmente hostil em '%s'\n" #, python-format +msgid "subrepo '%s' traverses symbolic link" +msgstr "o sub-repositório '%s' atravessa um link simbólico" + +msgid "subrepos not enabled" +msgstr "sub-repositórios não estão habilitados" + +msgid "see 'hg help config.subrepos' for details" +msgstr "veja 'hg help config.subrepos' para detalhes" + +#, python-format +msgid "%s subrepos not allowed" +msgstr "sub-repositórios %s não são permitidos" + +#, python-format msgid "unknown subrepo type %s" msgstr "tipo de sub-repositório %s desconhecido"
--- a/mercurial/chgserver.py Wed Nov 22 22:18:06 2017 +0800 +++ b/mercurial/chgserver.py Thu Nov 30 15:48:42 2017 -0500 @@ -235,6 +235,7 @@ cwds = dispatch._earlygetopt(['--cwd'], args) cwd = cwds and os.path.realpath(cwds[-1]) or None rpath = dispatch._earlygetopt(["-R", "--repository", "--repo"], args) + rpath = rpath and rpath[-1] or '' path, newlui = dispatch._getlocal(newui, rpath, wd=cwd) return (newui, newlui)
--- a/mercurial/cmdutil.py Wed Nov 22 22:18:06 2017 +0800 +++ b/mercurial/cmdutil.py Thu Nov 30 15:48:42 2017 -0500 @@ -3166,6 +3166,18 @@ raise error.Abort( _("failed to mark all new/missing files as added/removed")) + # Check subrepos. This depends on in-place wctx._status update in + # subrepo.precommit(). To minimize the risk of this hack, we do + # nothing if .hgsub does not exist. + if '.hgsub' in wctx or '.hgsub' in old: + from . import subrepo # avoid cycle: cmdutil -> subrepo -> cmdutil + subs, commitsubs, newsubstate = subrepo.precommit( + ui, wctx, wctx._status, matcher) + # amend should abort if commitsubrepos is enabled + assert not commitsubs + if subs: + subrepo.writestate(repo, newsubstate) + filestoamend = set(f for f in wctx.files() if matcher(f)) changes = (len(filestoamend) > 0) @@ -3179,9 +3191,11 @@ # introduced file X and the file was renamed in the working # copy, then those two files are the same and # we can discard X from our list of files. Likewise if X - # was deleted, it's no longer relevant + # was removed, it's no longer relevant. If X is missing (aka + # deleted), old X must be preserved. files.update(filestoamend) - files = [f for f in files if not samefile(f, wctx, base)] + files = [f for f in files if (not samefile(f, wctx, base) + or f in wctx.deleted())] def filectxfn(repo, ctx_, path): try: @@ -3193,12 +3207,11 @@ if path not in filestoamend: return old.filectx(path) + # Return None for removed files. + if path in wctx.removed(): + return None + fctx = wctx[path] - - # Return None for removed files. - if not fctx.exists(): - return None - flags = fctx.flags() mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
--- a/mercurial/commands.py Wed Nov 22 22:18:06 2017 +0800 +++ b/mercurial/commands.py Thu Nov 30 15:48:42 2017 -0500 @@ -103,6 +103,10 @@ _("when to paginate (boolean, always, auto, or never)"), _('TYPE')), ] +# options which must be pre-parsed before loading configs and extensions +# TODO: perhaps --debugger should be included +earlyoptflags = ("--cwd", "-R", "--repository", "--repo", "--config") + dryrunopts = cmdutil.dryrunopts remoteopts = cmdutil.remoteopts walkopts = cmdutil.walkopts
--- a/mercurial/configitems.py Wed Nov 22 22:18:06 2017 +0800 +++ b/mercurial/configitems.py Thu Nov 30 15:48:42 2017 -0500 @@ -208,6 +208,99 @@ default=None, generic=True, ) +coreconfigitem('convert', 'cvsps.cache', + default=True, +) +coreconfigitem('convert', 'cvsps.fuzz', + default=60, +) +coreconfigitem('convert', 'cvsps.logencoding', + default=None, +) +coreconfigitem('convert', 'cvsps.mergefrom', + default=None, +) +coreconfigitem('convert', 'cvsps.mergeto', + default=None, +) +coreconfigitem('convert', 'git.committeractions', + default=lambda: ['messagedifferent'], +) +coreconfigitem('convert', 'git.extrakeys', + default=list, +) +coreconfigitem('convert', 'git.findcopiesharder', + default=False, +) +coreconfigitem('convert', 'git.remoteprefix', + default='remote', +) +coreconfigitem('convert', 'git.renamelimit', + default=400, +) +coreconfigitem('convert', 'git.saverev', + default=True, +) +coreconfigitem('convert', 'git.similarity', + default=50, +) +coreconfigitem('convert', 'git.skipsubmodules', + default=False, +) +coreconfigitem('convert', 'hg.clonebranches', + default=False, +) +coreconfigitem('convert', 'hg.ignoreerrors', + default=False, +) +coreconfigitem('convert', 'hg.revs', + default=None, +) +coreconfigitem('convert', 'hg.saverev', + default=False, +) +coreconfigitem('convert', 'hg.sourcename', + default=None, +) +coreconfigitem('convert', 'hg.startrev', + default=None, +) +coreconfigitem('convert', 'hg.tagsbranch', + default='default', +) +coreconfigitem('convert', 'hg.usebranchnames', + default=True, +) +coreconfigitem('convert', 'ignoreancestorcheck', + default=False, +) +coreconfigitem('convert', 'localtimezone', + default=False, +) +coreconfigitem('convert', 'p4.encoding', + default=dynamicdefault, +) +coreconfigitem('convert', 'p4.startrev', + default=0, +) +coreconfigitem('convert', 'skiptags', + default=False, +) +coreconfigitem('convert', 'svn.debugsvnlog', + default=True, +) +coreconfigitem('convert', 'svn.trunk', + default=None, +) +coreconfigitem('convert', 'svn.tags', + default=None, +) +coreconfigitem('convert', 'svn.branches', + default=None, +) +coreconfigitem('convert', 'svn.startrev', + default=0, +) coreconfigitem('debug', 'dirstate.delaywrite', default=0, )
--- a/mercurial/dispatch.py Wed Nov 22 22:18:06 2017 +0800 +++ b/mercurial/dispatch.py Thu Nov 30 15:48:42 2017 -0500 @@ -55,6 +55,9 @@ self.fout = fout self.ferr = ferr + # remember options pre-parsed by _earlyreqopt*() + self.earlyoptions = {} + # reposetups which run before extensions, useful for chg to pre-fill # low-level repo state (for example, changelog) before extensions. self.prereposetups = prereposetups or [] @@ -147,7 +150,7 @@ try: if not req.ui: req.ui = uimod.ui.load() - if '--traceback' in req.args: + if _earlyreqoptbool(req, 'traceback', ['--traceback']): req.ui.setconfig('ui', 'traceback', 'on', '--traceback') # set ui streams from the request @@ -261,7 +264,8 @@ # read --config before doing anything else # (e.g. to change trust settings for reading .hg/hgrc) - cfgs = _parseconfig(req.ui, _earlygetopt(['--config'], req.args)) + cfgs = _parseconfig(req.ui, + _earlyreqopt(req, 'config', ['--config'])) if req.repo: # copy configs that were passed on the cmdline (--config) to @@ -275,7 +279,7 @@ if not debugger or ui.plain(): # if we are in HGPLAIN mode, then disable custom debugging debugger = 'pdb' - elif '--debugger' in req.args: + elif _earlyreqoptbool(req, 'debugger', ['--debugger']): # This import can be slow for fancy debuggers, so only # do it when absolutely necessary, i.e. when actual # debugging has been requested @@ -289,7 +293,7 @@ debugmortem[debugger] = debugmod.post_mortem # enter the debugger before command execution - if '--debugger' in req.args: + if _earlyreqoptbool(req, 'debugger', ['--debugger']): ui.warn(_("entering debugger - " "type c to continue starting hg or h for help\n")) @@ -305,7 +309,7 @@ ui.flush() except: # re-raises # enter the debugger when we hit an exception - if '--debugger' in req.args: + if _earlyreqoptbool(req, 'debugger', ['--debugger']): traceback.print_exc() debugmortem[debugger](sys.exc_info()[2]) raise @@ -465,7 +469,7 @@ self.cmdname = cmd = args.pop(0) self.givenargs = args - for invalidarg in ("--cwd", "-R", "--repository", "--repo", "--config"): + for invalidarg in commands.earlyoptflags: if _earlygetopt([invalidarg], args): self.badalias = (_("error in definition for alias '%s': %s may " "only be given on the command line") @@ -640,11 +644,11 @@ return configs -def _earlygetopt(aliases, args): +def _earlygetopt(aliases, args, strip=True): """Return list of values for an option (or aliases). The values are listed in the order they appear in args. - The options and values are removed from args. + The options and values are removed from args if strip=True. >>> args = [b'x', b'--cwd', b'foo', b'y'] >>> _earlygetopt([b'--cwd'], args), args @@ -654,13 +658,33 @@ >>> _earlygetopt([b'--cwd'], args), args (['bar'], ['x', 'y']) + >>> args = [b'x', b'--cwd=bar', b'y'] + >>> _earlygetopt([b'--cwd'], args, strip=False), args + (['bar'], ['x', '--cwd=bar', 'y']) + >>> args = [b'x', b'-R', b'foo', b'y'] >>> _earlygetopt([b'-R'], args), args (['foo'], ['x', 'y']) + >>> args = [b'x', b'-R', b'foo', b'y'] + >>> _earlygetopt([b'-R'], args, strip=False), args + (['foo'], ['x', '-R', 'foo', 'y']) + >>> args = [b'x', b'-Rbar', b'y'] >>> _earlygetopt([b'-R'], args), args (['bar'], ['x', 'y']) + + >>> args = [b'x', b'-Rbar', b'y'] + >>> _earlygetopt([b'-R'], args, strip=False), args + (['bar'], ['x', '-Rbar', 'y']) + + >>> args = [b'x', b'-R=bar', b'y'] + >>> _earlygetopt([b'-R'], args), args + (['=bar'], ['x', 'y']) + + >>> args = [b'x', b'-R', b'--', b'y'] + >>> _earlygetopt([b'-R'], args), args + ([], ['x', '-R', '--', 'y']) """ try: argcount = args.index("--") @@ -671,28 +695,77 @@ pos = 0 while pos < argcount: fullarg = arg = args[pos] - equals = arg.find('=') + equals = -1 + if arg.startswith('--'): + equals = arg.find('=') if equals > -1: arg = arg[:equals] if arg in aliases: - del args[pos] if equals > -1: values.append(fullarg[equals + 1:]) - argcount -= 1 + if strip: + del args[pos] + argcount -= 1 + else: + pos += 1 else: if pos + 1 >= argcount: # ignore and let getopt report an error if there is no value break - values.append(args.pop(pos)) - argcount -= 2 + values.append(args[pos + 1]) + if strip: + del args[pos:pos + 2] + argcount -= 2 + else: + pos += 2 elif arg[:2] in shortopts: # short option can have no following space, e.g. hg log -Rfoo - values.append(args.pop(pos)[2:]) - argcount -= 1 + values.append(args[pos][2:]) + if strip: + del args[pos] + argcount -= 1 + else: + pos += 1 else: pos += 1 return values +def _earlyreqopt(req, name, aliases): + """Peek a list option without using a full options table""" + values = _earlygetopt(aliases, req.args, strip=False) + req.earlyoptions[name] = values + return values + +def _earlyreqoptstr(req, name, aliases): + """Peek a string option without using a full options table""" + value = (_earlygetopt(aliases, req.args, strip=False) or [''])[-1] + req.earlyoptions[name] = value + return value + +def _earlyreqoptbool(req, name, aliases): + """Peek a boolean option without using a full options table + + >>> req = request([b'x', b'--debugger']) + >>> _earlyreqoptbool(req, b'debugger', [b'--debugger']) + True + + >>> req = request([b'x', b'--', b'--debugger']) + >>> _earlyreqoptbool(req, b'debugger', [b'--debugger']) + """ + try: + argcount = req.args.index("--") + except ValueError: + argcount = len(req.args) + value = None + pos = 0 + while pos < argcount: + arg = req.args[pos] + if arg in aliases: + value = True + pos += 1 + req.earlyoptions[name] = value + return value + def runcommand(lui, repo, cmd, fullargs, ui, options, d, cmdpats, cmdoptions): # run pre-hook, and abort if it fails hook.hook(lui, repo, "pre-%s" % cmd, True, args=" ".join(fullargs), @@ -727,8 +800,8 @@ lui = ui.copy() lui.readconfig(os.path.join(path, ".hg", "hgrc"), path) - if rpath and rpath[-1]: - path = lui.expandpath(rpath[-1]) + if rpath: + path = lui.expandpath(rpath) lui = ui.copy() lui.readconfig(os.path.join(path, ".hg", "hgrc"), path) @@ -759,6 +832,9 @@ fn = entry[0] if cmd and util.safehasattr(fn, 'shell'): + # shell alias shouldn't receive early options which are consumed by hg + args = args[:] + _earlygetopt(commands.earlyoptflags, args, strip=True) d = lambda: fn(ui, *args[1:]) return lambda: runcommand(lui, None, cmd, args[:1], ui, options, d, [], {}) @@ -768,11 +844,11 @@ ui = req.ui # check for cwd - cwd = _earlygetopt(['--cwd'], args) + cwd = _earlyreqoptstr(req, 'cwd', ['--cwd']) if cwd: - os.chdir(cwd[-1]) + os.chdir(cwd) - rpath = _earlygetopt(["-R", "--repository", "--repo"], args) + rpath = _earlyreqoptstr(req, 'repository', ["-R", "--repository", "--repo"]) path, lui = _getlocal(ui, rpath) uis = {ui, lui} @@ -780,7 +856,7 @@ if req.repo: uis.add(req.repo.ui) - if '--profile' in args: + if _earlyreqoptbool(req, 'profile', ['--profile']): for ui_ in uis: ui_.setconfig('profiling', 'enabled', 'true', '--profile') @@ -812,14 +888,17 @@ fullargs = args cmd, func, args, options, cmdoptions = _parse(lui, args) - if options["config"]: + if options["config"] != req.earlyoptions["config"]: raise error.Abort(_("option --config may not be abbreviated!")) - if options["cwd"]: + if options["cwd"] != req.earlyoptions["cwd"]: raise error.Abort(_("option --cwd may not be abbreviated!")) - if options["repository"]: + if options["repository"] != req.earlyoptions["repository"]: raise error.Abort(_( "option -R has to be separated from other options (e.g. not " "-qR) and --repository may only be abbreviated as --repo!")) + if options["debugger"] != req.earlyoptions["debugger"]: + raise error.Abort(_("option --debugger may not be abbreviated!")) + # don't validate --profile/--traceback, which can be enabled from now if options["encoding"]: encoding.encoding = options["encoding"] @@ -908,7 +987,7 @@ except error.RequirementError: raise except error.RepoError: - if rpath and rpath[-1]: # invalid -R path + if rpath: # invalid -R path raise if not func.optionalrepo: if func.inferrepo and args and not path:
--- a/mercurial/localrepo.py Wed Nov 22 22:18:06 2017 +0800 +++ b/mercurial/localrepo.py Thu Nov 30 15:48:42 2017 -0500 @@ -1848,58 +1848,8 @@ status.modified.extend(status.clean) # mq may commit clean files # check subrepos - subs = [] - commitsubs = set() - newstate = wctx.substate.copy() - # only manage subrepos and .hgsubstate if .hgsub is present - if '.hgsub' in wctx: - # we'll decide whether to track this ourselves, thanks - for c in status.modified, status.added, status.removed: - if '.hgsubstate' in c: - c.remove('.hgsubstate') - - # compare current state to last committed state - # build new substate based on last committed state - oldstate = wctx.p1().substate - for s in sorted(newstate.keys()): - if not match(s): - # ignore working copy, use old state if present - if s in oldstate: - newstate[s] = oldstate[s] - continue - if not force: - raise error.Abort( - _("commit with new subrepo %s excluded") % s) - dirtyreason = wctx.sub(s).dirtyreason(True) - if dirtyreason: - if not self.ui.configbool('ui', 'commitsubrepos'): - raise error.Abort(dirtyreason, - hint=_("use --subrepos for recursive commit")) - subs.append(s) - commitsubs.add(s) - else: - bs = wctx.sub(s).basestate() - newstate[s] = (newstate[s][0], bs, newstate[s][2]) - if oldstate.get(s, (None, None, None))[1] != bs: - subs.append(s) - - # check for removed subrepos - for p in wctx.parents(): - r = [s for s in p.substate if s not in newstate] - subs += [s for s in r if match(s)] - if subs: - if (not match('.hgsub') and - '.hgsub' in (wctx.modified() + wctx.added())): - raise error.Abort( - _("can't commit subrepos without .hgsub")) - status.modified.insert(0, '.hgsubstate') - - elif '.hgsub' in status.removed: - # clean up .hgsubstate when .hgsub is removed - if ('.hgsubstate' in wctx and - '.hgsubstate' not in (status.modified + status.added + - status.removed)): - status.removed.insert(0, '.hgsubstate') + subs, commitsubs, newstate = subrepo.precommit( + self.ui, wctx, status, match, force=force) # make sure all explicit patterns are matched if not force:
--- a/mercurial/scmutil.py Wed Nov 22 22:18:06 2017 +0800 +++ b/mercurial/scmutil.py Thu Nov 30 15:48:42 2017 -0500 @@ -1233,9 +1233,17 @@ def reportsummary(func): """decorator for report callbacks.""" - reporef = weakref.ref(repo) + # The repoview life cycle is shorter than the one of the actual + # underlying repository. So the filtered object can die before the + # weakref is used leading to troubles. We keep a reference to the + # unfiltered object and restore the filtering when retrieving the + # repository through the weakref. + filtername = repo.filtername + reporef = weakref.ref(repo.unfiltered()) def wrapped(tr): repo = reporef() + if filtername: + repo = repo.filtered(filtername) func(repo, tr) newcat = '%2i-txnreport' % len(categories) otr.addpostclose(newcat, wrapped)
--- a/mercurial/subrepo.py Wed Nov 22 22:18:06 2017 +0800 +++ b/mercurial/subrepo.py Thu Nov 30 15:48:42 2017 -0500 @@ -293,6 +293,71 @@ writestate(repo, sm) return sm +def precommit(ui, wctx, status, match, force=False): + """Calculate .hgsubstate changes that should be applied before committing + + Returns (subs, commitsubs, newstate) where + - subs: changed subrepos (including dirty ones) + - commitsubs: dirty subrepos which the caller needs to commit recursively + - newstate: new state dict which the caller must write to .hgsubstate + + This also updates the given status argument. + """ + subs = [] + commitsubs = set() + newstate = wctx.substate.copy() + + # only manage subrepos and .hgsubstate if .hgsub is present + if '.hgsub' in wctx: + # we'll decide whether to track this ourselves, thanks + for c in status.modified, status.added, status.removed: + if '.hgsubstate' in c: + c.remove('.hgsubstate') + + # compare current state to last committed state + # build new substate based on last committed state + oldstate = wctx.p1().substate + for s in sorted(newstate.keys()): + if not match(s): + # ignore working copy, use old state if present + if s in oldstate: + newstate[s] = oldstate[s] + continue + if not force: + raise error.Abort( + _("commit with new subrepo %s excluded") % s) + dirtyreason = wctx.sub(s).dirtyreason(True) + if dirtyreason: + if not ui.configbool('ui', 'commitsubrepos'): + raise error.Abort(dirtyreason, + hint=_("use --subrepos for recursive commit")) + subs.append(s) + commitsubs.add(s) + else: + bs = wctx.sub(s).basestate() + newstate[s] = (newstate[s][0], bs, newstate[s][2]) + if oldstate.get(s, (None, None, None))[1] != bs: + subs.append(s) + + # check for removed subrepos + for p in wctx.parents(): + r = [s for s in p.substate if s not in newstate] + subs += [s for s in r if match(s)] + if subs: + if (not match('.hgsub') and + '.hgsub' in (wctx.modified() + wctx.added())): + raise error.Abort(_("can't commit subrepos without .hgsub")) + status.modified.insert(0, '.hgsubstate') + + elif '.hgsub' in status.removed: + # clean up .hgsubstate when .hgsub is removed + if ('.hgsubstate' in wctx and + '.hgsubstate' not in (status.modified + status.added + + status.removed)): + status.removed.insert(0, '.hgsubstate') + + return subs, commitsubs, newstate + def _updateprompt(ui, sub, dirty, local, remote): if dirty: msg = (_(' subrepository sources for %s differ\n'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-amend-subrepo.t Thu Nov 30 15:48:42 2017 -0500 @@ -0,0 +1,154 @@ +#testcases obsstore-off obsstore-on + + $ cat << EOF >> $HGRCPATH + > [extensions] + > amend = + > EOF + +#if obsstore-on + $ cat << EOF >> $HGRCPATH + > [experimental] + > evolution.createmarkers = True + > EOF +#endif + +Prepare parent repo +------------------- + + $ hg init r + $ cd r + + $ echo a > a + $ hg ci -Am0 + adding a + +Link first subrepo +------------------ + + $ echo 's = s' >> .hgsub + $ hg add .hgsub + $ hg init s + +amend without .hgsub + + $ hg amend s + abort: can't commit subrepos without .hgsub + [255] + +amend with subrepo + + $ hg amend + saved backup bundle to * (glob) (obsstore-off !) + $ hg status --change . + A .hgsub + A .hgsubstate + A a + $ cat .hgsubstate + 0000000000000000000000000000000000000000 s + +Update subrepo +-------------- + +add new commit to be amended + + $ echo a >> a + $ hg ci -m1 + +amend with dirty subrepo + + $ echo a >> s/a + $ hg add -R s + adding s/a + $ hg amend + abort: uncommitted changes in subrepository "s" + (use --subrepos for recursive commit) + [255] + +amend with modified subrepo + + $ hg ci -R s -m0 + $ hg amend + saved backup bundle to * (glob) (obsstore-off !) + $ hg status --change . + M .hgsubstate + M a + $ cat .hgsubstate + f7b1eb17ad24730a1651fccd46c43826d1bbc2ac s + +revert subrepo change + + $ hg up -R s -q null + $ hg amend + saved backup bundle to * (glob) (obsstore-off !) + $ hg status --change . + M a + +Link another subrepo +-------------------- + +add new commit to be amended + + $ echo b >> b + $ hg ci -qAm2 + +also checks if non-subrepo change is included + + $ echo a >> a + +amend with another subrepo + + $ hg init t + $ echo b >> t/b + $ hg ci -R t -Am0 + adding b + $ echo 't = t' >> .hgsub + $ hg amend + saved backup bundle to * (glob) (obsstore-off !) + $ hg status --change . + M .hgsub + M .hgsubstate + M a + A b + $ cat .hgsubstate + 0000000000000000000000000000000000000000 s + bfb1a4fb358498a9533dabf4f2043d94162f1fcd t + +Unlink one subrepo +------------------ + +add new commit to be amended + + $ echo a >> a + $ hg ci -m3 + +amend with one subrepo dropped + + $ echo 't = t' > .hgsub + $ hg amend + saved backup bundle to * (glob) (obsstore-off !) + $ hg status --change . + M .hgsub + M .hgsubstate + M a + $ cat .hgsubstate + bfb1a4fb358498a9533dabf4f2043d94162f1fcd t + +Unlink subrepos completely +-------------------------- + +add new commit to be amended + + $ echo a >> a + $ hg ci -m3 + +amend with .hgsub removed + + $ hg rm .hgsub + $ hg amend + saved backup bundle to * (glob) (obsstore-off !) + $ hg status --change . + M a + R .hgsub + R .hgsubstate + + $ cd ..
--- a/tests/test-amend.t Wed Nov 22 22:18:06 2017 +0800 +++ b/tests/test-amend.t Thu Nov 30 15:48:42 2017 -0500 @@ -235,3 +235,97 @@ | o A + +More complete test for status changes (issue5732) +------------------------------------------------- + +Generates history of files having 3 states, r0_r1_wc: + + r0: ground (content/missing) + r1: old state to be amended (content/missing, where missing means removed) + wc: changes to be included in r1 (content/missing-tracked/untracked) + + $ hg init $TESTTMP/wcstates + $ cd $TESTTMP/wcstates + + $ $PYTHON $TESTDIR/generate-working-copy-states.py state 2 1 + $ hg addremove -q --similarity 0 + $ hg commit -m0 + + $ $PYTHON $TESTDIR/generate-working-copy-states.py state 2 2 + $ hg addremove -q --similarity 0 + $ hg commit -m1 + + $ $PYTHON $TESTDIR/generate-working-copy-states.py state 2 wc + $ hg addremove -q --similarity 0 + $ hg forget *_*_*-untracked + $ rm *_*_missing-* + +amend r1 to include wc changes + + $ hg amend + saved backup bundle to * (glob) (obsstore-off !) + +clean/modified/removed/added states of the amended revision + + $ hg status --all --change . 'glob:content1_*_content1-tracked' + C content1_content1_content1-tracked + C content1_content2_content1-tracked + C content1_missing_content1-tracked + $ hg status --all --change . 'glob:content1_*_content[23]-tracked' + M content1_content1_content3-tracked + M content1_content2_content2-tracked + M content1_content2_content3-tracked + M content1_missing_content3-tracked + $ hg status --all --change . 'glob:content1_*_missing-tracked' + M content1_content2_missing-tracked + R content1_missing_missing-tracked + C content1_content1_missing-tracked + $ hg status --all --change . 'glob:content1_*_*-untracked' + R content1_content1_content1-untracked + R content1_content1_content3-untracked + R content1_content1_missing-untracked + R content1_content2_content1-untracked + R content1_content2_content2-untracked + R content1_content2_content3-untracked + R content1_content2_missing-untracked + R content1_missing_content1-untracked + R content1_missing_content3-untracked + R content1_missing_missing-untracked + $ hg status --all --change . 'glob:missing_content2_*' + A missing_content2_content2-tracked + A missing_content2_content3-tracked + A missing_content2_missing-tracked + $ hg status --all --change . 'glob:missing_missing_*' + A missing_missing_content3-tracked + +working directory should be all clean (with some missing/untracked files) + + $ hg status --all 'glob:*_content?-tracked' + C content1_content1_content1-tracked + C content1_content1_content3-tracked + C content1_content2_content1-tracked + C content1_content2_content2-tracked + C content1_content2_content3-tracked + C content1_missing_content1-tracked + C content1_missing_content3-tracked + C missing_content2_content2-tracked + C missing_content2_content3-tracked + C missing_missing_content3-tracked + $ hg status --all 'glob:*_missing-tracked' + ! content1_content1_missing-tracked + ! content1_content2_missing-tracked + ! content1_missing_missing-tracked + ! missing_content2_missing-tracked + ! missing_missing_missing-tracked + $ hg status --all 'glob:*-untracked' + ? content1_content1_content1-untracked + ? content1_content1_content3-untracked + ? content1_content2_content1-untracked + ? content1_content2_content2-untracked + ? content1_content2_content3-untracked + ? content1_missing_content1-untracked + ? content1_missing_content3-untracked + ? missing_content2_content2-untracked + ? missing_content2_content3-untracked + ? missing_missing_content3-untracked
--- a/tests/test-blackbox.t Wed Nov 22 22:18:06 2017 +0800 +++ b/tests/test-blackbox.t Thu Nov 30 15:48:42 2017 -0500 @@ -19,7 +19,7 @@ 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest exited 0 after * seconds (glob) 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a exited 0 after * seconds (glob) - 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000+ (5000)> blackbox + 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000+ (5000)> blackbox --config *blackbox.dirty=True* (glob) alias expansion is logged $ rm ./.hg/blackbox.log
--- a/tests/test-bookmarks-pushpull.t Wed Nov 22 22:18:06 2017 +0800 +++ b/tests/test-bookmarks-pushpull.t Thu Nov 30 15:48:42 2017 -0500 @@ -261,7 +261,7 @@ Z 1:0d2164f0ce0d $ cd ../b - $ hg up --config + $ hg up 1 files updated, 0 files merged, 0 files removed, 0 files unresolved updating bookmark foobar $ echo c2 > f2
--- a/tests/test-dispatch.t Wed Nov 22 22:18:06 2017 +0800 +++ b/tests/test-dispatch.t Thu Nov 30 15:48:42 2017 -0500 @@ -30,6 +30,89 @@ (use 'hg cat -h' to show more help) [255] +Missing parameter for early option: + + $ hg log -R 2>&1 | grep 'hg log' + hg log: option -R requires argument + hg log [OPTION]... [FILE] + (use 'hg log -h' to show more help) + + $ hg log -R -- 2>&1 | grep 'hg log' + hg log: option -R requires argument + hg log [OPTION]... [FILE] + (use 'hg log -h' to show more help) + +Parsing of early options should stop at "--": + + $ hg cat -- --config=hooks.pre-cat=false + --config=hooks.pre-cat=false: no such file in rev cb9a9f314b8b + [1] + $ hg cat -- --debugger + --debugger: no such file in rev cb9a9f314b8b + [1] + +Unparsable form of early options: + + $ hg cat --debugg + abort: option --debugger may not be abbreviated! + [255] + +Parsing failure of early options should be detected before executing the +command: + + $ hg log -b '--config=hooks.pre-log=false' default + abort: option --config may not be abbreviated! + [255] + $ hg log -b -R. default + abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo! + [255] + $ hg log --cwd .. -b --cwd=. default + abort: option --cwd may not be abbreviated! + [255] + +However, we can't prevent it from loading extensions and configs: + + $ cat <<EOF > bad.py + > raise Exception('bad') + > EOF + $ hg log -b '--config=extensions.bad=bad.py' default + *** failed to import extension bad from bad.py: bad + abort: option --config may not be abbreviated! + [255] + + $ mkdir -p badrepo/.hg + $ echo 'invalid-syntax' > badrepo/.hg/hgrc + $ hg log -b -Rbadrepo default + hg: parse error at badrepo/.hg/hgrc:1: invalid-syntax + [255] + + $ hg log -b --cwd=inexistent default + abort: No such file or directory: 'inexistent' + [255] + + $ hg log -b '--config=ui.traceback=yes' 2>&1 | grep '^Traceback' + Traceback (most recent call last): + $ hg log -b '--config=profiling.enabled=yes' 2>&1 | grep -i sample + Sample count: .*|No samples recorded\. (re) + +Early options can't be specified in [aliases] and [defaults] because they are +applied before the command name is resolved: + + $ hg log -b '--config=alias.log=log --config=hooks.pre-log=false' + hg log: option -b not recognized + error in definition for alias 'log': --config may only be given on the command + line + [255] + + $ hg log -b '--config=defaults.log=--config=hooks.pre-log=false' + abort: option --config may not be abbreviated! + [255] + +Shell aliases bypass any command parsing rules but for the early one: + + $ hg log -b '--config=alias.log=!echo howdy' + howdy + [defaults] $ hg cat a
--- a/tests/test-lfconvert.t Wed Nov 22 22:18:06 2017 +0800 +++ b/tests/test-lfconvert.t Thu Nov 30 15:48:42 2017 -0500 @@ -233,9 +233,10 @@ $ cd .. round-trip: converting back to a normal (non-largefiles) repo with -"lfconvert --to-normal" should give the same as ../bigfile-repo +"lfconvert --to-normal" should give the same as ../bigfile-repo. The +convert extension is disabled to show config items can be loaded without it. $ cd largefiles-repo - $ hg lfconvert --to-normal . ../normal-repo + $ hg --config extensions.convert=! lfconvert --to-normal . ../normal-repo initializing destination ../normal-repo 0 additional largefiles cached scanning source...
--- a/tests/test-merge-subrepos.t Wed Nov 22 22:18:06 2017 +0800 +++ b/tests/test-merge-subrepos.t Thu Nov 30 15:48:42 2017 -0500 @@ -61,7 +61,7 @@ 9bfe45a197d7+ tip $ cat .hg/blackbox.log * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> serve --cmdserver chgunix * (glob) (chg !) - * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> id (glob) + * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> id --config *extensions.blackbox=* --config *blackbox.dirty=True* (glob) * @9bfe45a197d7b0ab09bf287729dd57e9619c9da5+ (*)> id --config *extensions.blackbox=* --config *blackbox.dirty=True* exited 0 * (glob) TODO: a deleted file should be listed as such, like the top level repo
--- a/tests/test-setdiscovery.t Wed Nov 22 22:18:06 2017 +0800 +++ b/tests/test-setdiscovery.t Thu Nov 30 15:48:42 2017 -0500 @@ -17,7 +17,7 @@ > hg -R a debugdiscovery b --verbose --debug --config progress.debug=true > echo > echo "% -- b -> a tree" - > hg -R b debugdiscovery a --verbose --old --config + > hg -R b debugdiscovery a --verbose --old > echo > echo "% -- b -> a set" > hg -R b debugdiscovery a --verbose --debug --config progress.debug=true @@ -406,8 +406,8 @@ 101 102 103 104 105 106 107 108 109 110 (no-eol) $ hg -R r1 --config extensions.blackbox= blackbox * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> serve --cmdserver chgunix * (glob) (chg !) - * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> outgoing r2 *-T{rev} * (glob) + * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* (glob) * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> found 101 common and 1 unknown server heads, 2 roundtrips in *.????s (glob) * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* exited 0 after *.?? seconds (glob) - * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> blackbox (glob) + * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 --config *extensions.blackbox=* blackbox (glob) $ cd ..