Before this patch, manually edited commit message for "message"
command in histedit-ing is not saved into ".hg/last-message.txt" until
it is saved by "localrepository.savecommitmessage()" in
"localrepository.commit()".
This may lose such commit message, if unexpected exception is raised.
This patch saves manually edited commit message for "message" comand
in histedit-ing into ".hg/last-message.txt" just after user editing.
This is the simplest implementation to fix on stable. Editing and
saving commit message should be centralized into the framework of
"localrepository.commit()" with "editor" argument in the future.
This patch uses repository wrapping class for exception raising before
saving commit message in "localrepository.commit()" easily and
certainly, because such exception requires corner case condition.
Python uses a C long (32 bits on Windows 64) rather than an ssize_t in
read(), and thus has a 2G size limit. Work around this by falling back
to reading one chunk at a time on overflow. This approximately doubles
our headroom until we run back into the size limit on single reads.
If backout generated no changes to commit, it showed wrong status, "changeset
<target> backs out changeset <target>", and raised TypeError with -v option.
This changes the return code to 1, which is the same as "hg commit" and
"hg rebase".
Before this patch, "contrib/check-code.py" can't detect these
problems, because the regexp pattern to detect "% inside _()" doesn't
suppose the case that format string consists of multiple string
components concatenated implicitly or explicitly,
This patch does below for that regexp pattern to detect "% inside _()"
problems in such case.
- put "+" into separator part ("[ \t\n]") for explicit concatenation
("...." + "...." style)
- enclose "component and separator" part by "(?:....)+" for
concatenation itself ("...." "...." or "...." + "....")
Before this patch, "contrib/check-code.py" can't detect these
problems, because the regexp pattern to detect "% inside _()" doesn't
suppose the case that the format string and "%" aren't placed in the
same line.
This patch replaces "\s" in that regexp pattern with "[ \t\n]" to
detect "% inside _()" problems in such case.
"[\s\n]" can't be used in this purpose, because "\s" is automatically
replaced with "[ \t]" by "_preparepats()" and "\s" in "[]" causes
nested "[]" unexpectedly.
In d87f1c1d18fa, be4d37a43992, 394118f2cf71, and 7594c2ea371e, new tests were
added that used TESTDIR instead of TESTTMP thereby leading to polluting the
working directory with these temporary files. Now, we use TESTTMP so that they
will be cleaned up properly.
Since changeset a8955c4d9ef5, "reposetup()" of each extensions is
invoked only on repositories enabling corresponded extensions.
This causes that largefiles specific interactions between the
repository enabling largefiles locally and remote (wire) peer fail,
because there is no way to know whether largefiles is enabled on the
remote repository behind the wire peer, and largefiles specific
"wireproto functions" are not given to any wire peers.
To avoid this problem, largefiles should be enabled in wider scope
than each repositories (e.g. user-wide "${HOME}/.hgrc").
This patch introduces "wirepeersetupfuncs" to setup wire peer by
extensions already enabled. Functions registered into
"wirepeersetupfuncs" are invoked for all wire peers.
This patch uses plain list instead of "util.hooks" for
"wirepeersetupfuncs", because the former allows to control order of
function invocation by order of extension enabling: it may be useful
for workaround of problems with combination of enabled extensions
Previously, if a template '{foo()}' was given, the buildfunc would not be able
to match it and hit a code path that would not return so it would error out
later in the templater stating that NoneType was not iterable. This patch makes
sure that a proper error is raised so that the user can be informed.
Tests have been updated.
When having ui.debugger=somedebugger in one's ~/.hgrc, this then
somedebugger would be imported for every hg command. With this patch,
this import only happens if the --debugger parameter is passed.
Changset 39a4d61c40d6 rewriting "hg.copystore()" with vfs uses
'dstbase + "/lock"' instead of "os.path.join()", because target files
given from "store.copyfiles()" already uses "/" as path separator
But in the repository using revlog format 0, "dstbase" becomes empty
("data" directory is located under ".hg" directly), and 'dstbase +
"/lock"' is treated as "/lock": in almost all cases, write access to
"/lock" causes "permission denied".
This patch uses "os.path.join()" to join path components which may be
empty in "hg.copystore()".
Before this patch, `hg commit --secret` was not getting propagated
correctly, and subrepos were not getting the commit in the secret
phase. The problem is that subrepos get their ui from the base repo's
baseui object and ignore the ui object passed on to them. This sets
and restores both ui objects with the appropriate option.
Before this patch, commit message (may be manually edited) for "commit
--amend" is never saved into ".hg/last-message.txt", because it uses
"localrepository.commitctx()" instead of "localrepository.commit()":
saving into ".hg/last-message.txt" is executed only in the latter.
This patch saves commit message for "commit --amend" into
".hg/last-message.txt" just after user editing.
This is the simplest implementation to fix on stable. Editing and
saving commit message for memctx should be centralized into the
framework like "localrepository.commit()" with "editor" argument or so
in the future.
Before this patch, manually edited commit message for "fold" command
in histedit-ing is never saved into ".hg/last-message.txt", because it
uses "localrepository.commitctx()" instead of
"localrepository.commit()": saving into ".hg/last-message.txt" is
executed only in the latter.
This patch saves manually edited commit message for "fold" command in
histedit-ing into ".hg/last-message.txt" just after user editing.
This is the simplest implementation to fix on stable. Editing and
saving commit message for memctx should be centralized into the
framework like "localrepository.commit()" with "editor" argument or so
in the future.
Before this patch, manually edited commit message for "hg qfold -e"
isn't saved into ".hg/last-message.txt" until it is saved by
"localrepository.savecommitmessage()" in "localrepository.commit()".
This may lose such commit message, if unexpected exception is raised.
This patch saves manually edited commit message for "hg qfold -e" into
".hg/last-message.txt" just after user editing. This patch doesn't
save the message specified by -m/-l options as same as other commands.
This is the simplest implementation to fix on stable. Editing and
saving commit message should be centralized into the framework of
"localrepository.commit()" with "editor" argument in the future.
This patch uses repository wrapping class for exception raising before
saving commit message in "localrepository.commit()" easily and
certainly, because such exception requires corner case condition.
Before this patch, manually edited commit message for "hg qnew -e"
isn't saved into ".hg/last-message.txt" until it is saved by
"localrepository.savecommitmessage()" in "localrepository.commit()".
This may lose such commit message, if unexpected exception is raised.
This patch saves manually edited commit message for "hg qnew -e" into
".hg/last-message.txt" just after user editing. This patch doesn't
save the message specified by -m/-l options as same as other commands.
This is the simplest implementation to fix on stable. Editing and
saving commit message should be centralized into the framework of
"localrepository.commit()" with "editor" argument in the future.
This patch uses repository wrapping class for exception raising before
saving commit message in "localrepository.commit()" easily and
certainly, because such exception requires corner case condition.
Before this patch, manually edited commit message for "hg tag -e"
isn't saved into ".hg/last-message.txt" until it is saved by
"localrepository.savecommitmessage()" in "localrepository.commit()".
This may lose such commit message, if unexpected exception is raised.
This patch saves manually edited commit message for "hg tag -e" into
".hg/last-message.txt" just after user editing. This patch doesn't
save the message specified by -m option (-l is not supported for "hg
tag") as same as other commands.
This is the simplest implementation to fix on stable. Editing and
saving commit message should be centralized into the framework of
"localrepository.commit()" with "editor" argument in the future.
Before this patch, "rebase --collapse --edit" without "--message" and
"--logfile" invokes editor twice unexpectedly:
1. explicit "ui.edit()" invocation in rebase extension itself
2. indirect invocation in "localrepository.commit()" with "editor =
commitforceeditor" assigned by "--edit" option
This patch uses indirect "commitforceeditor" invocation instead of
"ui.edit()" for "--collapse" without "--message" and "--logfile" to:
- suppress redundant the former invocation
- ensure editor invocation even when "--edit" is not specified
Before this patch, "localrepository.commit()" invokes specified
"editor" to edit commit message manually, and saves it after checking
sub-repositories.
This may lose manually edited commit message, if unexpected exception
is raised while checking (or commiting recursively) sub-repositories.
This patch saves manually edited commit message as soon as possible.
Before this patch, "hg commit --amend --secret" doesn't create new
amend changeset as secret, even though the internal function
"commitfunc()" passed to "cmdutil.amend()" make "phases.new-commit"
configuration as "secret" temporarily.
"cmdutil.amend()" uses specified "commitfunc" only for temporary amend
commit, and creates the final amend commit changeset by
"localrepository.commitctx()" directly with memctx.
This patch creates new amend changeset as secret correctly for
"--secret" option, by changing "phases.new-commit" configuration
temporarily before "localrepository.commitctx()".
Changeset 83ff877959a6 (released with 2.8.1) fixed "recursively
evaluate string literals as templates" problem (issue4102) by moving
the location of "string-escape"-ing from "tokenizer()" to
"compiletemplate()".
But some parts in template expressions below are not processed by
"compiletemplate()", and it may cause unexpected result.
- 'expr' of 'if(expr, then, else)'
- 'expr's of 'ifeq(expr, expr, then, else)'
- 'sep' of 'join(list, sep)'
- 'text' and 'style' of 'rstdoc(text, style)'
- 'text' and 'chars' of 'strip(text, chars)'
- 'pat' and 'repl' of 'sub(pat, repl, expr)'
For example, '\n' of "{join(extras, '\n')}" is not "string-escape"-ed
and treated as a literal '\n'. This breaks "Display the contents of
the 'extra' field, one per line" example in "hg help templates".
Just "string-escape"-ing on each parts above may not work correctly,
because inside expression of nested ones already applies
"string-escape" on string literals. For example:
- "{join(files, '\n')}" doesn't return "string-escape"-ed string, but
- "{join(files, if(branch, '\n', '\n'))}" does
To fix this problem, this patch does:
- introduce "rawstring" token and "runrawstring" method to handle
strings not to be "string-escape"-ed correctly, and
- make "runstring" method return "string-escape"-ed string, and
delay "string-escape"-ing until evaluation
This patch invokes "compiletemplate()" with "strtoken=exp[0]" in
"gettemplate()", because "exp[1]" is not yet evaluated. This code path
is tested via mapping ("expr % '{template}'").
In the other hand, this patch invokes it with "strtoken='rawstring'"
in "_evalifliteral()", because "t" is the result of "arg" evaluation
and it should be "string-escape"-ed if "arg" is "string" expression.
This patch doesn't test "string-escape"-ing on 'expr' of 'if(expr,
then, else)', because it doesn't affect the result.
Templating syntax allows nested expression to be specified as parts
below, but they are evaluated as a generator and don't work correctly.
- 'sep' of 'join(list, sep)'
- 'text' and 'chars' of 'strip(text, chars)'
In the former case, 'sep' returns expected string only for the first
separation, and empty one for the second or later, because the
generator has only one element.
In the latter case, templating is aborted by exception, because the
generator doesn't have 'strip()' method (as 'text') and can't be
passed as the argument to 'str.strip()' (as 'chars').
This patch applies "stringify()" on these sub expression to get string
correctly.
Changeset c84f81c3e120 (released with 2.8.1) fixed "recursively
evaluate string literals as templates" problem (issue4103) by
introducing "_evalifliteral()".
But some parts in template expressions below are still processed by
the combination of "compiletemplate()" and "runtemplate()", and may
cause same problem unexpectedly.
- 'init' and 'hang' of 'fill(text, width, init, hang)'
- 'expr' of 'sub(pat, repl, expr)'
- 'label' of 'label(label, expr)'
This patch processes them by "_evalifliteral()" instead of the
combination of "compiletemplate()" and "runtemplate()" to avoid
recursive evaluation of string literals completely.
We can use the "other" data from the recorded merge state instead of inferring
what the other could be from working copy parent. This will allow resolve to
fulfil its duty even when the second parent have been dropped.
Most direct benefit is fixing a regression in backout.
This data is mostly redundant with the "other" changeset node (+ other changeset
file path). However, more data never hurt.
The old format do not store it so this require some dancing to add and remove it
on demand.
When we have to fallback to the old version of the file, we infer the
"other" from current working directory parent. The same way it is currently done
in the resolve command. This is know to have shortcoming… but we cannot do
better from the data contained in the old file format. This is actually the
motivation to add this new file format.
We need to record the merge we were merging with. This solve multiple
bug with resolve when dropping the second parent after a merge. This
happen a lot when doing special merge (overriding the ancestor).
Backout, shelve, rebase, etc. can takes advantage of it.
This changeset just add the information in the merge state. We'll use it in the
resolve process in a later changeset.
This new format will allow us to address common bugs while doing special merge
(graft, backout, rebase…) and record user choice during conflict resolution.
The format is open so we can add more record for future usage.
This file still store hexified version of node to help human willing to debug
it by hand. The overhead or oversize are not expected be an issue.
The old format is still used. It will be written to disk along side the newer
format. And at parse time we detect if the data from old version of the
mergestate are different from the one in the new version file. If its the same,
both have most likely be written at the same time and you can trust the extra
data from the new file. If it differs, the old file have been written by an
older version of mercurial that did not knew about the new file. In that case we
use the content of the old file.