Commit Graph

75308 Commits

Author SHA1 Message Date
Johannes Schindelin
f6bcb0c455 fscache: add a test for the dir-not-found optimization
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-10 17:38:04 +02:00
Jeff Hostetler
feca8c7b43 fscache: remember not-found directories
Teach FSCACHE to remember "not found" directories.

This is a performance optimization.

FSCACHE is a performance optimization available for Windows.  It
intercepts Posix-style lstat() calls into an in-memory directory
using FindFirst/FindNext.  It improves performance on Windows by
catching the first lstat() call in a directory, using FindFirst/
FindNext to read the list of files (and attribute data) for the
entire directory into the cache, and short-cut subsequent lstat()
calls in the same directory.  This gives a major performance
boost on Windows.

However, it does not remember "not found" directories.  When STATUS
runs and there are missing directories, the lstat() interception
fails to find the parent directory and simply return ENOENT for the
file -- it does not remember that the FindFirst on the directory
failed. Thus subsequent lstat() calls in the same directory, each
re-attempt the FindFirst.  This completely defeats any performance
gains.

This can be seen by doing a sparse-checkout on a large repo and
then doing a read-tree to reset the skip-worktree bits and then
running status.

This change reduced status times for my very large repo by 60%.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-10 17:38:04 +02:00
Jeff Hostetler
497ed5c1dd fscache: add key for GIT_TRACE_FSCACHE
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-10 17:38:04 +02:00
Johannes Schindelin
98b525dff9 Merge branch 'long-paths'
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-10 17:38:03 +02:00
Karsten Blees
dca7c7b2ea Win32: fix 'lstat("dir/")' with long paths
Use a suffciently large buffer to strip the trailing slash.

Signed-off-by: Karsten Blees <blees@dcon.de>
2017-08-10 17:34:20 +02:00
Karsten Blees
614fe05a71 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-08-10 17:34:20 +02:00
Johannes Schindelin
b1b75cc1d7 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-08-10 17:34:20 +02:00
Doug Kelly
c79e1e5788 Add a test demonstrating a problem with long submodule paths
[jes: adusted test number to avoid conflicts, fixed non-portable use of
the 'export' statement]

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-10 17:34:20 +02:00
Karsten Blees
471832067c fscache: load directories only once
If multiple threads access a directory that is not yet in the cache, the
directory will be loaded by each thread. Only one of the results is added
to the cache, all others are leaked. This wastes performance and memory.

On cache miss, add a future object to the cache to indicate that the
directory is currently being loaded. Subsequent threads register themselves
with the future object and wait. When the first thread has loaded the
directory, it replaces the future object with the result and notifies
waiting threads.

Signed-off-by: Karsten Blees <blees@dcon.de>
2017-08-10 17:34:19 +02:00
Karsten Blees
f053ac1d92 Win32: add a cache below mingw's lstat and dirent implementations
Checking the work tree status is quite slow on Windows, due to slow lstat
emulation (git calls lstat once for each file in the index). Windows
operating system APIs seem to be much better at scanning the status
of entire directories than checking single files.

Add an lstat implementation that uses a cache for lstat data. Cache misses
read the entire parent directory and add it to the cache. Subsequent lstat
calls for the same directory are served directly from the cache.

Also implement opendir / readdir / closedir so that they create and use
directory listings in the cache.

The cache doesn't track file system changes and doesn't plug into any
modifying file APIs, so it has to be explicitly enabled for git functions
that don't modify the working copy.

Note: in an earlier version of this patch, the cache was always active and
tracked file system changes via ReadDirectoryChangesW. However, this was
much more complex and had negative impact on the performance of modifying
git commands such as 'git checkout'.

Signed-off-by: Karsten Blees <blees@dcon.de>
2017-08-10 17:34:19 +02:00
Karsten Blees
993c372e46 add infrastructure for read-only file system level caches
Add a macro to mark code sections that only read from the file system,
along with a config option and documentation.

This facilitates implementation of relatively simple file system level
caches without the need to synchronize with the file system.

Enable read-only sections for 'git status' and preload_index.

