Commit Graph

11783 Commits

Author SHA1 Message Date
Johannes Schindelin
eaf29602ef Merge pull request #994 from jeffhostetler/jeffhostetler/fscache_nfd
fscache: add not-found directory cache to fscache
2017-04-26 17:39:46 +02:00
Johannes Schindelin
82143fade3 t5580: verify that alternates can be UNC paths
On Windows, UNC paths are a very convenient way to share data, and
alternates are all about sharing data.

We fixed a bug where alternates specifying UNC paths were not handled
properly, and it is high time that we add a regression test to ensure
that this bug is not reintroduced.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 17:39:40 +02:00
Johannes Schindelin
328dc9a1fb t9001: work around hard-to-debug hangs
Just like the workaround we added for t9116, t9001.83 hangs sometimes --
but not always! -- when being run in the Git for Windows SDK.

The issue seems to be related to redirection via a pipe, but it is really
hard to diagnose, what with git.exe (a non-MSYS2 program) calling a Perl
script (which is executed by an MSYS2 Perl), piping into another MSYS2
program.

As hunting time is scarce these days, simply work around this for now and
leave the real diagnosis and resolution for later.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 17:39:39 +02:00
Johannes Schindelin
57c1ac75c9 t9116: work around hard-to-debug hangs
As of a couple of weeks ago, t9116 hangs sometimes -- but not always! --
when being run in the Git for Windows SDK.

The issue seems to be related to redirection via a pipe, but it is really
hard to diagnose, what with git.exe (a non-MSYS2 program) calling a Perl
script (which is executed by an MSYS2 Perl), piping into another MSYS2
program.

As hunting time is scarce these days, simply work around this for now and
leave the real diagnosis and resolution for later.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 17:39:39 +02:00
Johannes Schindelin
0626acfdd7 Merge branch 'interactive-rebase-current'
This series of branches introduces the git-rebase--helper, a builtin
helping to accelerate the interactive rebase dramatically.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 17:39:39 +02:00
Segev Finer
155bd38f1f connect: Add the envvar GIT_SSH_VARIANT and ssh.variant config
This environment variable and configuration value allow to
override the autodetection of plink/tortoiseplink in case that
Git gets it wrong.

[jes: wrapped overly-long lines, factored out and changed
get_ssh_variant() to handle_ssh_variant() to accomodate the
change from the putty/tortoiseplink variables to
port_option/needs_batch, adjusted the documentation, free()d
value obtained from the config.]

Signed-off-by: Segev Finer <segev208@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 17:39:17 +02:00
Segev Finer
ca55277637 connect: handle putty/plink also in GIT_SSH_COMMAND
Git for Windows has special support for the popular SSH client PuTTY:
when using PuTTY's non-interactive version ("plink.exe"), we use the -P
option to specify the port rather than OpenSSH's -p option. TortoiseGit
ships with its own, forked version of plink.exe, that adds support for
the -batch option, and for good measure we special-case that, too.

However, this special-casing of PuTTY only covers the case where the
user overrides the SSH command via the environment variable GIT_SSH
(which allows specifying the name of the executable), not
GIT_SSH_COMMAND (which allows specifying a full command, including
additional command-line options).

When users want to pass any additional arguments to (Tortoise-)Plink,
such as setting a private key, they are required to either use a shell
script named plink or tortoiseplink or duplicate the logic that is
already in Git for passing the correct style of command line arguments,
which can be difficult, error prone and annoying to get right.

This patch simply reuses the existing logic and expands it to cover
GIT_SSH_COMMAND, too.

Note: it may look a little heavy-handed to duplicate the entire
command-line and then split it, only to extract the name of the
executable. However, this is not a performance-critical code path, and
the code is much more readable this way.

Signed-off-by: Segev Finer <segev208@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 17:39:16 +02:00
Johannes Schindelin
c1dca8fe87 Merge branch 'jh/string-list-micro-optim'
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 17:37:58 +02:00
Johannes Schindelin
c59781de15 Merge branch 'jh/add-index-entry-optim'
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 17:36:49 +02:00
Johannes Schindelin
95447ea3c1 fscache: add a test for the dir-not-found optimization
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:59:02 +02:00
Johannes Schindelin
730f6138e2 rebase -i: rearrange fixup/squash lines using the rebase--helper
This operation has quadratic complexity, which is especially painful
on Windows, where shell scripts are *already* slow (mainly due to the
overhead of the POSIX emulation layer).

