The MSYS2 runtime does its best to emulate the command-line wildcard
expansion and de-quoting which would be performed by the calling Unix
shell on Unix systems.
Those Unix shell quoting rules differ from the quoting rules applying to
Windows' cmd and Powershell, making it a little awkward to quote
command-line parameters properly when spawning other processes.
In particular, git.exe passes arguments to subprocesses that are *not*
intended to be interpreted as wildcards, and if they contain
backslashes, those are not to be interpreted as escape characters, e.g.
when passing Windows paths.
Note: this is only a problem when calling MSYS2 executables, not when
calling MINGW executables such as git.exe. However, we do call MSYS2
executables frequently, most notably when setting the use_shell flag in
the child_process structure.
There is no elegant way to determine whether the .exe file to be
executed is an MSYS2 program or a MINGW one. But since the use case of
passing a command line through the shell is so prevalent, we need to
work around this issue at least when executing sh.exe.
Let's introduce an ugly, hard-coded test whether argv[0] is "sh", and
whether it refers to the MSYS2 Bash, to determine whether we need to
quote the arguments differently than usual.
That still does not fix the issue completely, but at least it is
something.
Incidentally, this also fixes the problem where `git clone \\server\repo`
failed due to incorrect handling of the backslashes when handing the path
to the git-upload-pack process.
We need to take care to quote not only whitespace, but also curly
brackets. As aliases frequently go through the MSYS2 Bash, and
as aliases frequently get parameters such as HEAD@{yesterday}, let's
make sure that this does not regress by adding a test case for that.
Helped-by: Kim Gybels <kgybels@infogroep.be>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Due to a quirk in Git's method to spawn git-upload-pack, there is a
problem when passing paths with backslashes in them: Git will force the
command-line through the shell, which has different quoting semantics in
Git for Windows (being an MSYS2 program) than regular Win32 executables
such as git.exe itself.
The symptom is that the first of the two backslashes in UNC paths of the
form \\myserver\folder\repository.git is *stripped off*.
Document this bug by introducing a test case.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
With this topic branch, the PERL5LIB variable is unset to avoid external
settings from interfering with Git's own Perl interpreter.
This branch also cleans up some of our Windows-only config setting code
(and this will need to be rearranged in the next merging rebase so that
the cleanup comes first, and fscache and longPaths support build on
top).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
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>
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>
The next commit introducing `normalize_ntpath()` into `mingw_chdir()`
relies on the former function being present...
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
`GetLongPathName()` function may fail when it is unable to query
the parent directory of a path component to determine the long name
for that component. It happens, because of it uses `FindFirstFile()`
function for each next short part of path. The `FindFirstFile()`
requires `List Directory` and `Synchronize` desired access for a calling
process.
In case of lacking such permission for some part of path,
the `GetLongPathName()` returns 0 as result and `GetLastError()`
returns ERROR_ACCESS_DENIED.
`GetFinalPathNameByHandle()` function can help in such cases, because
it requires `Read Attributes` and `Synchronize` desired access to the
target path only.
The `GetFinalPathNameByHandle()` function was introduced on
`Windows Server 2008/Windows Vista`. So we need to load it dynamically.
`CreateFile()` parameters:
`lpFileName` = path to the current directory
`dwDesiredAccess` = 0 (it means `Read Attributes` and `Synchronize`)
`dwShareMode` = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
(it prevents `Sharing Violation`)
`lpSecurityAttributes` = NULL (default security attributes)
`dwCreationDisposition` = OPEN_EXISTING
(required to obtain a directory handle)
`dwFlagsAndAttributes` = FILE_FLAG_BACKUP_SEMANTICS
(required to obtain a directory handle)
`hTemplateFile` = NULL (when opening an existing file or directory,
`CreateFile` ignores this parameter)
The string that is returned by `GetFinalPathNameByHandle()` function
uses the \\?\ syntax. To skip the prefix and convert backslashes
to slashes, the `normalize_ntpath()` mingw function will be used.
Note: `GetFinalPathNameByHandle()` function returns a final path.
It is the path that is returned when a path is fully resolved.
For example, for a symbolic link named "C:\tmp\mydir" that points to
"D:\yourdir", the final path would be "D:\yourdir".
Signed-off-by: Anton Serbulov <aserbulov@plesk.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This will be needed by the next commit, as it will make use of the
`GetFinalPathNameByHandleW()` function (which requires Vista or later).
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 switching the current working directory, say, in PowerShell, it is
quite possible to use a different capitalization than the one that is
recorded on disk. While doing the same in `cmd.exe` adjusts the
capitalization magically, that does not happen in PowerShell so that
`getcwd()` returns the current directory in a different way than is
recorded on disk.
Typically this creates no problems except when you call
git log .
in a subdirectory called, say, "GIT/" but you switched to "Git/" and
your `getcwd()` reports the latter, then Git won't understand that you
wanted to see the history as per the `GIT/` subdirectory but it thinks you
wanted to see the history of some directory that may have existed in the
past (but actually never did).
So let's be extra careful to adjust the capitalization of the current
directory before working with it.
Reported by a few PowerShell power users ;-)
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This is the convention elsewhere (and prepares for the case where we may
need to pass callback data).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This merging-rebase does not change anything in the code, just in the
commit structure of Git for Windows' branch thicket.
The motivation for this is that we have accumulated tons and tons of
patches in various stages of readiness to be contributed to core Git,
but there is no clear picture which patches are the most ready.
So here we use the calmer post-release days to organize our existing
branches into a more coherent structure, reordering them in order of
priority, and we also take the opportunity to merge branches (e.g.
misc-vs-fixes-extra into misc-vs-fixes) as well as patches (e.g. "The
stat() function should be independent of core.symlinks" really wanted to
be a fixup! commit for "Win32: implement stat() with symlink support").
This commit starts the rebase of f0badda8d7 to f0badda8d7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
It is a pain to maintain the .gitignore changes required to support
Vagrant. And we have had no indication whatsoever, at least since 2015,
that anybody was using it.
So let's drop it.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
In 9ac3f0e5b3 (pack-objects: fix performance issues on packing large
deltas, 2018-07-22), a mutex was introduced that is used to guard the
call to set the delta size. This commit even added code to initialize
it, but at an incorrect spot: in `init_threaded_search()`, while the
call to `oe_set_delta_size()` (and hence to `packing_data_lock()`) can
happen in the call chain `check_object()` <- `get_object_details()` <-
`prepare_pack()` <- `cmd_pack_objects()`, which is long before the
`prepare_pack()` function calls `ll_find_deltas()` (which initializes
the threaded search).
Another tell-tale that the mutex was initialized in an incorrect spot is
that the function to initialize it lives in builtin/, while the code
that uses the mutex is defined in a libgit.a header file.
Let's use a more appropriate function: `prepare_packing_data()`, which
not only lives in libgit.a, but *has* to be called before the
`packing_data` struct is used that contains that mutex.
This fixes https://github.com/git-for-windows/git/issues/1839.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
There is a problem in the way 9ac3f0e5b3 (pack-objects: fix
performance issues on packing large deltas, 2018-07-22) initializes that
mutex in the `packing_data` struct. The problem manifests in a
segmentation fault on Windows, when a mutex (AKA critical section) is
accessed without being initialized. (With pthreads, you apparently do
not really have to initialize them?)
This was reported in https://github.com/git-for-windows/git/issues/1839.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This trick was performed by rebasing the builtin-stash-rebase-v2 branch
thicket via `git rebase -ki --rebase-merges=rebase-cousins v2.19.1`,
replacing all branches that made it into `pu` by their current versions
(and also the builtin-stash by the newest iteration as of ungps/git),
labeling the branch as `builtin-stash-rebase-v3` and then replacing it
in the `merge` command in the todo list.
We did have to rebase the "cousins" because the initial merge of a
merging-rebase will confuse the merge-base logic (and hence the changes
would be dropped when we try to merge them "again").
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Git for Windows accepts pull requests; Core Git does not. Therefore we
need to adjust the template (because it only matches core Git's
project management style, not ours).
Also: direct Git for Windows enhancements to their contributions page,
space out the text for easy reading, and clarify that the mailing list
is plain text, not HTML.
Signed-off-by: Philip Oakley <philipoakley@iee.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Getting started contributing to Git can be difficult on a Windows
machine. CONTRIBUTING.md contains a guide to getting started, including
detailed steps for setting up build tools, running tests, and
submitting patches to upstream.
[includes an example by Pratik Karki how to submit v2, v3, v4, etc.]
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
It is better to state clearly expectations and intentions than to assume
quietly that everybody agrees.
This Code of Conduct is the Open Code of Conduct as per
http://todogroup.org/opencodeofconduct/ (the only modifications are the
adjustments to reflect that there is no "response team" in addition to the
Git for Windows maintainer, and the addition of the link to the Open Code
of Conduct itself).
[Completely revamped, based on the Covenant 1.4 by Brendan Forster]
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Completely convert the pathname expoted in the %msvc_bin_dir_msys%
variable to MSYS format with forward slashes rather than a mixture
of forward and back slashes.
This solves an obscure problem observed by some developers:
[...]
http-push.c
CC remote-curl.o
remote-curl.c
* new script parameters
GEN git-instaweb
sed: -e expression #7, char 155: invalid reference \2 on `s' command's RHS
make: *** [Makefile:2023: git-instaweb] Error 1
Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Add new condition to invoke vcpkg_install.bat: it's not enough to check
the presence of folder vcpkg. We need to check the presence of some
header files because this is one of the main goals of this script.
Previous build attempt could be aborted, so the folder will exist but
the project will not be built properly.
Signed-off-by: Olga Telezhnaia <olyatelezhnaya@gmail.com>
This is part two of the Ctrl+C story, where part one is
https://github.com/git-for-windows/MSYS2-packages/commit/f4fda0f30aa.
Part one took care of extending the signal handling in the MSYS2 runtime
such that non-MSYS2 processes "receive" a SIGINT by injecting a remote
thread that runs kernel32!CtrlRoutine as if GenerateConsoleCtrlHandler()
had been called (but in contrast to the latter, only one process is
targeted at a time, not every process attached to the same Console) into
the process that needs to be interrupted as well as into all of the
spawned child processes.
Part two now takes care of removing the misguided "kill all spawned
children" atexit() handler, and it also installs a ConsoleCtrl handler
to run Git's SIGINT handlers, such as the one waiting for the pager to
exit.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
... even if they may look like them.
As looking up the target of the "symbolic link" (just to see whether it
starts with `/ContainerMappedDirectories/`) is pretty expensive, we
do it when we can be *really* sure that there is a possibility that this
might be the case.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: JiSeop Moon <zcube@zcube.kr>
Previously, we did not install any handler for Ctrl+C, but now we really
want to because the MSYS2 runtime learned the trick to call the
ConsoleCtrlHandler when Ctrl+C was pressed.
With this, hitting Ctrl+C while `git log` is running will only terminate
the Git process, but not the pager. This finally matches the behavior on
Linux and on macOS.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
In preparation for making this function a bit more complicated (to allow
for special-casing the `ContainerMappedDirectories` in Windows
containers, which look like a symbolic link, but are not), let's move it
out of the header.
Signed-off-by: JiSeop Moon <zcube@zcube.kr>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
It is a known issue that a rename() can fail with an "Access denied"
error at times, when copying followed by deleting the original file
works. Let's just fall back to that behavior.
Signed-off-by: JiSeop Moon <zcube@zcube.kr>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Git documentation refers to $HOME and $XDG_CONFIG_HOME often, but does not specify how or where these values come from on Windows where neither is set by default. The new documentation reflects the behavior of setup_windows_environment() in compat/mingw.c.
Signed-off-by: Alejandro Barreto <alejandro.barreto@ni.com>
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>
This fixes the issue identified in
https://github.com/git-for-windows/git/issues/1498
where Git would not fall back to reading credentials from a Win32
Console when the credentials could not be read from the terminal via the
Bash hack (that is necessary to support running in a MinTTY).
Tested in a Powershell window.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
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>
We ran out of GUIDs in the script generating Visual Studio project
files. This topic branch fixes that issue once and for all, by
generating the GUIDs.
For extra goodness, we now generate GUIDs that are not random, but are
generated from the SHA-256 checksums of the target file of the project.
That way, the project<->GUID mapping is stable.
This fixes https://github.com/git-for-windows/git/issues/1507
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>