This patch is meant to make it easier for tools that wrap the mercurial
output (such as TortoiseHg) to find the "in subrepo MYSUBREPO" string that
(since 6c419dfc848c) is appended after subrepo error messages, particularly when
the mercurial output is translated to a non-English language.
The message remains the same but the '%s' that was used to prepend the original
error message in front of the 'in subrepo' string has been moved out of the
translatable string.
As an example of the usefulness of making it easy to look for "in subrepo
MYSUBREPO" strings, TortoiseHg looks for these strings in error messages in
order to "linkify them" (i.e. convert "MYSUBREPO" into alink to the
corresponding subrepo).
The original string made it hard for a tool such as TortoiseHg to look for the
translated string on mercurial's output because the translated string contained
the error message itself. This meant that a regular expression was required to
ignore the error message part. With this change TortoiseHg can just get the
translated "(in subrepo %s)" string, substitute %s for the subrepo path (which
it gets from the subrepo exception) and simply search for the resulting string
(no regular expression needed, or at least a much simpler regular expression
could be used).
Additionaly, the existing string could lead a translator mistakenly assume that
it was possible invert the order of the %s (error and subrepo path) fields,
which would not work because the string interpolation was position based.
This change appends the subrepo path to subrepo errors. That is, when there
is an error performing an operation a subrepo, rather than displaying a message
such as:
pushing subrepo MYSUBREPO to PATH
searching for changes
abort: push creates new remote head HEADHASH!
hint: did you forget to merge? use push -f to force
mercurial will show:
pushing subrepo MYSUBREPO to PATH
searching for changes
abort: push creates new remote head HEADHASH! (in subrepo MYSUBREPO)
hint: did you forget to merge? use push -f to force
The rationale for this change is that the current error messages make it hard
for TortoiseHg (and similar tools) to tell the user which subrepo caused the
push failure.
The "(in subrepo MYSUBREPO)" message has been added to those subrepo methods
were it made sense (by using a decorator). We avoid appending "(in subrepo XXX)"
multiple times when subrepos are nexted by throwing a "SubrepoAbort" exception
after the extra message is appended. The decorator will then "ignore" (i.e. just
re-raise) the exception and never add the message again.
A small drawback of this method is that part of the exception trace is lost when
the exception is catched and re-raised by the annotatesubrepoerror decorator.
Also, because the state() function already printed the subrepo path when it
threw an error, that error has been changed to avoid duplicating the subrepo
path in the error message.
Note that I have also updated several subrepo related tests to reflect these
changes.
Color extension achieves colorization by overriding the class of
"ui" object just before command execution.
Before this patch, "diff()" of abstractsubrepo and classes
derived from it has no "ui" argument, so "diff()" of hgsubrepo
uses "self._repo.ui" to invoke "cmdutil.diffordiffstat()".
For separation of configuration between repositories, revision
1498948ee815 changed the initialization source of "self._repo.ui"
from "ui"(overridden) to "baseui"(plain) of parent repository.
And this caused break of colorization.
This patch adds "ui" argument to "diff()" of abstractsubrepo and
classes derived from it to pass "ui" object of caller side.
Files in a subrepo were overwritten on update. But this should only happen on a
clean update (example: -C is specified).
Use the overwrite parameter introduced for svn subrepos in e3640daa4703 to
decide whether to merge changes (as update) or remove them (as clean).
The new function hg.updaterepo is intruduced to keep all update calls in hg.
test-subrepo.t is extended to test if an untracked file is overwritten
(issue3276). (Update -C is already tested in many places.)
The first two chunks are debugging output which has changed. (Because overwrite
is not always true anymore for subrepos)
All other tests still pass without any change.
Do not pass ui because it contains the configuration of the repo. It is the
same object as repo.ui.
When a repo is passed to hg.peer, the global configuration is read from
repo.baseui.
Before this patch, repository local configurations are not isolated
between repositories in subrepo tree, because "localrepository"
objects for each subrepositories are created with "ui" instance of the
parent of each ones.
So, local configuration of the parent or higher repositories are
visible also in children or lower ones.
This patch uses "baseui" instead of "ui" to create repository object:
the former contains only global configuration.
This patch also copies 'ui.commitsubrepos' configuration to commit
recursively in subrepo tree, because it may be set in not
"repo.baseui" but "repo.ui".
svn --version --quiet is implemented since svn 0.14.1 (August 2002)
and prints just the version number, not the long output (21 lines)
of "svn --version".
Additionally I expect this output format to be more stable, at least
it is not changed with different translations.
For example LC_ALL=de_DE.utf-8 would cause the version check to fail,
because "svn, Version 1.6.12 (r955767)" with a capital "V" will be printed.
Using "svn --version --quiet" would only print the version number, but then
matching other messages, e.g. "Committed revision" would fail.
Subversion 1.7 changes its XML output to include an explicit encoding tag:
<?xml version="1.0" encoding="UTF-8"?>
This triggers xml.dom.minidom to always return unicode strings, causing
other parts of the code to explode.
We unconditionally encode path names before handing them back, which
works with both str (actually a no-op) and unicode values.
This introduces a peer method into all repository classes, which currently
simply returns self. It also changes hg.repository so it now raises an
exception if the supplied paths does not resolve to a localrepo or descendant.
Finally, all call sites are changed to use the peer and local methods as
appropriate, where peer is used whenever the code is dealing with a remote
repository (even if it's on local disk).
Add a match object to subrepo.archive(). This will allow the -X and -I
options to be honored inside subrepos when archiving. They formerly
only affect the top level repo.
dbc9f6aea991 introduced "svn info TARGET@REV" to determine if a certain
path exists in the specified revision, but in svn 1.5 the error message
"Not a valid URL" yields exit code 0 so the error is not caught.
Use "svn list TARGET@REV" instead which works with svn 1.5 and is even
faster in some situations.
Popen does not consider "foo.cmd" equivalent to "foo" on Windows.
Unfortunately, the default MSYS Git installation installs only "git.cmd" into
the path by default. This patch probes for both possible names on Windows.
Until now, when calling subrepo.subrepo with a path at which there is no
subrepo, a "nullstate" tuple would be returned. However, this is not very
useful (the tuple can't really be used for creating a subrepo), so we'd just as
soon have the function just fail, and leave it up to the caller to decide what
to do.
The motivation for doing this now is to simplify the solution for (issue3056).
Note that aborting in subrepo.state() prevents "repairing" commands like revert
to be issued. The user will have to edit the .hgsubstate manually (but he
probably had already otherwise this would not be failing). The same behaviour
already happens with invalid .hgsub entries.
The initial version was to take the "Revision" field from svn info. It works
but produces false positive when parent paths are being moved or unrelated
changes are being committed, causing it to change while the svn checkout itself
remains the same. To avoid spurious commit, we took "Revision" and "Last
Changed Rev" for general comparison and kept the latter to answer "what is your
revision?" question. This is better but fails when the subrepo path exists at
"Revision" but not at "Last Changed Rev". This patch adds a check for this, and
returns "Revision" if the path does not exist. We try to avoid doing this as
much as possible at it implies an extra, *remote* call.
Previous code was printing a traceback because it expected some error output
from svn. But sometimes our definition of "changed" differs with the subversion
one. For instance, subversion ignores missing files when committing. And when
there are only missing files, svn commit will be a successful no-op with no
output. Still, we should stick to our definition including missing files in
changes as doing otherwise could cause surprising behaviour for the user.
The warning is similar to the warning that was shown before hgsubrepo revert
support was added, with the exception that now the subrepo type is shown.
For example, when trying to revert a git subrepo located in "include/mygitsub",
the warning message would be:
include/mygitsub: reverting git subrepos is unsupported
- _svncommand() in files() returns a tuple since 1ca3bbcf0c2a not a string.
- _svncommand() in filedata() returns a tuple not a string.
- "svn list" returns files but also directories.
- "svn list" is not recursive by default.
I have no idea what happens to svn:externals possibly embedded in the svn
subrepository.
When a subrepo is reverted but --no-backup is not set, call revert on the
subrepo that is being reverted prior to updating it to the revision specified
in the parent repo's .hgsubstate file.
The --all flag is passed down to the subrepo when it is being reverted. If the
--all flag is not set, all files that are modified on the subrepo will be
reverted.
Reverting a subrepo is done by updating it to the revision that is selected on
the parent repo .hgsubstate file.
* ISSUES/TODO:
- reverting added and removed subrepos is not supported yet.
- reverting subrepos is only supported if the --no-backup flag is used (this
limitation will be removed on another patch).
- The behavior of the --all flag has been changed. It now reverts subrepos as
well. Note that this may lead to data loss if the user has a dirty subrepo.
Merging ancestors with children is allowed if they are on different
named branches. This did not work for subrepo merges before. To fix
this inconsistency, the mergefunc() will now use the simple update
path only if both versions are on the same named branch. If not, they
get merged into a new changeset, just as if you did the merge from the
subrepo's root directly.
When support for handling explicit paths in subrepos was added to the forget
command (155b89136ae7), subrepo recursion wasn't taken into account. This
change fixes that by pulling the majority of the logic of commands.forget into
cmdutil.forget, which can then be called from both there and subrepo.forget.
When support for handling explicit paths in subrepos was added to the add
command (825c4cefde4b), subrepo recursion wasn't taken into account. This
change adds an explicitonly argument to cmdutil.add to allow controlling which
levels of recursion should include only explicit paths versus all matched
paths.
path to subrepo is used to identify or check location of subrepo.
it should be normalized (in "/" delimiter form), because it is also
used with narrowmatcher which uses only normalized path even on
Windows environment.
this patch applies "util.pconvert()" on path to subrepo (called
"subpath") to normalize it.
for this patch, referers of below were checked.
- subrepo.state()
- subrepo.itersubrepos()
- subrepo.subrepo()
- context.sub()
- context.substate()
typical usecase is:
for subpath in ctx.substate:
sub = ctx.sub(subpath)
... ctx.substate[subpath] ....
in this case, normalization has no side effect, because keys given
from substate are used as key itself.
other cases shown below also seem to require subpath to be normalized.
- path components are joined by "/", in "commands.forget()":
for subpath in ctx.substate:
subforget[subpath + '/' + fsub] = (fsub, sub)
- normalized "file" is used to check below condition, in
"commands.revert()", "localrepository.commit()", and
"localrepository._checknested()"
file in ctx.substate
- substate.keys() is passed to dirstate.walk()/status() which use
only normalized pathes