Let's reimplement this with linear complexity (using a hash map to
match the commits' subject lines) for the common case; Sadly, the
fixup/squash feature's design neglected performance considerations,
allowing arbitrary prefixes (read: `fixup! hell` will match the
commit subject `hello world`), which means that we are stuck with
quadratic performance in the worst case.

The reimplemented logic also happens to fix a bug where commented-out
lines (representing empty patches) were dropped by the previous code.

While at it, clarify how the fixup/squash feature works in `git rebase
-i`'s man page.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:43 +02:00
Johannes Schindelin
e36215d28e t3415: test fixup with wrapped oneline
The `git commit --fixup` command unwraps wrapped onelines when
constructing the commit message, without wrapping the result.

We need to make sure that `git rebase --autosquash` keeps handling such
cases correctly, in particular since we are about to move the autosquash
handling into the rebase--helper.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:43 +02:00
Johannes Schindelin
6969ef475f t3404: relax rebase.missingCommitsCheck tests
These tests were a bit anal about the *exact* warning/error message
printed by git rebase. But those messages are intended for the *end
user*, therefore it does not make sense to test so rigidly for the
*exact* wording.

In the following, we will reimplement the missing commits check in
the sequencer, with slightly different words.

So let's just test for the parts in the warning/error message that
we *really* care about, nothing more, nothing less.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:42 +02:00
Johannes Schindelin
97d286af36 rebase -i: use the rebase--helper builtin
Now that the sequencer learned to process a "normal" interactive rebase,
we use it. The original shell script is still used for "non-normal"
interactive rebases, i.e. when --root or --preserve-merges was passed.

Please note that the --root option (via the $squash_onto variable) needs
special handling only for the very first command, hence it is still okay
to use the helper upon continue/skip.

Also please note that the --no-ff setting is volatile, i.e. when the
interactive rebase is interrupted at any stage, there is no record of
it. Therefore, we have to pass it from the shell script to the
rebase--helper.

Note: the test t3404 had to be adjusted because the the error messages
produced by the sequencer comply with our current convention to start with
a lower-case letter.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:41 +02:00
Jeff Hostetler
c4ad680d66 string-list: use ALLOC_GROW macro when reallocing string_list
Use ALLOC_GROW() macro when reallocing a string_list array
rather than simply increasing it by 32.  This is a performance
optimization.

During status on a very large repo and there are many changes,
a significant percentage of the total run time is spent
reallocing the wt_status.changes array.

This change decreases the time in wt_status_collect_changes_worktree()
from 125 seconds to 45 seconds on my very large repository.

This produced a modest gain on my 1M file artificial repo, but
broke even on linux.git.

Test                                            HEAD^^            HEAD
---------------------------------------------------------------------------------------
0005.2: read-tree status br_ballast (1000001)   8.29(5.62+2.62)   8.22(5.57+2.63) -0.8%

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-26 16:58:30 +02:00
Johannes Schindelin
c14b80f64d Merge branch 'visual-studio'
This topic branch teaches the project generator to generate a Visual
Studio solution, ready to be opened in Visual Studio 2010 or later.

The idea, of course, is to let some automatic build job generate and
commit the project files with

	make MSVC=1 vcxproj

and then (force-)push to a special-purpose branch.

The major part of this branch thicket concerns itself not only with
generating the Visual Studio project files, but making sure that the
user can then run the test suite from a regular Git Bash (i.e. *not*
requiring a Git for Windows SDK), e.g. by running

	cd t
	prove --timer --jobs 15 ./t[0-9]*.sh

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:28 +02:00
Johannes Schindelin
433f3dfd3a Merge branch 'reset-stdin'
This topic branch adds the (experimental) --stdin/-z options to `git
reset`. Those patches are still under review in the upstream Git project,
but are already merged in their experimental form into Git for Windows'
`master` branch, in preparation for a MinGit-only release.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:26 +02:00
Johannes Schindelin
77ec3d19c9 Unbreak interactive GPG prompt upon signing
With the recent update in efee955 (gpg-interface: check gpg signature
creation status, 2016-06-17), we ask GPG to send all status updates to
stderr, and then catch the stderr in an strbuf.