Signed-off-by: Karsten Blees <blees@dcon.de>
2017-08-10 17:34:18 +02:00
Karsten Blees
dab1093f48 Win32: make the lstat implementation pluggable
Emulating the POSIX lstat API on Windows via GetFileAttributes[Ex] is quite
slow. Windows operating system APIs seem to be much better at scanning the
status of entire directories than checking single files. A caching
implementation may improve performance by bulk-reading entire directories
or reusing data obtained via opendir / readdir.

Make the lstat implementation pluggable so that it can be switched at
runtime, e.g. based on a config option.

Signed-off-by: Karsten Blees <blees@dcon.de>
2017-08-10 17:34:18 +02:00
Karsten Blees
bd4724e9d9 Win32: Make the dirent implementation pluggable
Emulating the POSIX dirent API on Windows via FindFirstFile/FindNextFile is
pretty staightforward, however, most of the information provided in the
WIN32_FIND_DATA structure is thrown away in the process. A more
sophisticated implementation may cache this data, e.g. for later reuse in
calls to lstat.

Make the dirent implementation pluggable so that it can be switched at
runtime, e.g. based on a config option.

Define a base DIR structure with pointers to readdir/closedir that match
the opendir implementation (i.e. similar to vtable pointers in OOP).
Define readdir/closedir so that they call the function pointers in the DIR
structure. This allows to choose the opendir implementation on a
call-by-call basis.

Move the fixed sized dirent.d_name buffer to the dirent-specific DIR
structure, as d_name may be implementation specific (e.g. a caching
implementation may just set d_name to point into the cache instead of
copying the entire file name string).

Signed-off-by: Karsten Blees <blees@dcon.de>
2017-08-10 17:34:18 +02:00
Karsten Blees
02f3bc7a19 Win32: dirent.c: Move opendir down
Move opendir down in preparation for the next patch.

Signed-off-by: Karsten Blees <blees@dcon.de>
2017-08-10 17:34:18 +02:00
Karsten Blees
4bfda48eb9 Win32: make FILETIME conversion functions public
Signed-off-by: Karsten Blees <blees@dcon.de>
2017-08-10 17:34:18 +02:00
Johannes Schindelin
fb74203802 mingw: unset PERL5LIB by default
Git for Windows ships with its own Perl interpreter, and insists on
using it, so it will most likely wreak havoc if PERL5LIB is set before
launching Git.

Let's just unset that environment variables when spawning processes.

To make this feature extensible (and overrideable), there is a new
config setting `core.unsetenvvars` that allows specifying a
comma-separated list of names to unset before spawning processes.

Reported by Gabriel Fuhrmann.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-10 17:34:17 +02:00
Johannes Schindelin
ad69de2927 Move Windows-specific config settings into compat/mingw.c
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-10 17:34:17 +02:00
Johannes Schindelin
d4cfed12ba Allow for platform-specific core.* config settings
In the Git for Windows project, we have ample precendent for config
settings that apply to Windows, and to Windows only.

Let's formalize this concept by introducing a platform_core_config()
function that can be #define'd in a platform-specific manner.

This will allow us to contain platform-specific code better, as the
corresponding variables no longer need to be exported so that they can
be defined in environment.c and be set in config.c

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-10 17:34:17 +02:00
Johannes Schindelin
6614a11301 Start the merging-rebase to v2.14.1
This commit starts the rebase of e14c3892c4 to 6abeb172d0
2017-08-10 17:34:05 +02:00
Johannes Schindelin
0f3342804f Revert "git_connect: prefer Git's builtins over dashed form"
It would appear that this change (which was intended to fix tests
interacting with local repositories when `git-upload-pack` was not in the
`PATH`) regresses on SSH access.

This reverts commit 40023e58cd and fixes
https://github.com/git-for-windows/git/issues/1258.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-07 10:55:31 +02:00
Johannes Schindelin
f0a126c029 fixup! Teach status to show ignored directories with all untracked files
It is totally my fault that I failed to notice the updated PR at
https://github.com/git-for-windows/git/pull/1243. This backports the fixes
into the next Git for Windows version's commit graph.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-06 01:07:18 +02:00
Johannes Schindelin
8d74ef6015 Merge branch 'busybox-w32'
This topic branch brings slightly experimental changes supporting Git
for Windows to use BusyBox-w32 to execute its shell scripts as well as
its test suite.

