This is retry of #1419.
I added flush_fscache macro to flush cached stats after disk writing
with tests for regression reported in #1438 and #1442.
git checkout checks each file path in sorted order, so cache flushing does not
make performance worse unless we have large number of modified files in
a directory containing many files.
Using chromium repository, I tested `git checkout .` performance when I
delete 10 files in different directories.
With this patch:
TotalSeconds: 4.307272
TotalSeconds: 4.4863595
TotalSeconds: 4.2975562
Avg: 4.36372923333333
Without this patch:
TotalSeconds: 20.9705431
TotalSeconds: 22.4867685
TotalSeconds: 18.8968292
Avg: 20.7847136
I confirmed this patch passed all tests in t/ with core_fscache=1.
Signed-off-by: Takuto Ikuta <tikuta@chromium.org>
When I do git fetch, git call file stats under .git/objects for each
refs. This takes time when there are many refs.
By enabling fscache, git takes file stats by directory traversing and that
improved the speed of fetch-pack for repository having large number of
refs.
In my windows workstation, this improves the time of `git fetch` for
chromium repository like below. I took stats 3 times.
* With this patch
TotalSeconds: 9.9825165
TotalSeconds: 9.1862075
TotalSeconds: 10.1956256
Avg: 9.78811653333333
* Without this patch
TotalSeconds: 15.8406702
TotalSeconds: 15.6248053
TotalSeconds: 15.2085938
Avg: 15.5580231
Signed-off-by: Takuto Ikuta <tikuta@chromium.org>
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>
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>
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>
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>
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>
In December 2016 and January 2017, we revamped the Windows-specific
`isatty()` handling, replacing a hack by a more robust solution.
This patch is a follow-up we realized was necessary already in March
2017, but forgot to contribute to core Git yet.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When compiling Git with a runtime prefix (so that it can be installed
into any location, finding its libexec/ directory relative to the
location of the `git` executable), it is convenient to provide
"absolute" Unix-y paths e.g. for http.sslCAInfo, and have those absolute
paths be resolved relative to the runtime prefix.
This patch makes it so for Windows. It is up for discussion whether we
want this for other platforms, too, as long as building with
RUNTIME_PREFIX.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
On Windows, it is more common than on other platforms to "cross-compile"
32-bit binaries on a 64-bit machine. It is even possible to compile
32-bit binaries and 64-bit binaries in the same worktree, as the CFLAGS
differ, triggering a rebuild.
Except for the resource file, which does not need the CFLAGS. Let's work
around that.
This patch has been carried in Git for Windows for well over a year now,
and while it is not interesting to non-Windows platforms, it is time to
graduate to core Git.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This patch has been carried by Git for Windows for almost two years. It
makes loading system libraries safer.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This patch series contains a couple of fixes revolving around testing
an installed Git, via GIT_TEST_INSTALLED=/path/to/git.
The original motivation for these patches is that Git for Windows wants
to provide a version where the Unix shell scripts are interpreted by
BusyBox (to reduce the footprint on disk, mainly), and we want to verify
that this actually works, and is not perchance missing any Unix shell
tool that is present in the Git for Windows SDK but is missing from the
installed set of files.
While the BusyBox-based Git for Windows is not ready for prime time,
this here patch series is, and might be useful for packagers who want to
verify a similar scenario.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
We newly handle isatty() by special-casing the stdin/stdout/stderr file
descriptors, caching the return value. However, we missed the case where
dup2() overrides the respective file descriptor.
That poses a problem e.g. where the `show` builtin asks for a pager very
early, the `setup_pager()` function sets the pager depending on the
return value of `isatty()` and then redirects stdout. Subsequently,
`cmd_log_init_finish()` calls `setup_pager()` *again*. What should
happen now is that `isatty()` reports that stdout is *not* a TTY and
consequently stdout should be left alone.
Let's override dup2() to handle this appropriately.
This fixes https://github.com/git-for-windows/git/issues/1077
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When git.rc is compiled into git.res, the result is actually dependent
on the architecture. That is, you cannot simply link a 32-bit git.res
into a 64-bit git.exe.
Therefore, to allow 32-bit and 64-bit builds in the same directory, we
let git.res depend on GIT-PREFIX so that it gets recompiled when
compiling for a different architecture (this works because the exec path
changes based on the architecture: /mingw32/libexec/git-core for 32-bit
and /mingw64/libexec/git-core for 64-bit).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When we access IPv6-related functions, we load the corresponding system
library using the `LoadLibrary()` function, which is not the recommended
way to load system libraries.
In practice, it does not make a difference: the `ws2_32.dll` library
containing the IPv6 functions is already loaded into memory, so
LoadLibrary() simply reuses the already-loaded library.
Still, recommended way is recommended way, so let's use that instead.
While at it, also adjust the code in contrib/ that loads system libraries.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
In the bin-wrappers/* scripts, we already take pains to use `git.exe`
rather than `git`, as this could pick up the wrong thing on Windows
(i.e. if there exists a `git` file or directory in the build directory).
Now we do the same in the tests' start-up code.
This also helps when testing an installed Git, as there might be even
more likely some stray file or directory in the way.
Note: the only way we can record whether the `.exe` suffix is by writing
it to the `GIT-BUILD-OPTIONS` file and sourcing it at the beginning of
`t/test-lib.sh`. This is not a requirement introduced by this patch, but
we move the call to be able to use the `$X` variable that holds the file
extension, if any.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
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>
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>
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>
We really need to be able to find the test helpers... Really. This
change was forgotten when we moved the test helpers into t/helper/
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This topic branch teaches Git to accept UNC paths of the form
file://host/share/repository.git.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This topic branch brings support for choosing cURL's SSL backend at
runtime via http.sslBackend, based on patches already submitted to the
cURL project and backported to cURL 7.54.1 as used in Git for Windows'
SDK.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This backports f31d23a399 (Merge branch 'bw/config-h', 2017-06-24) from
upstream Git's `master` branch, plus a patch that seems to be required
to let the test suite pass.
This topic branch fixes problems when looking up aliases in worktrees.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This topic branch addresses a problem identified in
https://github.com/git-for-windows/git/issues/439: while
cloning/fetching/pushing from "POSIX-ified UNC paths" (i.e. UNC paths
whose backslashes have been converted to forward slashes) works for some
time now, true UNC paths (with backslashes left intact) were handled
incorrectly. Example:
git clone //myserver/folder/repo.git
works, but
git clone \\myserver\folder\repo.git
(in CMD; in Git Bash, the backslashes would need to be doubled) used to
fail. The reason was an unexpected difference in command-line handling
between Win32 executables and MSYS2 ones (such as the shell that is used
by git-clone.exe to spawn git-upload-pack.exe).
This topic branch features a workaround *just* for the case where Git
passes stuff through sh.exe (which covers quite a few use cases,
though).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This topic branch allows us to specify absolute paths without the drive
prefix e.g. when cloning.
Example:
C:\Users\me> git clone https://github.com/git/git \upstream-git
This will clone into a new directory C:\upstream-git, in line with how
Windows interprets absolute paths.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This fixes a bug where a .git directory at the root of a network share
(e.g. \\MYSERVER\sharedfolder\.git) was not handled correctly.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The function CreateHardLink is available in all supported Windows
versions (since Windows XP), so there is no more need to resolve it
in runtime.
Helped-by: Max Kirillov <max@max630.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Quite some time ago, a last plea to the XP users out there who want to
see Windows XP support in Git for Windows, asking them to get engaged
and help, vanished into the depths of the universe.
It is time to codify the ascent by the "silent majority" of XP users,
and mark the minimum Windows version required for Git for Windows as
Windows Vista.
This, incidentally, lets us use quite a few nice new APIs.
This also means that we no longer need the inet_pton() and inet_ntop()
emulation, and we no longer need to do the PROC_ADDR dance with the
`CreateSymbolicLinkW()` function, either.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Previously, we only ever declared a target Windows version if compiling
with Visual C.
Which meant that we were relying on the MinGW headers to guess which
Windows version we want to target...
Let's be explicit about it, in particular because we actually want to
bump the target Windows version to Vista (which we will do in the next
commit).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Windows Vista (and later) actually have a working poll(), but we still
cannot use it because it only works on sockets.
So let's detect when we are targeting Windows Vista and undefine those
constants, and define `pollfd` so that we can declare our own pollfd
struct.
We also need to make sure that we override those constants *after*
`winsock2.h` has been `#include`d (otherwise we would not really
override those constants).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
When working in the root directory of a file share (this is only
possible in Git Bash and Powershell, but not in CMD), the current
directory is reported without a trailing slash.
This is different from Unix and standard Windows directories: both / and
C:\ are reported with a trailing slash as current directories.
If a Git worktree is located there, Git is not quite prepared for that:
while it does manage to find the .git directory/file, it returns as
length of the top-level directory's path *one more* than the length of
the current directory, and setup_git_directory_gently() would then
return an undefined string as prefix.
In practice, this undefined string usually points to NUL bytes, and does
not cause much harm. Under rare circumstances that are really involved
to reproduce (and not reliably so), the reported prefix could be a
suffix string of Git's exec path, though.
A careful analysis determined that this bug is unlikely to be
exploitable, therefore we mark this as a regular bug fix.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
A very common assumption in Git's source code base is that
offset_1st_component() returns either 0 for relative paths, or 1 for
absolute paths that start with a slash. In other words, the return value
is either 0 or points just after the dir separator.
This assumption is not fulfilled when calling offset_1st_component()
e.g. on UNC paths on Windows, e.g. "//my-server/my-share". In this case,
offset_1st_component() returns the length of the entire string (which is
correct, because stripping the last "component" would not result in a
valid directory), yet the return value still does not point just after a
dir separator.
This assumption is most prominently seen in the
setup_git_directory_gently_1() function, where we want to append a
".git" component and simply assume that there is already a dir
separator. In the UNC example given above, this assumption is incorrect.
As a consequence, Git will fail to handle a worktree at the top of a UNC
share correctly.
Let's fix this by adding a dir separator specifically for that case: we
found that there is no first component in the path and it does not end
in a dir separator? Then add it.
This fixes https://github.com/git-for-windows/git/issues/1320
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
The fix we introduced in Git for Windows will be made obsolete by a more
general fix that has been already accepted into upstream Git's `next`
branch.
But we still can introduce a regression test that verifies that this bug
will be caught very quickly, if reintroduced.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This was pull request #1003 from shoelzer/master
poll: Use GetTickCount64 to avoid wraparound issues
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This was pull request #797 from glhez/master
`git bundle create <bundle>` leaks handle the revlist is empty.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This came in via pull request #677 from yaras/fix-git-675
Fixed masking username with asterisks when reading credentials
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>