But GPG might fail, and send error messages to stderr. And we simply
do not show them to the user.

Even worse: this swallows any interactive prompt for a passphrase. And
detaches stderr from the tty so that the passphrase cannot be read.

So while the first problem could be fixed (by printing the captured
stderr upon error), the second problem cannot be easily fixed, and
presents a major regression.

So let's just revert commit efee9553a4.

This fixes https://github.com/git-for-windows/git/issues/871

Cc: Michael J Gruber <git@drmicha.warpmail.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:25 +02:00
Johannes Schindelin
ca715bedd0 Merge branch 'unhidden-git'
It has been reported that core.hideDotFiles=false stopped working...
This topic branch fixes it.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:24 +02:00
Johannes Schindelin
21453f7909 Merge branch 'status-no-lock-index'
This branch allows third-party tools to call `git status
--no-lock-index` to avoid lock contention with the interactive Git usage
of the actual human user.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:23 +02:00
Johannes Schindelin
a9f6746e02 Merge pull request #797 from glhez/master
`git bundle create <bundle>` leaks handle the revlist is empty.
2017-04-26 16:58:23 +02:00
Jeff Hostetler
e61c40a8af p0006-read-tree-checkout: perf test to time read-tree
Created t/perf/repos/many-files.sh to generate large, but
artificial repositories.

Created t/perf/inflate-repo.sh to alter an EXISTING repo
to have a set of large commits.  This can be used to create
a branch with 1M+ files in repositories like git.git or
linux.git, but with more realistic content.  It does this
by making multiple copies of the entire worktree in a series
of sub-directories.

The branch name and ballast structure created by both scripts
match, so either script can be used to generate very large
test repositories for the following perf test.

Created t/perf/p0006-read-tree-checkout.sh to measure
performance on various read-tree, checkout, and update-index
operations.  This test can run using either normal repos or
ones from the above scripts.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-26 16:58:20 +02:00
Jeff Hostetler
56bbc37826 read-cache: add strcmp_offset function
Add strcmp_offset() function to also return the offset of the
first change.

Add unit test and helper to verify.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-26 16:58:20 +02:00
Johannes Schindelin
e5bd8bdb08 Merge 'misc-vs-fixes' into HEAD 2017-04-26 16:58:17 +02:00
Johannes Schindelin
1fc93d3abe msvc: fix make test without having to play PATH games
When building with Microsoft Visual C, we use NuGet to acquire the
dependencies (such as OpenSSL, cURL, etc). We even unpack those
dependencies.

This patch teaches the test suite to add the directory with the unpacked
.dll files to the PATH before running the tests.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:16 +02:00
Johannes Schindelin
af06fdb2d5 t5505,t5516: create .git/branches/ when needed
It is a real old anachronism from the Cogito days to have a
.git/branches/ directory. And to have tests that ensure that Cogito
users can migrate away from using that directory.

But so be it, let's continue testing it.

Let's make sure, however, that git init does not need to create that
directory.

This bug was noticed when testing with templates that had been
pre-committed, skipping the empty branches/ directory of course because
Git does not track empty directories.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:11 +02:00
Johannes Schindelin
382026b9c9 reset: support the experimental --stdin option
Just like with other Git commands, this option makes it read the paths
from the standard input. It comes in handy when resetting many, many
paths at once and wildcards are not an option (e.g. when the paths are
generated by a tool).

Note: we first parse the entire list and perform the actual reset action
only in a second phase. Not only does this make things simpler, it also
helps performance, as do_diff_cache() traverses the index and the
(sorted) pathspecs in simultaneously to avoid unnecessary lookups.

