d6f3cca7f3a5 is adding a new tar call but forgot to filter out the
pax_global_header file that some tar versions write. This is similar to what
happened in 686775e575f3.
Unix utilities like tar will happily prefix the files it packs with './', but
annoyingly, Windows Explorer will not show these packed files when it opens the
archive. Since there doesn't seem to be a point in including './' in the path
names, just drop it. The default 'hg archive' prefix is the basename of the
archive, so specifying '.' allows for that default to be disabled completely.
'git diff-index' by default does not recurse into subdirectories
when changes are found. As a result, the directory is shown as changed,
rather than the files in this directory.
Adding '-r' results in recursing until the blobs themselves are checked.
The previous behavior when archiving a subrepo 's' on Windows was to internally
name the file under it 's\file', due to the use of vfs.reljoin(). When printing
the file list from the archive on Windows or Linux, the file was named
's\\file'. The archive extracted OK on Windows, but if the archive was brought
to a Linux system, it created a file named 's\file' instead of a directory 's'
containing 'file'.
*.zip format achives seemed not to have the problem, but this was definitely an
issue with *.tgz archives.
Largefiles actually got this right, but a test is added to keep this from
regressing. The subrepo-deep-nested-change.t test was repurposed to archive to
a file, since there are several subsequent tests that archive to a directory.
The output change is losing the filesystem prefix '../archive_lf' and not
listing the directories 'sub1' and 'sub1/sub2'.
One case where that would happen is while trying to resolve a subrepo, if the
path to the subrepo was actually a broken symlink. This bug was exposed by an
hg-git test.
In git 2.2.0 and higher, removing files and directories is changed:
removing an object that does not exist returns success rather than failure.
As a result, even though .hg/hgrc does not exist, success is returned
and the .hg/ directory is removed.
To handle this correctly, use 'rm -rf' to allow successful removing
for all git versions.
The exact changeset where this was introduced in git:
1054af7d04aef64378d69a0496b45cdbf6a0bef2
wrapper.c: remove/unlink_or_warn: simplify, treat ENOENT as success
This follows normal Mercurial rules, and the message is lifted from
workingctx.add(). The file is printed with abs() to be consistent with how it
is printed in workingctx, even though that is inconsistent with how added files
are printed in verbose mode. Further, the 'already tracked' notifications come
after all of the files that are added are printed, like in Mercurial.
As a side effect, we now have the reject list to return to the caller, so that
'hg add' exits with the proper code. It looks like an abort occurs if git fails
to add the file. Prior to touching 'snake.python' in the test, this was the
result of attempting to add the file after a 'git rm':
fatal: pathspec 'snake.python' did not match any files
abort: git add error 128 in s (in subrepo s)
I'm not sure what happens when git is a deep subrepo, but the 'in s' and
'in subrepo s' from @annotatesubrepoerror are redundant here. Maybe we should
stat the files before invoking git to catch this case and print out the prettier
hg message? The other thing missing from workingctx.add() is the call to
scmutil.checkportable(), but that would need to borrow the parent's ui object.
The previous test gave a false success because only an hg-ignored pattern was
specified. Therefore match.files() was empty, and it fell back to the files
unknown to git. The simplest fix is to always consider what is unknown to git,
as well as anything specified explicitly. Files that are ignored by git can
only be introduced by an explicit mention in match.files().
V2: use 'self._ctx.node()' instead of 'rev' in makefileobj.
As Matt Harbison mentioned, using 'rev' does not make sense,
since we'd be passing a git revision to the top-level
Mercurial repository.
Previously, git subrepo diffs did not have a newline at the end.
This caused multiple subrepo diffs to be joined on the same line.
Additionally, the command prompt after the diff still contained
a part of the diff.
Previously, revert was only possible if the '--no-backup'
switch was specified.
Now, to support backups, we explicitly go over all modified
files in the subrepo.
'git diff --stat' output changed with regard to the amount
of changes/insertions/deletions shown.
In older git versions (1.7.7.6), output was shown as:
2 files changed, 2 insertions(+), 1 deletions(-)
In newer versions, output is shown as:
2 files changed, 2 insertions(+), 1 deletion(-)
This patch uses a regex to handle both cases.
Previously, git subrepos did not support reverting.
This change adds basic support for reverting
when '--no-backup' is specified.
A warning is given (and the current state is kept)
when a revert is done without the '--no-backup' flag.
The output of 'git diff --stat' changed in git 1.7.10 and 1.7.11.
To ensure the tests work with earlier versions of git as well,
the output is now wrapped with a whitespace regex.
So far, git subrepositories were silently ignored for diffs.
This patch adds support for git subrepositories,
with the remark that --include and --exclude are not supported.
If --include or --exclude are used, the subrepo is ignored.
Before this patch, sanitizing ".hg/hgrc" scans directories and files
also in meta data area for non-hg subrepos: under ".svn" for
Subversion subrepo, for example.
This may cause not only performance impact (especially in large scale
subrepos) but also unexpected removing meta data files.
This patch avoids sanitizing ".hg/hgrc" in meta data area for non-hg
subrepos.
This patch stops checking "ignore" target at the first
(case-insensitive) appearance of it, because continuation of scanning
is meaningless in almost all cases.
Before this patch, "hg update" doesn't sanitize ".hg/hgrc" in non-hg
subrepos correctly, if "hg update" is executed not at the root of the
parent repository.
"_sanitize()" takes relative path to subrepo from the root of the
parent repository, and passes it to "os.walk()". In this case,
"os.walk()" expects CWD to be equal to the root of the parent
repository.
So, "os.walk()" can't find specified path (or may scan unexpected
path), if CWD isn't equal to the root of the parent repository.
Non-hg subrepo under nested hg-subrepos may cause same problem, too:
CWD may be equal to the root of the outer most repository, or so.
This patch makes "_sanitize()" take absolute path to the root of
subrepo to sanitize correctly in such cases.
This patch doesn't normalize the path to hostile files as the one
relative to CWD (or the root of the outer most repository), to fix the
problem in the simple way suitable for "stable".
Normalizing should be done in the future: maybe as a part of the
migration to vfs.
Before this patch, sanitizing ".hg/hgrc" in git subrepo doesn't work,
when the working directory is updated by "git merge --ff".
"_sanitize()" is not invoked after checking target revision out into
the working directory in this case, even though it is invoked
indirectly via "checkout" (or "rawcheckout") in other cases.
This patch invokes "_sanitize()" explicitly also after "git merge
--ff" execution.
"_sanitize()" was introduced by 5131f2755f60 on "stable" branch, but
it has done nothing for sanitizing since 5131f2755f60.
"_sanitize()" assumes "Visitor" design pattern:
"os.walk()" should invoke specified function ("v" in this case)
for each directory elements under specified path
but "os.walk()" assumes "Iterator" design pattern:
callers of it should drive loop to scan each directory elements
under specified path by themselves with the returned generator
object
Because of this mismatching, "_sanitize()" just discards the generator
object returned by "os.walk()" and does nothing for sanitizing.
This patch makes "_sanitize()" work.
This patch also changes the format of warning message to show each
unlinked files, for multiple appearances of "potentially hostile
.hg/hgrc".
When a subrepo has changed on the local and remote revisions, prompt the user
whether it wants to merge those subrepo revisions, keep the local revision or
keep the remote revision.
Up until now mercurial would always perform a merge on a subrepo that had
changed on the local and the remote revisions. This is often inconvenient. For
example:
- You may want to perform the actual subrepo merge after you have merged the
parent subrepo files.
- Some subrepos may be considered "read only", in the sense that you are not
supposed to add new revisions to them. In those cases "merging a subrepo" means
choosing which _existing_ revision you want to use on the merged revision. This
is often the case for subrepos that contain binary dependencies (such as DLLs,
etc).
This new prompt makes mercurial better cope with those common scenarios.
Notes:
- The default behavior (which is the one that is used when ui is not
interactive) remains unchanged (i.e. merge is the default action).
- This prompt will be shown even if the ui --tool flag is set.
- I don't know of a way to test the "keep local" and "keep remote" options (i.e.
to force the test to choose those options).
# HG changeset patch
# User Angel Ezquerra <angel.ezquerra@gmail.com>
# Date 1378420708 -7200
# Fri Sep 06 00:38:28 2013 +0200
# Node ID 2fb9cb0c7b26303ac3178b7739975e663075857d
# Parent 796d34e1b749b79834321ef1181ed8433a5515d9
merge: let the user choose to merge, keep local or keep remote subrepo revisions
When a subrepo has changed on the local and remote revisions, prompt the user
whether it wants to merge those subrepo revisions, keep the local revision or
keep the remote revision.
Up until now mercurial would always perform a merge on a subrepo that had
changed on the local and the remote revisions. This is often inconvenient. For
example:
- You may want to perform the actual subrepo merge after you have merged the
parent subrepo files.
- Some subrepos may be considered "read only", in the sense that you are not
supposed to add new revisions to them. In those cases "merging a subrepo" means
choosing which _existing_ revision you want to use on the merged revision. This
is often the case for subrepos that contain binary dependencies (such as DLLs,
etc).
This new prompt makes mercurial better cope with those common scenarios.
Notes:
- The default behavior (which is the one that is used when ui is not
interactive) remains unchanged (i.e. merge is the default action).
- This prompt will be shown even if the ui --tool flag is set.
- I don't know of a way to test the "keep local" and "keep remote" options (i.e.
to force the test to choose those options).
The test didn't break when I originally committed it (git version
1.7.12.4 (Apple Git-37)), and still doesn't on that machine, but the
output changes elsewhere with "Warning: you are leaving N commits
behind..."
This change sets a ref on the commit we're updating the subrepo _away_
from to quash the warning.
We were always using only the first 12 characters of the subrepo revision id
when generating the "subrepo diverged" promptchoice. This is not necessarily
correct for non mercurial subrepos.
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.
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.
hg forget 'notafile*' is changed to use a name that is valid on Windows so we
still get the same error ... but the error message is disabled because it
varies with the Windows version.
Many tests didn't change back from subdirectories at the end of the tests ...
and they don't have to. The missing 'cd ..' could always be added when another
test case is added to the test file.
This change do that tests (99.5%) consistently end up in $TESTDIR where they
started, thus making it simpler to extend them or move them around.
git version 1.7.9.1 makes the testsuite fail with:
@@ -482,7 +482,17 @@
Sticky repository, update --clean
$ hg update --clean tip
- Previous HEAD position was aa84837... f
+ Warning: you are leaving 2 commits behind, not connected to
+ any of your branches:
+
+ aa84837 f
+ 126f2a1 gg
+
+ If you want to keep them by creating a new branch, this may be a good time
+ to do so with:
+
+ git branch new_branch_name aa84837ccfbdfedcdcdeeedc309d73e6eb069edc
+
HEAD is now at 32a3438... fff
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg id -n
ERROR: test-subrepo-git.t output changed
When the contents of .hgsubstate are stale (either because they've
manually been tweaked or partial updates have confused it), we get
confused about whether it actually needs committing.
So instead, we actively consult the parent's substate and compare it
the actual current state when deciding whether it needs committing.
Side effect: lots of "committing subrepo" messages that didn't
correspond with real commits disappear.
This change is fairly invasive for a fairly obscure condition, so it's
kept on the default branch.