The test suite can be run by installing the test artifacts into a MinGit
that has busybox.exe (and using Git for Windows' SDK's Perl for now, as
the test suite requires Perl even when NO_PERL is set, go figure) by
using the `install-mingit-test-artifacts` Makefile target with the
DESTDIR variable pointing to the top-level directory of the MinGit
installation.

To facilitate running the test suite (without having `make` available,
as `make.exe` is not part of MinGit), this branch brings an experimental
patch to the `test-run-command` helper to run Git's test suite. It is
still very experimental, though: in this developer's tests it seemed
that the `poll()` emulation required for `run_parallel_processes()` to
work sometimes hiccups on Windows, causing infinite "hangs". It is also
possible that BusyBox itself has problems writing to the pipes opened by
`test-run-command` (and merging this branch will help investigate
further). Caveat emptor.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:22 +02:00
Johannes Schindelin
ed4d0cd013 mingw: add a Makefile target to copy test artifacts
The Makefile target `install-mingit-test-artifacts` simply copies stuff
and things directly into a MinGit directory, including an init.bat
script to set everything up so that the tests can be run in a cmd
window.

Sadly, Git's test suite still relies on a Perl interpreter even if
compiled with NO_PERL=YesPlease. We punt for now, installing a small
script into /usr/bin/perl that hands off to an existing Perl of a Git
for Windows SDK.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:20 +02:00
Johannes Schindelin
aa118d62f3 t9350: skip ISO-8859-1 test when the environment is always-UTF-8
In the BusyBox-w32 version that is currently under consideration for
MinGit for Windows (to reduce the .zip size, and to avoid problems with
the MSYS2 runtime), the UTF-16 environment present in Windows is
considered to be authoritative, and the 8-bit version is always in UTF-8
encoding.

As a consequence, the ISO-8859-1 test in t9350-fast-export (which tries
to set GIT_AUTHOR_NAME to a ISO-8859-1 encoded value) *must* fail in
that setup.

So let's detect when it would fail (due to an environment being purely
kept UTF-8 encoded), and skip that test in that case.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:20 +02:00
Johannes Schindelin
c09a6b334c t9200: skip tests when $PWD contains a colon
On Windows, the current working directory is pretty much guaranteed to
contain a colon. If we feed that path to CVS, it mistakes it for a
separator between host and port, though.