This feature is marked experimental because it is still under review in
the upstream Git project.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:06 +02:00
Johannes Schindelin
cfc3bd7683 mingw: respect core.hidedotfiles = false in git-init again
This is a brown paper bag. When adding the tests, we actually failed
to verify that the config variable is heeded in git-init at all. And
when changing the original patch that marked the .git/ directory as
hidden after reading the config, it was lost on this developer that
the new code would use the hide_dotfiles variable before the config
was read.

The fix is obvious: read the (limited, pre-init) config *before*
creating the .git/ directory.

This fixes https://github.com/git-for-windows/git/issues/789

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:04 +02:00
Johannes Schindelin
5bb7063672 status: offer *not* to lock the index and update it
When a third-party tool periodically runs `git status` in order to keep
track of the state of the working tree, it is a bad idea to lock the
index: it might interfere with interactive commands executed by the
user, e.g. when the user wants to commit files.

Let's introduce the option `--no-lock-index` to prevent such problems.
The idea is that the third-party tool calls `git status` with this
option, preventing it from ever updating the index.

The downside is that the periodic `git status` calls will be a little
bit more wasteful because they may have to refresh the index repeatedly,
only to throw away the updates when it exits. This cannot really be
helped, though, as tools wanting to get a periodic update of the status
have no way to predict when the user may want to lock the index herself.

Note that the regression test added in this commit does not *really*
verify that no index.lock file was written; that test is not possible in
a portable way. Instead, we verify that .git/index is rewritten *only*
when `git status` is run without `--no-lock-index`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:58:03 +02:00
Gaël Lhez
419904f654 git bundle create <bundle> leaks handle the revlist is empty.
issue #790: git bundle create does not close handle to *.lock file

This problem happens when an user tries to create an empty bundle, using the
following command:  `git bundle create <bundle> <revlist>` and when <revlist>
resolve to an empty list (for example, like `master..master`), `git bundle` fails
and warn the user about how it don't want to create empty bundle.

In that case, git tries to delete the `<bundle>.lock` file, and since there's still
an open file handle, fails to do so and ask the user if it should retry (which will
fail again).

The lock can still be deleted manually by the user (and it is required if the user
want to create a bundle after revising his rev-list).

Signed-off-by: Gaël Lhez <gael.lhez@gmail.com>
2017-04-26 16:58:02 +02:00
Johannes Schindelin
f073b6bd94 Merge branch 'clean-long-paths'
This addresses https://github.com/git-for-windows/git/issues/521

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:58 +02:00
Johannes Schindelin
219e22ebdb Merge pull request #773 from jeffhostetler/vs2015
Build with VS2015
2017-04-26 16:57:46 +02:00
Johannes Schindelin
52c59930a3 Merge pull request #305 from dscho/msysgit_issues_182
Allow `add -p` and `add -i` with a large number of files
2017-04-26 16:57:45 +02:00
Johannes Schindelin
3e301cc622 Merge 'remote-hg-prerequisites' into HEAD
These fixes were necessary for Sverre Rabbelier's remote-hg to work,
but for some magic reason they are not necessary for the current
remote-hg. Makes you wonder how that one gets away with it.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:41 +02:00
Johannes Schindelin
37cb6383cc Merge 'win-tests-fixes' into HEAD 2017-04-26 16:57:40 +02:00
Johannes Schindelin
470f50010f Merge 'msys2' into HEAD
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:40 +02:00
Johannes Schindelin
b77576e094 Merge 'jberezanski/wincred-sso-r2' into HEAD 2017-04-26 16:57:39 +02:00
Johannes Schindelin
d5ec29e5ff t7300: git clean -dfx must show an error with long paths
In particular on Windows, where the default maximum path length is quite
small, but there are ways to circumvent that limit in many cases, it is
very important that users be given an indication why their command
failed because of too long paths when it did.

This test case makes sure that a warning is issued that would have
helped the user who reported Git for Windows' issue 521:

	https://github.com/git-for-windows/git/issues/521

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:33 +02:00
Johannes Schindelin
a8da631c06 t7800: fix quoting
When passing a command-line to call an external diff command to the
difftool, we must be prepared for paths containing special characters,
e.g. backslashes in the temporary directory's path on Windows.

