summaryrefslogtreecommitdiffstats
path: root/compat (follow)
Commit message (Collapse)AuthorAgeFilesLines
* Merge branch 'js/mingw-rename-fix'Junio C Hamano2024-12-231-1/+1
|\ | | | | | | | | | | | | | | Update the way rename() emulation on Windows handle directories to correct an earlier attempt to do the same. * js/mingw-rename-fix: mingw_rename: do support directory renames
| * mingw_rename: do support directory renamesJohannes Schindelin2024-12-171-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In 391bceae435 (compat/mingw: support POSIX semantics for atomic renames, 2024-10-27), we taught the `mingw_rename()` function to respect POSIX semantics, but we did so only as a fallback after `_wrename()` fails. This hid a bug in the implementation that was not caught by Git's test suite: The `CreateFileW()` function _can_ open handles to directories, but not when asked to use the `FILE_ATTRIBUTE_NORMAL` flag, as that flag only is allowed for files. Let's fix this by using the common `FILE_FLAG_BACKUP_SEMANTICS` flag that can be used for opening handles to directories, too. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | global: trivial conversions to fix `-Wsign-compare` warningsPatrick Steinhardt2024-12-062-8/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | We have a bunch of loops which iterate up to an unsigned boundary using a signed index, which generates warnigs because we compare a signed and unsigned value in the loop condition. Address these sites for trivial cases and enable `-Wsign-compare` warnings for these code units. This patch only adapts those code units where we can drop the `DISABLE_SIGN_COMPARE_WARNINGS` macro in the same step. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt2024-12-066-0/+11
| | | | | | | | | | | | | | | | | | Mark code units that generate warnings with `-Wsign-compare`. This allows for a structured approach to get rid of all such warnings over time in a way that can be easily measured. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | compat/win32: fix -Wsign-compare warning in "wWinMain()"Patrick Steinhardt2024-12-061-8/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | GCC generates a warning in "headless.c" because we compare `slash` with `size`, where the former is an `int` and the latter is a `size_t`. Fix the warning by storing `slash` as a `size_t`, as well. This commit is being singled out because the file does not include the "git-compat-util.h" header, and consequently, we cannot easily mark it with the `DISABLE_SIGN_COMPARE_WARNING` macro. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | compat/regex: explicitly ignore "-Wsign-compare" warningsPatrick Steinhardt2024-12-061-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Explicitly ignore "-Wsign-compare" warnings in our bundled copy of the regcomp implementation. We don't use the macro introduced in the preceding commit because this code does not include "git-compat-util.h" in the first place. Note that we already directly use "#pragma GCC diagnostic ignored" in "regcomp.c", so it shouldn't be an issue to use it directly in the new spot, either. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'ps/mingw-rename'Junio C Hamano2024-11-131-6/+151
|\| | | | | | | | | | | | | | | | | | | | | The MinGW compatibility layer has been taught to support POSIX semantics for atomic renames when other process(es) have a file opened at the destination path. * ps/mingw-rename: compat/mingw: support POSIX semantics for atomic renames compat/mingw: allow deletion of most opened files compat/mingw: share file handles created via `CreateFileW()`
| * compat/mingw: support POSIX semantics for atomic renamesPatrick Steinhardt2024-11-061-4/+83
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | By default, Windows restricts access to files when those files have been opened by another process. As explained in the preceding commits, these restrictions can be loosened such that reads, writes and/or deletes of files with open handles _are_ allowed. While we set up those sharing flags in most relevant code paths now, we still don't properly handle POSIX-style atomic renames in case the target path is open. This is failure demonstrated by t0610, where one of our tests spawns concurrent writes in a reftable-enabled repository and expects all of them to succeed. This test fails most of the time because the process that has acquired the "tables.list" lock is unable to rename it into place while other processes are busy reading that file. Windows 10 has introduced the `FILE_RENAME_FLAG_POSIX_SEMANTICS` flag that allows us to fix this usecase [1]. When set, it is possible to rename a file over a preexisting file even when the target file still has handles open. Those handles must have been opened with the `FILE_SHARE_DELETE` flag, which we have ensured in the preceding commits. Careful readers might have noticed that [1] does not mention the above flag, but instead mentions `FILE_RENAME_POSIX_SEMANTICS`. This flag is not for use with `SetFileInformationByHandle()` though, which is what we use. And while the `FILE_RENAME_FLAG_POSIX_SEMANTICS` flag exists, it is not documented on [2] or anywhere else as far as I can tell. Unfortunately, we still support Windows systems older than Windows 10 that do not yet have this new flag. Our `_WIN32_WINNT` SDK version still targets 0x0600, which is Windows Vista and later. And even though that Windows version is out-of-support, bumping the SDK version all the way to 0x0A00, which is Windows 10 and later, is not an option as it would make it impossible to compile on Windows 8.1, which is still supported. Instead, we have to manually declare the relevant infrastructure to make this feature available and have fallback logic in place in case we run on a Windows version that does not yet have this flag. On another note: `mingw_rename()` has a retry loop that is used in case deleting a file failed because it's still open in another process. One might be pressed to not use this loop anymore when we can use POSIX semantics. But unfortunately, we have to keep it around due to our dependence on the `FILE_SHARE_DELETE` flag. While we know to set that sharing flag now, other applications may not do so and may thus still cause sharing violations when we try to rename a file. This fixes concurrent writes in the reftable backend as demonstrated in t0610, but may also end up fixing other usecases where Git wants to perform renames. [1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_rename_information [2]: https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_rename_info Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com> Reviewed-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * compat/mingw: allow deletion of most opened filesPatrick Steinhardt2024-10-281-0/+66
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On Windows, we emulate open(3p) via `mingw_open()`. This function implements handling of some platform-specific quirks that are required to make it behave as closely as possible like open(3p) would, but for most cases we just call the Windows-specific `_wopen()` function. This function has a major downside though: it does not allow us to specify the sharing mode. While there is `_wsopen()` that allows us to pass sharing flags, those sharing flags are not the same `FILE_SHARE_*` flags as `CreateFileW()` accepts. Instead, `_wsopen()` only allows concurrent read- and write-access, but does not allow for concurrent deletions. Unfortunately though, we have to allow concurrent deletions if we want to have POSIX-style atomic renames on top of an existing file that has open file handles. Implement a new function that emulates open(3p) for existing files via `CreateFileW()` such that we can set the required sharing flags. While we have the same issue when calling open(3p) with `O_CREAT`, implementing that mode would be more complex due to the required permission handling. Furthermore, atomic updates via renames typically write to exclusive lockfile and then perform the rename, and thus we don't have to handle the case where the locked path has been created with `O_CREATE`. So while it would be nice to have proper POSIX semantics in all paths, we instead aim for a minimum viable fix here. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
| * compat/mingw: share file handles created via `CreateFileW()`Patrick Steinhardt2024-10-281-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Unless told otherwise, Windows will keep other processes from reading, writing and deleting files when one has an open handle that was created via `CreateFileW()`. This behaviour can be altered via `FILE_SHARE_*` flags: - `FILE_SHARE_READ` allows a concurrent process to open the file for reading. - `FILE_SHARE_WRITE` allows a concurrent process to open the file for writing. - `FILE_SHARE_DELETE` allows a concurrent process to delete the file or to replace it via an atomic rename. This sharing mechanism is quite important in the context of Git, as we assume POSIX semantics all over the place. But there are two callsites where we don't pass all three of these flags: - We don't set `FILE_SHARE_DELETE` when creating a file for appending via `mingw_open_append()`. This makes it impossible to delete the file from another process or to replace it via an atomic rename. The function was introduced via d641097589 (mingw: enable atomic O_APPEND, 2018-08-13) and has been using `FILE_SHARE_READ | FILE_SHARE_WRITE` since the inception. There aren't any indicators that the omission of `FILE_SHARE_DELETE` was intentional. - We don't set any sharing flags in `mingw_utime()`, which changes the access and modification of a file. This makes it impossible to perform any kind of operation on this file at all from another process. While we only open the file for a short amount of time to update its timestamps, this still opens us up for a race condition with another process. `mingw_utime()` was originally implemented via `_wopen()`, which doesn't give you full control over the sharing mode. Instead, it calls `_wsopen()` with `_SH_DENYNO`, which ultimately translates to `FILE_SHARE_READ | FILE_SHARE_WRITE`. It was then refactored via 090a3085bc (t/helper/test-chmtime: update mingw to support chmtime on directories, 2022-03-02) to use `CreateFileW()`, but we stopped setting any sharing flags at all, which seems like an unintentional side effect. By restoring `FILE_SHARE_READ | FILE_SHARE_WRITE` we thus fix this and get back the old behaviour of `_wopen()`. The fact that we didn't set the equivalent of `FILE_SHARE_DELETE` can be explained, as well: neither `_wopen()` nor `_wsopen()` allow you to do so. So overall, it doesn't seem intentional that we didn't allow deletions here, either. Adapt both of these callsites to pass all three sharing flags. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
* | Merge branch 'sk/msvc-warnings'Taylor Blau2024-10-253-12/+21
|\ \ | | | | | | | | | | | | | | | | | | Fixes compile time warnings with 64-bit MSVC. * sk/msvc-warnings: mingw.c: Fix complier warnings for a 64 bit msvc
| * | mingw.c: Fix complier warnings for a 64 bit msvcSören Krecker2024-10-173-12/+21
| |/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Remove some complier warnings from msvc in compat/mingw.c for value truncation from 64 bit to 32 bit integers. Compiling compat/mingw.c under a 64 bit version of msvc produces warnings. An "int" is 32 bit, and ssize_t or size_t should be 64 bit long. Prepare compat/vcbuild/include/unistd.h to have a 64 bit type _ssize_t, when _WIN64 is defined and 32 bit otherwise. Further down in this include file, as before, ssize_t is defined as _ssize_t, if needed. Use size_t instead of int for all variables that hold the result of strlen() or wcslen() (which cannot be negative). Use ssize_t to hold the return value of read(). Signed-off-by: Sören Krecker <soekkle@freenet.de> Signed-off-by: Taylor Blau <me@ttaylorr.com>
* | Merge branch 'ak/typofixes'Taylor Blau2024-10-253-4/+4
|\ \ | |/ |/| | | | | | | | | | | | | | | | | | | Typofixes. * ak/typofixes: t: fix typos t/helper: fix a typo t/perf: fix typos t/unit-tests: fix typos contrib: fix typos compat: fix typos
| * compat: fix typosAndrew Kreimer2024-10-103-4/+4
| | | | | | | | | | | | | | | | Fix typos and grammar. Reported-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Andrew Kreimer <algonell@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'jk/fsmonitor-event-listener-race-fix'Taylor Blau2024-10-155-11/+82
|\ \ | |/ |/| | | | | | | | | | | | | | | On macOS, fsmonitor can fall into a race condition that results in a client waiting forever to be notified for an event that have already happened. This problem has been corrected. * jk/fsmonitor-event-listener-race-fix: fsmonitor: initialize fs event listener before accepting clients simple-ipc: split async server initialization and running
| * fsmonitor: initialize fs event listener before accepting clientsJeff King2024-10-082-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There's a racy hang in fsmonitor on macOS that we sometimes see in CI. When we serve a client, what's supposed to happen is: 1. The client thread calls with_lock__wait_for_cookie() in which we create a cookie file and then wait for a pthread_cond event 2. The filesystem event listener sees the cookie file creation, does some internal book-keeping, and then triggers the pthread_cond. But there's a problem: we start the listener that accepts client threads before we start the fs event thread. So it's possible for us to accept a client which creates the cookie file and starts waiting before the fs event thread is initialized, and we miss those filesystem events entirely. That leaves the client thread hanging forever. In CI, the symptom is that t9210 (which is testing scalar, which always enables fsmonitor under the hood) may hang forever in "scalar clone". It is waiting on "git fetch" which is waiting on the fsmonitor daemon. The race happens more frequently under load, but you can trigger it predictably with a sleep like this, which delays the start of the fs event thread: --- a/compat/fsmonitor/fsm-listen-darwin.c +++ b/compat/fsmonitor/fsm-listen-darwin.c @@ -510,6 +510,7 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state) FSEventStreamSetDispatchQueue(data->stream, data->dq); data->stream_scheduled = 1; + sleep(1); if (!FSEventStreamStart(data->stream)) { error(_("Failed to start the FSEventStream")); goto force_error_stop_without_loop; One solution might be to reverse the order of initialization: start the fs event thread before we start the thread listening for clients. But the fsmonitor code explicitly does it in the opposite direction. The fs event thread wants to refer to the ipc_server_data struct, so we need it to be initialized first. A further complication is that we need a signal from the fs event thread that it is actually ready and listening. And those details happen within backend-specific fsmonitor code, whereas the initialization is in the shared code. So instead, let's use the ipc_server init/start split added in the previous commit. The generic fsmonitor code will init the ipc_server but _not_ start it, leaving that to the backend specific code, which now needs to call ipc_server_start_async() at the right time. For macOS, that is right after we start the FSEventStream that you can see in the diff above. It's not clear to me if Windows suffers from the same problem (and we simply don't trigger it in CI), or if it is immune. Regardless, the obvious place to start accepting clients there is right after we've established the ReadDirectoryChanges watch. This makes the hangs go away in our macOS CI environment, even when compiled with the sleep() above. Helped-by: Koji Nakamaru <koji.nakamaru@gree.net> Signed-off-by: Jeff King <peff@peff.net> Acked-by: Koji Nakamaru <koji.nakamaru@gree.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * simple-ipc: split async server initialization and runningJeff King2024-10-083-11/+70
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To start an async ipc server, you call ipc_server_run_async(). That initializes the ipc_server_data object, and starts all of the threads running, which may immediately start serving clients. This can create some awkward timing problems, though. In the fsmonitor daemon (the sole user of the simple-ipc system), we want to create the ipc server early in the process, which means we may start serving clients before the rest of the daemon is fully initialized. To solve this, let's break run_async() into two parts: an initialization which allocates all data and spawns the threads (without letting them run), and a start function which actually lets them begin work. Since we have two simple-ipc implementations, we have to handle this twice: - in ipc-unix-socket.c, we have a central listener thread which hands connections off to worker threads using a work_available mutex. We can hold that mutex after init, and release it when we're ready to start. We do need an extra "started" flag so that we know whether the main thread is holding the mutex or not (e.g., if we prematurely stop the server, we want to make sure all of the worker threads are released to hear about the shutdown). - in ipc-win32.c, we don't have a central mutex. So we'll introduce a new startup_barrier mutex, which we'll similarly hold until we're ready to let the threads proceed. We again need a "started" flag here to make sure that we release the barrier mutex when shutting down, so that the sub-threads can proceed to the finish. I've renamed the run_async() function to init_async() to make sure we catch all callers, since they'll now need to call the matching start_async(). We could leave run_async() as a wrapper that does both, but there's not much point. There are only two callers, one of which is fsmonitor, which will want to actually do work between the two calls. And the other is just a test-tool wrapper. For now I've added the start_async() calls in fsmonitor where they would otherwise have happened, so there should be no behavior change with this patch. Signed-off-by: Jeff King <peff@peff.net> Acked-by: Koji Nakamaru <koji.nakamaru@gree.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'ps/environ-wo-the-repository'Junio C Hamano2024-09-232-0/+4
|\ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Code clean-up. * ps/environ-wo-the-repository: (21 commits) environment: stop storing "core.notesRef" globally environment: stop storing "core.warnAmbiguousRefs" globally environment: stop storing "core.preferSymlinkRefs" globally environment: stop storing "core.logAllRefUpdates" globally refs: stop modifying global `log_all_ref_updates` variable branch: stop modifying `log_all_ref_updates` variable repo-settings: track defaults close to `struct repo_settings` repo-settings: split out declarations into a standalone header environment: guard state depending on a repository environment: reorder header to split out `the_repository`-free section environment: move `set_git_dir()` and related into setup layer environment: make `get_git_namespace()` self-contained environment: move object database functions into object layer config: make dependency on repo in `read_early_config()` explicit config: document `read_early_config()` and `read_very_early_config()` environment: make `get_git_work_tree()` accept a repository environment: make `get_graft_file()` accept a repository environment: make `get_index_file()` accept a repository environment: make `get_object_directory()` accept a repository environment: make `get_git_common_dir()` accept a repository ...
| * | environment: guard state depending on a repositoryPatrick Steinhardt2024-09-122-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In "environment.h" we have quite a lot of functions and variables that either explicitly or implicitly depend on `the_repository`. The implicit set of stateful declarations includes for example variables which get populated when parsing a repository's Git configuration. This set of variables is broken by design, as their state often depends on the last repository config that has been parsed. So they may or may not represent the state of `the_repository`. Fixing that is quite a big undertaking, and later patches in this series will demonstrate a solution for a first small set of those variables. So for now, let's guard these with `USE_THE_REPOSITORY_VARIABLE` so that callers are aware of the implicit dependency. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Merge branch 'rj/compat-terminal-unused-fix'Junio C Hamano2024-09-101-1/+1
|\ \ \ | | |/ | |/| | | | | | | | | | | | | Build fix. * rj/compat-terminal-unused-fix: compat/terminal: mark parameter of git_terminal_prompt() UNUSED
| * | compat/terminal: mark parameter of git_terminal_prompt() UNUSEDRamsay Jones2024-09-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If neither HAVE_DEV_TTY nor GIT_WINDOWS_NATIVE is set, the fallback code calls the system getpass(). This unfortunately ignores the "echo" boolean parameter, as we have no way to implement that functionality. But we still have to keep the unused parameter, since our interface has to match the other implementations. Co-authored-by: Jeff King <peff@peff.net> Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | compat: mark unused parameters in win32/mingw functionsJeff King2024-08-288-23/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The compat/ directory contains many stub functions, wrappers, and so on that have to conform to a specific interface, but don't necessarily need to use all of their parameters. Let's mark them to avoid complaints from -Wunused-parameter. This was done mostly via guess-and-check with the Windows build in GitHub CI. I also confirmed that the win+VS build is similarly happy. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | compat: disable -Wunused-parameter in win32/headless.cJeff King2024-08-281-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As with the files touched in the previous commit, win32/headless.c does not include git-compat-util.h, so it doesn't have our UNUSED macro. Unlike those ones, this is not third-party code, so it would not be a big deal to modify it. However, I'm not sure if including git-compat-util.h would create other headaches (and I don't even have a machine to test this on; I'm relying on Windows CI to compile it at all). Given how trivial the file is, and that the unused parameters are not interesting (they are just boilerplate for the wWinMain() function), we can just use the same trick as the previous commit and disable the warnings via pragma. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | compat: disable -Wunused-parameter in 3rd-party codeJeff King2024-08-282-0/+4
| |/ |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We carry some vendored 3rd-party code in compat/ that does not build cleanly with -Wunused-parameters. We could mark these with UNUSED, but there are two reasons not to: 1. This is code imported from elsewhere, so we'd prefer to avoid modifying it in an invasive way that could create conflicts if we tried to pull in a new version. 2. These files don't include git-compat-util.h at all, so we'd need to factor out (or repeat) our UNUSED macro. In theory we could modify the build process to invoke the compiler with the extra warning disabled for these files, but there are tricky corner cases there (e.g., for NO_REGEX we cannot assume that the compiler understands -Wno-unused-parameter as an option, so we'd have to use our detect-compiler script). Instead, let's rely on the gcc diagnostic #pragma. This is horribly unportable, of course, but it should do what we want. Compilers which don't understand this particular pragma should ignore it (per the standard), and compilers which do care about "-Wunused-parameter" will hopefully respect it, even if they are not gcc (e.g., clang does). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | global: prepare for hiding away repo-less config functionsPatrick Steinhardt2024-08-132-0/+3
|/ | | | | | | | | | | | We're about to hide config functions that implicitly depend on `the_repository` behind the `USE_THE_REPOSITORY_VARIABLE` macro. This will uncover a bunch of dependents that transitively relied on the global variable, but didn't define the macro yet. Adapt them such that we define the macro to prepare for this change. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* mingw(is_msys2_sh): handle forward slashes in the `sh.exe` path, tooJohannes Schindelin2024-07-141-1/+1
| | | | | | | | | | | | | | | | | | | Whether the full path to the MSYS2 Bash is specified using backslashes or forward slashes, in either case the command-line arguments need to be quoted in the MSYS2-specific manner instead of using regular Win32 command-line quoting rules. In preparation for `prepare_shell_cmd()` to use the full path to `sh.exe` (with forward slashes for consistency), let's teach the `is_msys2_sh()` function about this; Otherwise 5580.4 'clone with backslashed path' would fail once `prepare_shell_cmd()` uses the full path instead of merely `sh`. This patch relies on the just-introduced fix where `fspathcmp()` handles backslashes and forward slashes as equivalent on Windows. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* win32: override `fspathcmp()` with a directory separator-aware versionJohannes Schindelin2024-07-142-0/+41
| | | | | | | | | | | | | | | | | | | | On Windows, the backslash is the directory separator, even if the forward slash can be used, too, at least since Windows NT. This means that the paths `a/b` and `a\b` are equivalent, and `fspathcmp()` needs to be made aware of that fact. Note that we have to override both `fspathcmp()` and `fspathncmp()`, and the former cannot be a mere pre-processor constant that transforms calls to `fspathcmp(a, b)` into `fspathncmp(a, b, (size_t)-1)` because the function `report_collided_checkout()` in `unpack-trees.c` wants to assign `list.cmp = fspathcmp`. Also note that `fspatheq()` does _not_ need to be overridden because it calls `fspathcmp()` internally. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* Merge branch 'ps/use-the-repository'Junio C Hamano2024-07-023-4/+7
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A CPP macro USE_THE_REPOSITORY_VARIABLE is introduced to help transition the codebase to rely less on the availability of the singleton the_repository instance. * ps/use-the-repository: hex: guard declarations with `USE_THE_REPOSITORY_VARIABLE` t/helper: remove dependency on `the_repository` in "proc-receive" t/helper: fix segfault in "oid-array" command without repository t/helper: use correct object hash in partial-clone helper compat/fsmonitor: fix socket path in networked SHA256 repos replace-object: use hash algorithm from passed-in repository protocol-caps: use hash algorithm from passed-in repository oidset: pass hash algorithm when parsing file http-fetch: don't crash when parsing packfile without a repo hash-ll: merge with "hash.h" refs: avoid include cycle with "repository.h" global: introduce `USE_THE_REPOSITORY_VARIABLE` macro hash: require hash algorithm in `empty_tree_oid_hex()` hash: require hash algorithm in `is_empty_{blob,tree}_oid()` hash: make `is_null_oid()` independent of `the_repository` hash: convert `oidcmp()` and `oideq()` to compare whole hash global: ensure that object IDs are always padded hash: require hash algorithm in `oidread()` and `oidclr()` hash: require hash algorithm in `hasheq()`, `hashcmp()` and `hashclr()` hash: drop (mostly) unused `is_empty_{blob,tree}_sha1()` functions
| * compat/fsmonitor: fix socket path in networked SHA256 reposPatrick Steinhardt2024-06-141-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The IPC socket used by the fsmonitor on Darwin is usually contained in the Git repository itself. When the repository is hosted on a networked filesystem though, we instead create the socket path in the user's home directory or the socket directory. In that case, we derive the path by hashing the repository path. But while we always use SHA1 to hash the repository path, we then end up using `hash_to_hex()` to append the computed hash to the socket path. This is wrong because `hash_to_hex()` uses the hash algorithm configured in `the_repository`, which may not be SHA1. The consequence is that we may append uninitialized bytes to the path when operating in a SHA256 repository. Fix this bug by using `hash_to_hex_algop()` with SHA1. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * hash-ll: merge with "hash.h"Patrick Steinhardt2024-06-141-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The "hash-ll.h" header was introduced via d1cbe1e6d8 (hash-ll.h: split out of hash.h to remove dependency on repository.h, 2023-04-22) to make explicit the split between hash-related functions that rely on the global `the_repository`, and those that don't. This split is no longer necessary now that we we have removed the reliance on `the_repository`. Merge "hash-ll.h" back into "hash.h". This causes some code units to not include "repository.h" anymore, which requires us to add some forward declarations. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * global: introduce `USE_THE_REPOSITORY_VARIABLE` macroPatrick Steinhardt2024-06-141-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Use of the `the_repository` variable is deprecated nowadays, and we slowly but steadily convert the codebase to not use it anymore. Instead, callers should be passing down the repository to work on via parameters. It is hard though to prove that a given code unit does not use this variable anymore. The most trivial case, merely demonstrating that there is no direct use of `the_repository`, is already a bit of a pain during code reviews as the reviewer needs to manually verify claims made by the patch author. The bigger problem though is that we have many interfaces that implicitly rely on `the_repository`. Introduce a new `USE_THE_REPOSITORY_VARIABLE` macro that allows code units to opt into usage of `the_repository`. The intent of this macro is to demonstrate that a certain code unit does not use this variable anymore, and to keep it from new dependencies on it in future changes, be it explicit or implicit For now, the macro only guards `the_repository` itself as well as `the_hash_algo`. There are many more known interfaces where we have an implicit dependency on `the_repository`, but those are not guarded at the current point in time. Over time though, we should start to add guards as required (or even better, just remove them). Define the macro as required in our code units. As expected, most of our code still relies on the global variable. Nearly all of our builtins rely on the variable as there is no way yet to pass `the_repository` to their entry point. For now, declare the macro in "biultin.h" to keep the required changes at least a little bit more contained. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'js/mingw-remove-unused-extern-decl'Junio C Hamano2024-06-271-1/+0
|\ \ | | | | | | | | | | | | | | | | | | | | | An unused extern declaration for mingw has been removed to prevent it from causing build failure. * js/mingw-remove-unused-extern-decl: mingw: drop bogus (and unneeded) declaration of `_pgmptr`
| * | mingw: drop bogus (and unneeded) declaration of `_pgmptr`Johannes Schindelin2024-06-201-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In 08809c09aa13 (mingw: add a helper function to attach GDB to the current process, 2020-02-13), I added a declaration that was not needed. Back then, that did not matter, but now that the declaration of that symbol was changed in mingw-w64's headers, it causes the following compile error: CC compat/mingw.o compat/mingw.c: In function 'open_in_gdb': compat/mingw.c:35:9: error: function declaration isn't a prototype [-Werror=strict-prototypes] 35 | extern char *_pgmptr; | ^~~~~~ In file included from C:/git-sdk-64/usr/src/git/build-installers/mingw64/lib/gcc/x86_64-w64-mingw32/14.1.0/include/mm_malloc.h:27, from C:/git-sdk-64/usr/src/git/build-installers/mingw64/lib/gcc/x86_64-w64-mingw32/14.1.0/include/xmmintrin.h:34, from C:/git-sdk-64/usr/src/git/build-installers/mingw64/lib/gcc/x86_64-w64-mingw32/14.1.0/include/immintrin.h:31, from C:/git-sdk-64/usr/src/git/build-installers/mingw64/lib/gcc/x86_64-w64-mingw32/14.1.0/include/x86intrin.h:32, from C:/git-sdk-64/usr/src/git/build-installers/mingw64/include/winnt.h:1658, from C:/git-sdk-64/usr/src/git/build-installers/mingw64/include/minwindef.h:163, from C:/git-sdk-64/usr/src/git/build-installers/mingw64/include/windef.h:9, from C:/git-sdk-64/usr/src/git/build-installers/mingw64/include/windows.h:69, from C:/git-sdk-64/usr/src/git/build-installers/mingw64/include/winsock2.h:23, from compat/../git-compat-util.h:215, from compat/mingw.c:1: compat/mingw.c:35:22: error: '__p__pgmptr' redeclared without dllimport attribute: previous dllimport ignored [-Werror=attributes] 35 | extern char *_pgmptr; | ^~~~~~~ Let's just drop the declaration and get rid of this compile error. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | compat/win32: fix const-correctness with string constantsPatrick Steinhardt2024-06-073-15/+31
| | | | | | | | | | | | | | | | | | | | | | | | Adjust various places in our Win32 compatibility layer where we are not assigning string constants to `const char *` variables. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | global: improve const correctness when assigning string constantsPatrick Steinhardt2024-06-071-1/+1
| |/ |/| | | | | | | | | | | | | | | We're about to enable `-Wwrite-strings`, which changes the type of string constants to `const char[]`. Fix various sites where we assign such constants to non-const variables. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | Merge branch 'jc/compat-regex-calloc-fix'Junio C Hamano2024-05-203-13/+13
|\ \ | | | | | | | | | | | | | | | | | | | | | | | | Windows CI running in GitHub Actions started complaining about the order of arguments given to calloc(); the imported regex code uses the wrong order almost consistently, which has been corrected. * jc/compat-regex-calloc-fix: compat/regex: fix argument order to calloc(3)
| * | compat/regex: fix argument order to calloc(3)Junio C Hamano2024-05-133-13/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Windows compiler suddenly started complaining that calloc(3) takes its arguments in <nmemb, size> order. Indeed, there are many calls that has their arguments in a _wrong_ order. Fix them all. A sample breakage can be seen at https://github.com/git/git/actions/runs/9046793153/job/24857988702#step:4:272 Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * | nedmalloc: avoid new compile errorJohannes Schindelin2023-03-121-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GCC v12.x complains thusly: compat/nedmalloc/nedmalloc.c: In function 'DestroyCaches': compat/nedmalloc/nedmalloc.c:326:12: error: the comparison will always evaluate as 'true' for the address of 'caches' will never be NULL [-Werror=address] 326 | if(p->caches) | ^ compat/nedmalloc/nedmalloc.c:196:22: note: 'caches' declared here 196 | threadcache *caches[THREADCACHEMAXCACHES]; | ^~~~~~ ... and it is correct, of course. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * | compat/win32/syslog: fix use-after-reallocJohannes Schindelin2023-03-121-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Git for Windows' SDK recently upgraded to GCC v12.x which points out that the `pos` variable might be used even after the corresponding memory was `realloc()`ed and therefore potentially no longer valid. Since a subset of this SDK is used in Git's CI/PR builds, we need to fix this to continue to be able to benefit from the CI/PR runs. Note: This bug has been with us since 2a6b149c64f6 (mingw: avoid using strbuf in syslog, 2011-10-06), and while it looks tempting to replace the hand-rolled string manipulation with a `strbuf`-based one, that commit's message explains why we cannot do that: The `syslog()` function is called as part of the function in `daemon.c` which is set as the `die()` routine, and since `strbuf_grow()` can call that function if it runs out of memory, this would cause a nasty infinite loop that we do not want to re-introduce. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | win32: fix building with NO_UNIX_SOCKETSMike Hommey2024-05-031-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After 2406bf5f (Win32: detect unix socket support at runtime, 2024-04-03), it fails with: compat/mingw.c:4160:5: error: no previous prototype for function 'mingw_have_unix_sockets' [-Werror,-Wmissing-prototypes] 4160 | int mingw_have_unix_sockets(void) | ^ because the prototype is behind `ifndef NO_UNIX_SOCKETS`. Signed-off-by: Mike Hommey <mh@glandium.org> Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Win32: detect unix socket support at runtimeMatthias Aßhauer2024-04-032-0/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Windows 10 build 17063 introduced support for unix sockets to Windows. bb390b1 (git-compat-util: include declaration for unix sockets in windows, 2021-09-14) introduced a way to build git with unix socket support on Windows, but you still had to decide at build time which Windows version the compiled executable was supposed to run on. We can detect at runtime wether the operating system supports unix sockets and act accordingly for all supported Windows versions. This fixes https://github.com/git-for-windows/git/issues/3892 Signed-off-by: Matthias Aßhauer <mha1993@live.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | Merge branch 'jc/no-include-of-compat-util-from-headers'Junio C Hamano2024-03-052-2/+0
|\ \ \ | |_|/ |/| | | | | | | | | | | | | | Header file clean-up. * jc/no-include-of-compat-util-from-headers: compat: drop inclusion of <git-compat-util.h>
| * | compat: drop inclusion of <git-compat-util.h>Junio C Hamano2024-02-242-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | These two header files are included from ordinary source files that already include <git-compat-util.h> as the first header file as they should. There is no need to include the compat-util in these headers. "make hdr-check" is not affected, as it is designed to assume that what <git-compat-util.h> offers is available to everybody without being included. Signed-off-by: Junio C Hamano <gitster@pobox.com>
| * | Merge branch 'js/win32-retry-pipe-write-on-enospc' into maint-2.43Junio C Hamano2024-02-131-4/+15
| |\ \ | | | | | | | | | | | | | | | | | | | | | | | | Update to the code that writes to pipes on Windows. * js/win32-retry-pipe-write-on-enospc: win32: special-case `ENOSPC` when writing to a pipe
| * \ \ Merge branch 'en/header-cleanup' into maint-2.43Junio C Hamano2024-02-095-4/+3
| |\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Remove unused header "#include". * en/header-cleanup: treewide: remove unnecessary includes in source files treewide: add direct includes currently only pulled in transitively trace2/tr2_tls.h: remove unnecessary include submodule-config.h: remove unnecessary include pkt-line.h: remove unnecessary include line-log.h: remove unnecessary include http.h: remove unnecessary include fsmonitor--daemon.h: remove unnecessary includes blame.h: remove unnecessary includes archive.h: remove unnecessary include treewide: remove unnecessary includes in source files treewide: remove unnecessary includes from header files
* | \ \ \ Merge branch 'js/win32-retry-pipe-write-on-enospc'Junio C Hamano2024-02-061-4/+15
|\ \ \ \ \ | | |_|/ / | |/| | | | | | | | | | | | | | | | | | | | | | | Update to the code that writes to pipes on Windows. * js/win32-retry-pipe-write-on-enospc: win32: special-case `ENOSPC` when writing to a pipe
| * | | | win32: special-case `ENOSPC` when writing to a pipeJohannes Schindelin2024-01-301-4/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since c6d3cce6f3c4 (pipe_command(): handle ENOSPC when writing to a pipe, 2022-08-17), one `write()` call that results in an `errno` value `ENOSPC` (which typically indicates out of disk space, which makes little sense in the context of a pipe) is treated the same as `EAGAIN`. However, contrary to expectations, as diagnosed in https://github.com/python/cpython/issues/101881#issuecomment-1428667015, when writing to a non-blocking pipe on Windows, an `errno` value of `ENOSPC` means something else: the write _fails_. Completely. Because more data was provided than the internal pipe buffer can handle. Somewhat surprising, considering that `write()` is allowed to write less than the specified amount, e.g. by writing only as much as fits in that buffer. But it doesn't, it writes no byte at all in that instance. Let's handle this by manually detecting when an `ENOSPC` indicates that a pipe's buffer is smaller than what needs to be written, and re-try using the pipe's buffer size as `size` parameter. It would be plausible to try writing the entire buffer in a loop, feeding pipe buffer-sized chunks, but experiments show that trying to write more than one buffer-sized chunk right after that will immediately fail because the buffer is unlikely to be drained as fast as `write()` could write again. And the whole point of a non-blocking pipe is to be non-blocking. Which means that the logic that determines the pipe's buffer size unfortunately has to be run potentially many times when writing large amounts of data to a non-blocking pipe, as there is no elegant way to cache that information between `write()` calls. It's the best we can do, though, so it has to be good enough. This fix is required to let t3701.60 (handle very large filtered diff) pass with the MSYS2 runtime provided by the MSYS2 project: Without this patch, the failed write would result in an infinite loop. This patch is not required with Git for Windows' variant of the MSYS2 runtime only because Git for Windows added an ugly work-around specifically to avoid a hang in that test case. The diff is slightly chatty because it extends an already-existing conditional that special-cases a _different_ `errno` value for pipes, and because this patch needs to account for the fact that `_get_osfhandle()` potentially overwrites `errno`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | | | Merge branch 'sk/mingw-owner-check-error-message-improvement'Junio C Hamano2024-01-201-13/+57
|\ \ \ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In addition to (rather cryptic) Security Identifiers, show username and domain in the error message when we barf on mismatch between the Git directory and the current user on Windows. * sk/mingw-owner-check-error-message-improvement: mingw: give more details about unsafe directory's ownership
| * | | | | mingw: give more details about unsafe directory's ownershipSören Krecker2024-01-101-13/+57
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Add domain/username in error message, if owner sid of repository and user sid are not equal on windows systems. Old error message: ''' fatal: detected dubious ownership in repository at 'C:/Users/test/source/repos/git' 'C:/Users/test/source/repos/git' is owned by: 'S-1-5-21-571067702-4104414259-3379520149-500' but the current user is: 'S-1-5-21-571067702-4104414259-3379520149-1001' To add an exception for this directory, call: git config --global --add safe.directory C:/Users/test/source/repos/git ''' New error message: ''' fatal: detected dubious ownership in repository at 'C:/Users/test/source/repos/git' 'C:/Users/test/source/repos/git' is owned by: DESKTOP-L78JVA6/Administrator (S-1-5-21-571067702-4104414259-3379520149-500) but the current user is: DESKTOP-L78JVA6/test (S-1-5-21-571067702-4104414259-3379520149-1001) To add an exception for this directory, call: git config --global --add safe.directory C:/Users/test/source/repos/git ''' Signed-off-by: Sören Krecker <soekkle@freenet.de> Acked-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
* | | | | | Merge branch 'en/header-cleanup'Junio C Hamano2024-01-085-4/+3
|\ \ \ \ \ \ | |_|_|/ / / |/| | | / / | | |_|/ / | |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Remove unused header "#include". * en/header-cleanup: treewide: remove unnecessary includes in source files treewide: add direct includes currently only pulled in transitively trace2/tr2_tls.h: remove unnecessary include submodule-config.h: remove unnecessary include pkt-line.h: remove unnecessary include line-log.h: remove unnecessary include http.h: remove unnecessary include fsmonitor--daemon.h: remove unnecessary includes blame.h: remove unnecessary includes archive.h: remove unnecessary include treewide: remove unnecessary includes in source files treewide: remove unnecessary includes from header files