This has not been a problem so far because Git for Windows uses MSYS2's
Bash using a POSIX emulation layer that also pretends that the current
directory is a Unix path (at least as long as we're in a shell script).

However, that is rather limiting, as Git for Windows also explores other
ports of other Unix shells. One of those is BusyBox-w32's ash, which is
a native port (i.e. *not* using any POSIX emulation layer, and certainly
not emulating Unix paths).

So let's just detect if there is a colon in $PWD and punt in that case.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:20 +02:00
Johannes Schindelin
229ba9c537 t7063: when running under BusyBox, avoid unsupported find option
BusyBox' find implementation does not understand the -ls option, so
let's not use it when we're running inside BusyBox.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:20 +02:00
Johannes Schindelin
7abc9c408e t5813: allow for $PWD to be a Windows path
Git for Windows uses MSYS2's Bash to run the test suite, which comes
with benefits but also at a heavy price: on the plus side, MSYS2's
POSIX emulation layer allows us to continue pretending that we are on a
Unix system, e.g. use Unix paths instead of Windows ones, yet this is
bought at a rather noticeable performance penalty.

There *are* some more native ports of Unix shells out there, though,
most notably BusyBox-w32's ash. These native ports do not use any POSIX
emulation layer (or at most a *very* thin one, choosing to avoid
features such as fork() that are expensive to emulate on Windows), and
they use native Windows paths (usually with forward slashes instead of
backslashes, which is perfectly legal in almost all use cases).

And here comes the problem: with a $PWD looking like, say,
C:/git-sdk-64/usr/src/git/t/trash directory.t5813-proto-disable-ssh
Git's test scripts get quite a bit confused, as their assumptions have
been shattered. Not only does this path contain a colon (oh no!), it
also does not start with a slash.

This is a problem e.g. when constructing a URL as t5813 does it:
ssh://remote$PWD. Not only is it impossible to separate the "host" from
the path with a $PWD as above, even prefixing $PWD by a slash won't
work, as /C:/git-sdk-64/... is not a valid path.

As a workaround, detect when $PWD does not start with a slash on
Windows, and simply strip the drive prefix, using an obscure feature of
Windows paths: if an absolute Windows path starts with a slash, it is
implicitly prefixed by the drive prefix of the current directory. As we
are talking about the current directory here, anyway, that strategy
works.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:19 +02:00
Johannes Schindelin
c4e8f69f06 t5605: special-case hardlink test for BusyBox-w32
When t5605 tries to verify that files are hardlinked (or that they are
not), it uses the `-links` option of the `find` utility.

BusyBox' implementation does not support that option, and BusyBox-w32's
lstat() does not even report the number of hard links correctly (for
performance reasons).

So let's just switch to a different method that actually works on
Windows.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:19 +02:00
Johannes Schindelin
0c114ef44f t5532: workaround for BusyBox on Windows
While it may seem super convenient to some old Unix hands to simpy
require Perl to be available when running the test suite, this is a
major hassle on Windows, where we want to verify that Perl is not,
actually, required in a NO_PERL build.

As a super ugly workaround, we "install" a script into /usr/bin/perl
reading like this:

	#!/bin/sh

	# We'd much rather avoid requiring Perl altogether when testing
	# an installed Git. Oh well, that's why we cannot have nice
	# things.
	exec c:/git-sdk-64/usr/bin/perl.exe "$@"

The problem with that is that BusyBox assumes that the #! line in a
script refers to an executable, not to a script. So when it encounters
the line #!/usr/bin/perl in t5532's proxy-get-cmd, it barfs.

Let's help this situation by simply executing the Perl script with the
"interpreter" specified explicitly.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:19 +02:00
Johannes Schindelin
6bff2d313c t5003: skip unzip -a tests with BusyBox
BusyBox' unzip is working pretty well. But Git's tests want to abuse it
to not only extract files, but to convert their line endings on the fly,
too. BusyBox' unzip does not support that, and it would appear that
it would require rather intrusive changes.

So let's just work around this by skipping the test case that uses
`unzip -a` and the subsequent test cases expecting `unzip -a`'s output.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:19 +02:00
Johannes Schindelin
2c07dd2ca3 t5003: use binary file from t/diff-lib/
At some stage, t5003-archive-zip wants to add a file that is not ASCII.
To that end, it uses /bin/sh. But that file may actually not exist (it
is too easy to forget that not all the world is Unix/Linux...)! Besides,
we already have perfectly fine binary files intended for use solely by
the tests. So let's use one of them instead.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:19 +02:00
Johannes Schindelin
70b6f5c601 t4124: avoid using "normal" diff mode
Everybody and their dogs, cats and other pets settled on using unified
diffs. It is a really quaint holdover from a long-gone era that GNU diff
outputs "normal" diff by default.

Yet, t4124 relied on that mode.

This mode is so out of fashion in the meantime, though, that e.g.
BusyBox' diff decided not even to bother to support it. It only supports
unified diffs.

So let's just switch away from "normal" diffs and use unified diffs, as
we really are only interested in the `+` lines.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:18 +02:00
Johannes Schindelin
33e64e7ebe t1300: mark all test cases with funny filenames as !MINGW
On Windows, it is impossible to create a file whose name contains a
quote character. We already excluded test cases using such files from
running on Windows when git.exe itself was tested.

However, we still had two test cases that try to create such a file, and
redirect stdin from such a file, respectively. This *seems* to work in
Git for Windows' Bash due to an obscure feature inherited from Cygwin:
illegal filename characters are simply mapped into/from a private UTF-8
page. Pure Win32 programs (such as git.exe) *still* cannot work with
those files, of course, but at least Unix shell scripts pretend to be
able to.

This entire strategy breaks down when switching to any Unix shell
lacking support for that private UTF-8 page trick, e.g. BusyBox-w32's
ash. So let's just exclude test cases that test whether the Unix shell
can redirect to/from files with "funny names" those from running on
Windows, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:18 +02:00
Johannes Schindelin
2edfddc2ba t0021: use Windows path when appropriate
Since c6b0831c9c (docs: warn about possible '=' in clean/smudge filter
process values, 2016-12-03), t0021 writes out a file with quotes in its
name, and MSYS2's path conversion heuristics mistakes that to mean that
we are not talking about a path here.

Therefore, we need to use Windows paths, as the test-helper is a Win32
program that would otherwise have no idea where to look for the file.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:18 +02:00
Johannes Schindelin
89b2382ee8 test-lib: add BUSYBOX prerequisite
When running with BusyBox, we will want to avoid calling executables on
the PATH that are implemented in BusyBox itself.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:18 +02:00
Johannes Schindelin
18badfe268 tests (mingw): remove Bash-specific pwd option
The -W option is only understood by MSYS2 Bash's pwd command. We already
make sure to override `pwd` by `builtin pwd -W` for MINGW, so let's not
double the effort here.

This will also help when switching the shell to another one (such as
BusyBox' ash) whose pwd does *not* understand the -W option.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:18 +02:00
Johannes Schindelin
3edc1c7c79 mingw: only use Bash-ism builtin pwd -W when available
Traditionally, Git for Windows' SDK uses Bash as its default shell.
However, other Unix shells are available, too. Most notably, the Win32
port of BusyBox comes with `ash` whose `pwd` command already prints
Windows paths as Git for Windows wants them, while there is not even a
`builtin` command.

Therefore, let's be careful not to override `pwd` unless we know that
the `builtin` command is available.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:17 +02:00
Johannes Schindelin
c757368ad4 tests: use the correct path separator with BusyBox
BusyBox-w32 is a true Win32 application, i.e. it does not come with a
POSIX emulation layer.

That also means that it does *not* use the Unix convention of separating
the entries in the PATH variable using colons, but semicolons.

However, there are also BusyBox ports to Windows which use a POSIX
emulation layer such as Cygwin's or MSYS2's runtime, i.e. using colons
as PATH separators.

As a tell-tale, let's use the presence of semicolons in the PATH
variable: on Unix, it is highly unlikely that it contains semicolons,
and on Windows (without POSIX emulation), it is virtually guaranteed, as
everybody should have both $SYSTEMROOT and $SYSTEMROOT/system32 in their
PATH.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:17 +02:00
Johannes Schindelin
4f403db818 tests: move test PNGs into t/diff-lib/
We already have a directory where we store files intended for use by
multiple test scripts. The same directory is a better home for the
test-binary-*.png files than t/.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:17 +02:00
Johannes Schindelin
3ca6964fb5 tests: use t/diff-lib/* consistently
The idea of copying README and COPYING into t/diff-lib/ was to step away
from using files from outside t/ in tests. Let's really make sure that
we use the files from t/diff-lib/ instead of other versions of those
files.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:17 +02:00
Johannes Schindelin
f6a6f7a619 t/lib-gettext:test installed git-sh-i18n if GIT_TEST_INSTALLED is set
It makes very, very little sense to test the built git-sh-i18n when the
user asked specifically to test another one.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:17 +02:00
Johannes Schindelin
70eae48cdc tests: respect GIT_TEST_INSTALLED when initializing repositories
It really makes very, very little sense to use a different git
executable than the one the caller indicated via setting the environment
variable GIT_TEST_INSTALLED.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:16 +02:00
Johannes Schindelin
de9928fa83 tests: do not require Git to be built when testing an installed Git
We really only need the test helpers in that case, but that is not what
we test for. So let's skip the test for now when we know that we want to
test an installed Git.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:16 +02:00
Johannes Schindelin
5ab5e9f63c tests(mingw): if iconv is unavailable, use test-helper --iconv
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:16 +02:00
Johannes Schindelin
44cd93cf87 test-helper: learn to act as a drop-in replacement for iconv
It is convenient to assume that everybody who wants to build & test Git
has access to a working `iconv` executable (after all, we already pretty
much require libiconv)

However, that limits esoteric test scenarios such as Git for Windows',
where an end user installation has to ship with `iconv` for the sole
purpose of being testable. That payload serves no other purpose.

So let's just have a test helper (to be able to test Git, the test
helpers have to be available, after all) to act as `iconv` replacement.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:39:16 +02:00
Johannes Schindelin
2b0b369a3b tests: replace mingw_test_cmp with a helper in C
This helper is slightly more performant than the script with MSYS2's
Bash. And a lot more readable.

To accommodate t1050, which wants to compare files weighing in with 3MB
(falling outside of t1050's malloc limit of 1.5MB), we simply lift the
allocation limit by setting the environment variable GIT_ALLOC_LIMIT to
zero when calling the helper.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:29:46 +02:00
Johannes Schindelin
17f2e06ba2 test-lib: avoid unnecessary Perl invocation
It is a bit strange, and even undesirable, to require Perl just to run
the test suite even when NO_PERL was set.

This patch does not fix this problem by any stretch of imagination.
However, it fixes *the* Perl invocation that *every single* test script
has to run.

While at it, it makes the source code also more grep'able, as the code
that unsets some, but not all, GIT_* environment variables just became a
*lot* more explicit. And all that while still reducing the total number
of lines.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 22:29:46 +02:00
Johannes Schindelin
d6908620fe test-run-command: learn to run (parts of) the testsuite
Instead of relying on the presence of `make`, or `prove`, we might just
as well use our own facilities to run the test suite.

This helps e.g. when trying to verify a Git for Windows installation
without requiring to download a full Git for Windows SDK (which would use
up 600+ megabytes of bandwidth, and over a gigabyte of disk space).

Of course, it still requires the test helpers to be build *somewhere*,
and the Git version should at least roughly match the version from which
the test suite comes.

At the same time, this new way to run the test suite allows to validate
that a BusyBox-backed MinGit works as expected (verifying that BusyBox'
functionality is enough to at least pass the test suite).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 00:24:59 +02:00
Johannes Schindelin
13abb2b233 mingw: when path_lookup() failed, try BusyBox
BusyBox comes with a ton of applets ("applet" being the identical
concept to Git's "builtins"). And similar to Git's builtins, the applets
can be called via `busybox <command>`, or the BusyBox executable can be
copied/hard-linked to the command name.

The similarities do not end here. Just as with Git's builtins, it is
problematic that BusyBox' hard-linked applets cannot easily be put into
a .zip file: .zip archives have no concept of hard-links and therefore
would store identical copies (and also extract identical copies,
"inflating" the archive unnecessarily).

To counteract that issue, MinGit already ships without hard-linked
copies of the builtins, and the plan is to do the same with BusyBox'
applets: simply ship busybox.exe as single executable, without
hard-linked applets.

To accommodate that, Git is being taught by this commit a very special
trick, exploiting the fact that it is possible to call an executable
with a command-line whose argv[0] is different from the executable's
name: when `sh` is to be spawned, and no `sh` is found in the PATH, but
busybox.exe is, use that executable (with unchanged argv).

Likewise, if any executable to be spawned is not on the PATH, but
busybox.exe is found, parse the output of `busybox.exe --help` to find
out what applets are included, and if the command matches an included
applet name, use busybox.exe to execute it.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 00:24:59 +02:00
Johannes Schindelin
7b3c373cc9 mingw: explicitly specify with which cmd to prefix the cmdline
The main idea of this patch is that even if we have to look up the
absolute path of the script, if only the basename was specified as
argv[0], then we should use that basename on the command line, too, not
the absolute path.

This patch will also help with the upcoming patch where we automatically
substitute "sh ..." by "busybox sh ..." if "sh" is not in the PATH but
"busybox" is: we will do that by substituting the actual executable, but
still keep prepending "sh" to the command line.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
2017-08-05 00:24:59 +02:00