This has been caught by running the test suite with an MSVC-built Git:
in contrast to the MINGW one, it does not rewrite `$TMP` to use forward
slashes instead of backslashes.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:30 +02:00
Johannes Schindelin
2a76b81d49 Merge branch 'redirect-std-handles'
This topic branch introduces a highly-experimental feature allowing to
override stdin/stdout/stderr by setting environment variables e.g. to
named pipes, solving a problem in highly multi-threaded applications
where inheritable handles could cause blocked Git operations.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:27 +02:00
Johannes Schindelin
a16080faa0 t3701: verify that we can add *lots* of files interactively
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:26 +02:00
Sverre Rabbelier
0c34a30843 remote-helper: check helper status after import/export
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>
2017-04-26 16:57:15 +02:00
Johannes Schindelin
188fb7f754 t0302: add forgotten quotes
This was probably missed because nobody had a left-over `trash/`
directory and the `-f` flag made sure that no error message was
produced when the file was not found that *actually* wanted to
be removed.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:14 +02:00
Sverre Rabbelier
6e7cfa0950 t9350: point out that refs are not updated correctly
This happens only when the corresponding commits are not exported in
the current fast-export run. This can happen either when the relevant
commit is already marked, or when the commit is explicitly marked
as UNINTERESTING with a negative ref by another argument.

This breaks fast-export basec remote helpers.

Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>
2017-04-26 16:57:14 +02:00
Johannes Schindelin
634de5dd69 Skip t9020 with MSys2
POSIX-to-Windows path mangling would make it fail.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:13 +02:00
Johannes Schindelin
fd04c2509b Mark t0027-auto-crlf as cheap enough for MinGW
t0027 is marked expensive, but really, for MinGW we want to run these
tests always.

Suggested by Thomas Braun.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:13 +02:00
Thomas Braun
f89f68d700 t0027: Disable test on MINGW
We can't mmap 2GB of RAM on our 32bit platform, so
just disable the test.

Signed-off-by: Thomas Braun <thomas.braun@byte-physics.de>
2017-04-26 16:57:13 +02:00
Johannes Schindelin
7cdaf67d8f Tests: optionally skip redirecting stdin/stdout/stderr
There is a really useful debugging technique developed by Sverre
Rabbelier that inserts "bash &&" somewhere in the test scripts, letting
the developer interact at given points with the current state.

Another debugging technique, used a lot by this here coder, is to run
certain executables via gdb by guarding a "gdb -args" call in
bin-wrappers/git.

Both techniques were disabled by 781f76b1(test-lib: redirect stdin of
tests).

Let's reinstate the ability to run an interactive shell by making the
redirection optional: setting the TEST_NO_REDIRECT environment variable
will skip the redirection.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:10 +02:00
Karsten Blees
809fe37577 Win32: support long paths
Windows paths are typically limited to MAX_PATH = 260 characters, even
though the underlying NTFS file system supports paths up to 32,767 chars.
This limitation is also evident in Windows Explorer, cmd.exe and many
other applications (including IDEs).

Particularly annoying is that most Windows APIs return bogus error codes
if a relative path only barely exceeds MAX_PATH in conjunction with the
current directory, e.g. ERROR_PATH_NOT_FOUND / ENOENT instead of the
infinitely more helpful ERROR_FILENAME_EXCED_RANGE / ENAMETOOLONG.

Many Windows wide char APIs support longer than MAX_PATH paths through the
file namespace prefix ('\\?\' or '\\?\UNC\') followed by an absolute path.
Notable exceptions include functions dealing with executables and the
current directory (CreateProcess, LoadLibrary, Get/SetCurrentDirectory) as
well as the entire shell API (ShellExecute, SHGetSpecialFolderPath...).

Introduce a handle_long_path function to check the length of a specified
path properly (and fail with ENAMETOOLONG), and to optionally expand long
paths using the '\\?\' file namespace prefix. Short paths will not be
modified, so we don't need to worry about device names (NUL, CON, AUX).

Contrary to MSDN docs, the GetFullPathNameW function doesn't seem to be
limited to MAX_PATH (at least not on Win7), so we can use it to do the
heavy lifting of the conversion (translate '/' to '\', eliminate '.' and
'..', and make an absolute path).

Add long path error checking to xutftowcs_path for APIs with hard MAX_PATH
limit.

Add a new MAX_LONG_PATH constant and xutftowcs_long_path function for APIs
that support long paths.

While improved error checking is always active, long paths support must be
explicitly enabled via 'core.longpaths' option. This is to prevent end
users to shoot themselves in the foot by checking out files that Windows
Explorer, cmd/bash or their favorite IDE cannot handle.

Test suite:
Test the case is when the full pathname length of a dir is close
to 260 (MAX_PATH).
Bug report and an original reproducer by Andrey Rogozhnikov:
https://github.com/msysgit/git/pull/122#issuecomment-43604199

Note that the test cannot rely on the presence of short names, as they
are not enabled by default except on the system drive.

[jes: adjusted test number to avoid conflicts, reinstated && chain,
adjusted test to work without short names]

Thanks-to: Martin W. Kirst <maki@bitkings.de>
Thanks-to: Doug Kelly <dougk.ff7@gmail.com>
Signed-off-by: Karsten Blees <blees@dcon.de>
Original-test-by: Andrey Rogozhnikov <rogozhnikov.andrey@gmail.com>
Signed-off-by: Stepan Kasal <kasal@ucw.cz>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:07 +02:00
Johannes Schindelin
eb8ae43f28 Win32: support long paths
Windows paths are typically limited to MAX_PATH = 260 characters, even
though the underlying NTFS file system supports paths up to 32,767 chars.
This limitation is also evident in Windows Explorer, cmd.exe and many
other applications (including IDEs).

Particularly annoying is that most Windows APIs return bogus error codes
if a relative path only barely exceeds MAX_PATH in conjunction with the
current directory, e.g. ERROR_PATH_NOT_FOUND / ENOENT instead of the
infinitely more helpful ERROR_FILENAME_EXCED_RANGE / ENAMETOOLONG.

Many Windows wide char APIs support longer than MAX_PATH paths through the
file namespace prefix ('\\?\' or '\\?\UNC\') followed by an absolute path.
Notable exceptions include functions dealing with executables and the
current directory (CreateProcess, LoadLibrary, Get/SetCurrentDirectory) as
well as the entire shell API (ShellExecute, SHGetSpecialFolderPath...).

Introduce a handle_long_path function to check the length of a specified
path properly (and fail with ENAMETOOLONG), and to optionally expand long
paths using the '\\?\' file namespace prefix. Short paths will not be
modified, so we don't need to worry about device names (NUL, CON, AUX).

Contrary to MSDN docs, the GetFullPathNameW function doesn't seem to be
limited to MAX_PATH (at least not on Win7), so we can use it to do the
heavy lifting of the conversion (translate '/' to '\', eliminate '.' and
'..', and make an absolute path).

Add long path error checking to xutftowcs_path for APIs with hard MAX_PATH
limit.

Add a new MAX_LONG_PATH constant and xutftowcs_long_path function for APIs
that support long paths.

While improved error checking is always active, long paths support must be
explicitly enabled via 'core.longpaths' option. This is to prevent end
users to shoot themselves in the foot by checking out files that Windows
Explorer, cmd/bash or their favorite IDE cannot handle.

Test suite:
Test the case is when the full pathname length of a dir is close
to 260 (MAX_PATH).
Bug report and an original reproducer by Andrey Rogozhnikov:
https://github.com/msysgit/git/pull/122#issuecomment-43604199

[jes: adjusted test number to avoid conflicts]

Thanks-to: Martin W. Kirst <maki@bitkings.de>
Thanks-to: Doug Kelly <dougk.ff7@gmail.com>
Signed-off-by: Karsten Blees <blees@dcon.de>
Original-test-by: Andrey Rogozhnikov <rogozhnikov.andrey@gmail.com>
Signed-off-by: Stepan Kasal <kasal@ucw.cz>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-04-26 16:57:07 +02:00