Commit Graph

3963 Commits (seen)

Author SHA1 Message Date
Junio C Hamano 0c8b75e4c5 Merge branch 'as/utimensat-utimes' into jch
The codebase has been updated to use the newer utimensat() POSIX
function instead of the obsolescent utime(), allowing
high-precision timestamps while preserving fallback compatibility.

* as/utimensat-utimes:
  compat/posix: drop legacy <utime.h> header and shims
  treewide: use utimensat(2) instead of legacy utime(3p)
  compat/posix: introduce utimensat(2) wrapper
2026-09-21 10:04:03 -07:00
Junio C Hamano efd03c700b Merge branch 'ij/subtree-reject-v2-config' into jch
The shell script implementation of 'git subtree' has been updated to
check for the presence of the configuration file of the new Rust
implementation, preventing users from accidentally running the old
script on repositories already managed by the new tool.

* ij/subtree-reject-v2-config:
  git-subtree: Bail out if we find output from Rust rewrite (test)
  git-subtree: Bail out if we find output from Rust rewrite
2026-09-21 10:04:02 -07:00
Junio C Hamano 92a9076df4 Merge branch 'sg/precompile-git-compat-util' into jch
The 'Makefile' has been taught to precompile 'git-compat-util.h' to
speed up overall compilation, while excluding sources that do not
include the compatibility header.

* sg/precompile-git-compat-util:
  Makefile: precompile "git-compat-util.h"
  Makefile: reintroduce REFTABLE_OBJS
  cmake: remove any "$(*_OBJS)" variables when parsing Makefile for sources
  Makefile: remove XDIFF_OBJS initialization
2026-09-21 10:04:01 -07:00
Junio C Hamano c7d4b0c33d Merge branch 'ps/ref-storage-format' into jch
The terminology regarding reference storage formats has been unified
across command-line options, environment variables, configuration
variables, and source code, standardizing on the phrase "ref storage
format" (e.g., `--ref-storage-format`, `'GIT_REF_STORAGE_FORMAT'`).
Additionally, the `--ref-storage-format` option has been updated to
accept payloads in the form `<format>://<payload>`.

* ps/ref-storage-format:
  setup: allow "--ref-storage-format=" to specify a payload
  setup: rename "init.defaultRefFormat" to "init.defaultRefStorageFormat"
  t: rename GIT_TEST_DEFAULT_REF_FORMAT
  setup: rename ref storage format environment variables
  setup: refactor how we configure the ref storage format
  refs: expose function to parse reference URIs
  help: rename "default-ref-format" to "default-ref-storage-format"
  builtin/rev-parse: rename "--show-ref-format" to "--show-ref-storage-format"
  builtin/submodule: rename "--ref-format=" to "--ref-storage-format="
  builtin/refs: rename "--ref-format=" to "--ref-storage-format="
  builtin/clone: rename "--ref-format=" to "--ref-storage-format="
  builtin/init: rename "--ref-format=" to "--ref-storage-format="
  parse-options: allow for hidden aliases
2026-09-21 10:04:00 -07:00
SZEDER Gábor af36bb91f9 Makefile: reintroduce REFTABLE_OBJS
In the next commit we are about to precompile "git-compat-util.h" with
"make" to reduce build times.  But using the precompiled header should
not change what actually gets compiled, therefore a source file can
only be compiled using the precompiled header if the first included
header file is "git-compat-util.h".

The reftable source files are kind of special, because the reftable
implementation is supposed to be easily includable in other projects.
Therefore, the reftable source files don't include
"git-compat-util.h", with the sole exception of the purposefully
project-specific "reftable/system.c".  Consequently, they shouldn't be
compiled with our precompiled header.

List object files under "reftable" in the REFTABLE_OBJS Makefile
variable, so in the next commit we'll be able to easily filter them
out and keep building them the old way, without the precompiled
header.

Note that object files under "reftable/" used to be listed in
REFTABLE_OBJS so we could build a static library from them.  This
static library was removed in f3b4c89d59 (make: delete REFTABLE_LIB,
add reftable to LIB_OBJS, 2025-10-02), along with filling
REFTALBE_OBJS with object files.  This change essentially reverts the
removal of REFTABLE_OBJS, but not the building of that static library.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-09-15 09:18:05 -07:00
SZEDER Gábor 986cd1cd9e cmake: remove any "$(*_OBJS)" variables when parsing Makefile for sources
To get various lists of files, CMake parses our Makefile looking for
lines matching e.g. "list_var += ...".  In case of LIB_OBJS this
picks up the line "LIB_OBJS += $(COMPAT_OBJS)" as well, so the parsing
macro has a specific instruction to remove "$(COMPAT_OBJS)" from the
resulting list.

Currently this is the only such Makefile variable to be removed from
the list, but the next patches will (re)introduce more variables
containing lists of object files, so let's generalize that removing
instruction to remove any "$(*_OBJS)" Makefile variable as well.

Note that we can't make the pattern matching the Makefile variable too
general, e.g. to match any "$(VARIABLE)", because some lines of our
Makefile do contain variables as directory prefixes, e.g.
"UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o", and we must
definitely keep those.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-09-15 09:18:05 -07:00
Johannes Schindelin 1cd6b7de52 cmake(windows): accommodate for Git for Windows' migration to UCRT64
Git for Windows needs to ship with a lot of Unix tools that Git takes
for granted, such as `sed`, `awk`, a C compiler and a Unix shell, just
to name a few. In Git for Windows, these are provided by the MSYS2
project.

Part of these tools (such as `bash.exe`) use a POSIX emulation layer
("MSYS2 runtime", a friendly fork of the Cygwin runtime), but others
target a native Win32 toolchain, e.g. `git.exe`. There are multiple
flavors of that toolchain, and historically Git for Windows used MINGW64
on x64 Windows. This toolchain uses the old MSVC runtime, and therefore
the MSYS2 project deprecated it.

As a consequence, Git for Windows switches to UCRT64 with v2.56.0. That
flavor still uses GCC to compile native Win32 binaries, but targets the
Universal C Runtime ("UCRT"). Internally, this means that the new
`git.exe` is installed into a new prefix, `/ucrt64/`, whereas the old
`git.exe` was installed into `/mingw64/`.

A recently-upstreamed commit hard-codes this expectation even into the
CMake-based build, so that the built `git.exe` "knows where it lives"
and can ensure that the tools it expects on the `PATH` are found.

Naturally, this hard-coded MINGW64 needs to change to UCRT64 now, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-09-13 16:01:18 -07:00
Junio C Hamano bca240abc3 Merge branch 'js/mingw-build-updates'
A collection of patches from Git for Windows has been upstreamed,
mostly focusing on simplifying and robustifying build configurations
for MinGW/MSYS2, dropping obsolete compatibility options, and allowing
the main 'git.exe' to be used directly without the extra wrapper
process on Windows.

* js/mingw-build-updates:
  t0060: adjust the code style
  mingw: allow `git.exe` to be used instead of the "Git wrapper"
  mingw: ensure valid CTYPE
  mingw: always define `ETC_*` for MSYS2 environments
  windows: skip linking `git-<command>` for built-ins
  mingw: rely on MSYS2's metadata instead of hard-coding it
  mingw: only enable the MSYS2-specific stuff when compiling in MSYS2
  mingw: set the prefix and HOST_CPU as per MSYS2's settings
  mingw: avoid over-specifying `--pic-executable`
  mingw: only use -Wl,--large-address-aware for 32-bit builds
  mingw: drop the -D_USE_32BIT_TIME_T option
  mingw: stop hard-coding `CC = gcc`
  mingw: include the Python parts in the build
2026-09-11 09:45:10 -07:00
Johannes Schindelin caa5d9eab2 mingw: allow `git.exe` to be used instead of the "Git wrapper"
Git for Windows wants to add `git.exe` to the users' `PATH`, without
cluttering the latter with unnecessary executables such as `wish.exe`.
To that end, it invented the concept of its "Git wrapper", i.e. a tiny
executable located in `C:\Program Files\Git\cmd\git.exe` (originally a
CMD script) whose sole purpose is to set up a couple of environment
variables and then spawn the _actual_ `git.exe` (which nowadays lives in
`C:\Program Files\Git\mingw64\bin\git.exe` for 64-bit, and the obvious
equivalent for 32-bit installations).

Currently, the following environment variables are set unless already
initialized:

- `MSYSTEM`, to make sure that the MSYS2 Bash and the MSYS2 Perl
  interpreter behave as expected, and

- `PLINK_PROTOCOL`, to force PuTTY's `plink.exe` to use the SSH
  protocol instead of Telnet,

- `PATH`, to make sure that the `bin` folder in the user's home
  directory, as well as the `/mingw64/bin` and the `/usr/bin`
  directories are included. The trick here is that the `/mingw64/bin/`
  and `/usr/bin/` directories are relative to the top-level installation
  directory of Git for Windows (which the included Bash interprets as
  `/`, i.e. as the MSYS pseudo root directory).

Using the absence of `MSYSTEM` as a tell-tale, we can detect in
`git.exe` whether these environment variables have been initialized
properly. Therefore we can call `C:\Program Files\Git\mingw64\bin\git`
in-place after this change, without having to call Git through the Git
wrapper.

Obviously, above-mentioned directories must be _prepended_ to the `PATH`
variable, otherwise we risk picking up executables from unrelated Git
installations. We do that by constructing the new `PATH` value from
scratch, appending `$HOME/bin` (if `HOME` is set), then the MSYS2 system
directories, and then appending the original `PATH`.

Side note: this modification of the `PATH` variable is independent of
the modification necessary to reach the executables and scripts in
`/mingw64/libexec/git-core/`, i.e. the `GIT_EXEC_PATH`. That
modification is still performed by Git, elsewhere, long after making the
changes described above.

While we _still_ cannot simply hard-link `mingw64\bin\git.exe` to `cmd`
(because the former depends on a couple of `.dll` files that are only in
`mingw64\bin`, i.e. calling `...\cmd\git.exe` would fail to load due to
missing dependencies), at least we can now avoid that extra process of
running the Git wrapper (which then has to wait for the spawned
`git.exe` to finish) by calling `...\mingw64\bin\git.exe` directly, via
its absolute path.

Testing this is in Git's test suite tricky: we set up a "new" MSYS
pseudo-root and copy the `git.exe` file into the appropriate location,
then verify that `MSYSTEM` is set properly, and also that the `PATH` is
modified so that scripts can be found in `$HOME/bin`, `/mingw64/bin/`
and `/usr/bin/`.

This addresses https://github.com/git-for-windows/git/issues/2283

Note: This keeps the same, hard-coded MSYSTEM platform support for CMake
as before, and introduces an `msystem' and `mingw-prefix` knob for Meson
(read: neither CMake nor Meson will automatically inherit the setting
from the current build environment).

Helped-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-09-10 05:19:43 -07:00
Patrick Steinhardt 4ebec19711 builtin/rev-parse: rename "--show-ref-format" to "--show-ref-storage-format"
With the same reasoning as for git-init(1), rename "--show-ref-format"
to "--show-ref-storage-format" and keep the old name as an alias.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-09-09 11:04:31 -07:00
Junio C Hamano 098d38059e Merge branch 'll/zsh-complete-git-potty-options'
The zsh completion script (in 'contrib/') has been updated to
correctly locate the Git command after global options like '-C' by
properly skipping them, similar to how the bash completion does.

* ll/zsh-complete-git-potty-options:
  completion: zsh: support completion after "git -C <path>"
2026-09-07 09:32:06 -07:00
Junio C Hamano 189ff3a56d Merge branch 'vm/complete-history'
The command line completion (in contrib/) has been taught to handle
the experimental 'git history' command.

* vm/complete-history:
  completion: complete 'git history split' pathspecs
  completion: complete 'git history --update-refs' values
  completion: complete 'git history --empty' values
  completion: add 'git history' subcommands
2026-08-31 08:24:59 -07:00
Junio C Hamano fee541a0d8 Merge branch 'jc/complete-checkout'
'git -C <dir> checkout fi<TAB>' did not complete, which has been
corrected.

* jc/complete-checkout:
  completion: 'git checkout' completes untracked paths as a last resort
  completion: complete tracked paths for "git checkout"
  completion: no-op refactoring of checkout completion
2026-08-25 10:53:34 -07:00
Junio C Hamano 4e5713a686 Merge branch 'jc/complete-diff-tracked-paths'
'git -C <dir> diff fi<TAB>' did not complete 'file', which has been
corrected.

* jc/complete-diff-tracked-paths:
  completion: 'git diff' completes untracked paths as a last resort
  completion: complete tracked paths for 'git diff'
  completion: no-op refactoring of diff completion
2026-08-25 10:53:33 -07:00
Alexey Samsonov be2b0a8f00 compat/posix: introduce utimensat(2) wrapper
In POSIX.1-2008, utime(3p) was marked as obsolescent in favor of
utimensat(2) and futimens(2). In the recent POSIX.1-2024 (Issue 8)
specification, <utime.h> and utime(3p) were officially removed.

utimensat(2) operates on `struct timespec` rather than the second-only
`struct utimbuf`, allowing sub-second timestamp updates while also
providing support for UTIME_NOW and UTIME_OMIT flags to selectively
update or preserve individual access and modification timestamps.

Introduce a compatibility layer for utimensat(2):
- Provide fallback definitions for AT_FDCWD, UTIME_NOW, and UTIME_OMIT
  in case the system headers lack them.
- Introduce `ST_ATIME_NSEC(st)` to complement `ST_MTIME_NSEC(st)` and
  `ST_CTIME_NSEC(st)`.
- Implement `git_utimensat()` in `compat/utimensat.c` as a fallback using
  utimes(2) on platforms that define NO_UTIMENSAT.
- Implement `mingw_utimensat()` in `compat/mingw.c` converting `struct
  timespec` to Windows FILETIME with 100ns precision.
- Wire up NO_UTIMENSAT support in Makefile, meson.build,
  contrib/buildsystems/CMakeLists.txt, and configure.ac.

Subsequent commits will migrate callers across the codebase to
utimensat(2) and drop the legacy <utime.h> header.

Signed-off-by: Alexey Samsonov <vonosmas@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-21 10:24:33 -07:00
Lutz Lengemann da9c6e7e04 completion: zsh: support completion after "git -C <path>"
The zsh completion wrapper does not handle the global -C option, so

	git -C <path> <command> <TAB>

offers nothing.  -C is not part of the _arguments specification, and the
wrapper hard-codes __git_cmd_idx=1, i.e. it assumes that the command is
the first argument, so the bash helpers look at the wrong word.  The
latter is not specific to -C; the assumption breaks after any global
option, e.g. "git -p checkout <TAB>" does not complete branch names.

Add -C to the specification, and find the command by skipping over the
global options and, where they take one, their arguments, as __git_main
in git-completion.bash does.  The index is one less than zsh's, as the
helpers count the words from zero.  Collect the paths given to -C into
__git_C_args, or else the helpers run git in the current directory and
fail to resolve the aliases and refs of the repository the command runs
in.

The argument of a -C is still completed without regard for the -C
options before it, i.e. "git -C dir -C <TAB>" offers the directories in
".", not the ones in "dir".

Signed-off-by: Lutz Lengemann <lutz@lengemann.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-19 10:22:14 -07:00
Junio C Hamano 3beb8bb742 Merge branch 'ps/writev'
A compatibility wrapper for writev(3p) has been reintroduced,
including fixes for CMake build and 'MAX_IO_SIZE' limits on NonStop.
Calls to write(3p) in send_sideband() and cat_blob() have been
refactored to use writev(3p) wrappers to reduce syscall overhead.

* ps/writev:
  fast-import: use writev(3p) to send cat-blob responses
  sideband: use writev(3p) to send pktlines
  wrapper: properly handle MAX_IO_SIZE in writev(3p)
  wrapper: introduce writev(3p) wrappers
  compat/posix: introduce writev(3p) wrapper
2026-08-18 09:31:36 -07:00
Vincent Mailhol 328b3b9d62 completion: complete 'git history split' pathspecs
Arguments following the required revision of "git history split" are
pathspecs. Complete them from tracked paths, including after an explicit
"--".

Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 12:22:55 -07:00
Vincent Mailhol 5bda733b18 completion: complete 'git history --update-refs' values
The "--update-refs" option accepts either "branches" or "head".
Complete these values for the documented

  --update-refs=<value>

form.

While parse-options also accepts the split

  --update-refs <value>

form, it is not documented. Omit it from completion as a trade-off for
code simplicity.

Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 12:22:54 -07:00
Vincent Mailhol 8231551929 completion: complete 'git history --empty' values
The "--empty" option accepts "drop", "keep", or "abort" for the "drop"
and "fixup" subcommands. Complete these values for the documented

  --empty=<value>

form.

While parse-options also accepts the split

  --empty <value>

form, it is not documented. Omit it from completion as a trade-off for
code simplicity.

Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 12:22:54 -07:00
Vincent Mailhol 27be716454 completion: add 'git history' subcommands
Use the parse-options completion helpers for the

  git history

subcommands and their options. All current history subcommands take a
revision as their first positional argument, so complete that argument
as a revision.

Once the revision is present, leave any further positional arguments to
subcommand-specific completion. This allows a subcommand to complete
another kind of argument, such as the pathspec accepted by

  git history split

or another revision if a future subcommand accepts one.

Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 12:22:54 -07:00
Junio C Hamano 05e2ab1f31 completion: 'git checkout' completes untracked paths as a last resort
We taught 'git checkout' to first try to complete revisions (unless
'--' is present on the command line) and, failing that, to complete
tracked paths.  If this yields nothing, it lets the Bash default,
which offers paths in $PWD, kick in.

Teach it to complete untracked paths before giving up and letting
the Bash default kick in.  With this change,

    $ git -C another-directory checkout un<TAB>

finds the 'untracked' file in another-directory and offers it as a
completion candidate.

Note that this is of somewhat dubious value, as an untracked path by
definition does not exist in the index, so checking it out from the
index would not work well.  Even when used to check out the path
from a different branch, it is still of dubious value because it is
unlikely that a path tracked in another branch is lying untracked in
the working tree, as switching from a branch with the path to a
branch without it will normally remove the file in the working tree.

A better behavior probably is to detect the tree-ish argument on
the command line and offer paths with the given prefix as candidates,
but there is no __git_complete_from_tree() helper readily usable,
so mark this as #leftoverbits to wait for another day.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 12:13:56 -07:00
Junio C Hamano 3fe9209986 completion: complete tracked paths for "git checkout"
When completing arguments for "git checkout", _git_checkout()
delegates to __git_complete_refs(), which only completes revision
references.  This is good, as mixing revisions and paths in a single
list from which the user can choose is confusing.  However, if no
reference matches, or if "--" is given, _git_checkout() leaves
COMPREPLY empty.  Bash then falls back to the default filename
completion in $PWD.

This fails when "git -C <path>" is used, as $PWD is not the target
repository.

Update _git_checkout() to use __git_complete_index_file() when "--"
is present, or when revision reference completion yields no matching
candidates, so that tracked paths are offered as candidates.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 12:13:56 -07:00
Junio C Hamano 735514635b completion: no-op refactoring of checkout completion
The 'git checkout' completion function punts very early when it sees
'--' on the command line, as it indicates that options or revisions
can no longer appear.  By returning early, it allows the default
Bash action (which completes files in '$PWD') to kick in.

In preparation for changing what happens in the next step when
option or revision completion yields no matching candidates, or when
'--' is present, reorganize the control flow to avoid this early
return, and add explicit returns to the option completion branches.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 12:13:55 -07:00
Junio C Hamano 354d1bf3a0 completion: 'git diff' completes untracked paths as a last resort
We taught 'git diff' to first try to complete revisions (unless '--'
is present on the command line) and, failing that, to complete
tracked paths.  If this yields nothing, it lets the Bash default,
which offers paths in $PWD, kick in.

Teach it to complete untracked paths before giving up and letting
the Bash default kick in.  With this change,

    $ git -C another-directory diff un<TAB>

finds the 'untracked' file in another-directory and offers it as a
completion candidate.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-12 10:14:42 -07:00
Junio C Hamano 4b1b7a4e95 completion: complete tracked paths for 'git diff'
When completing arguments for 'git diff', _git_diff() delegates to
__git_complete_revlist_file(), which only completes revision
references.  This is good [*], as mixing both revisions and paths in a
single list for the user to pick from is simply too confusing.

If no reference matches, or if '--' is given, however, _git_diff()
leaves COMPREPLY empty.  Bash then falls back to default filename
completion in $PWD.  This fails when 'git -C <path>' is used because
$PWD is not the target repository.

Update _git_diff() to use __git_complete_index_file() when '--' is
present, or when revision reference completion yields no matching
candidates, so that tracked paths are offered as candidates.

This changes behavior even in the case where '-C <there>' is not
used.  The new behavior omits untracked paths from suggestions when
no revs match the prefix but matching tracked paths exist, which is
more useful in the context of 'git diff'.

When run outside the working tree of a repository, or when nothing
matches from revisions or tracked paths, Bash still falls back to
default filename completion in $PWD, so such a use case would be
just like completing paths for any 'diff' command, rather than for
'git diff'.

[Footnote]
 * In https://lore.kernel.org/git/al%2Fw2qgBfhe9qMg6@szeder.dev/
   SZEDER made the same argument for "git send-email 0<TAB>".

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-12 10:14:42 -07:00
Junio C Hamano a039ee6757 completion: no-op refactoring of diff completion
The "git diff" completion function punts very early when it sees
"--" on the command line, since it is a sign that options or
revisions can appear and the current completion does not need to do
anything "git diff" specific. By returning, it lets Bash default
action that completes the names of the files in $PWD to kick in.

In preparation for the next step to change what happens when we
"punt", arrange the code flow to avoid this early return.  The
behaviour at this step is unchanged, but the control flow just
falls straight to the end.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-12 10:14:42 -07:00
Patrick Steinhardt 8b0ab33247 compat/posix: introduce writev(3p) wrapper
In a subsequent commit we're going to add the first caller to
writev(3p). Introduce a compatibility wrapper for this syscall that we
can use on systems that don't have this syscall.

The syscall exists on modern Unixes like Linux and macOS, and seemingly
even for NonStop according to [1]. It doesn't seem to exist on Windows
though.

[1]: http://nonstoptools.com/manuals/OSS-SystemCalls.pdf
[2]: https://www.gnu.org/software/gnulib/manual/html_node/writev.html

Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07 08:57:25 -07:00
Junio C Hamano f8ec2c6aee Merge branch 'sn/osxkeychain-rust-universal'
The build system has been updated to support building universal macOS
binaries when 'Rust' is enabled, by compiling separate static archives
for each target triple listed in 'RUST_TARGETS' and combining them
using the macOS 'lipo' tool.  The 'git-credential-osxkeychain' helper
has been updated to link against '$(RUST_LIB)' when 'Rust' is enabled.

* sn/osxkeychain-rust-universal:
  contrib: wire up osxkeychain in contrib/Makefile on macOS
  Makefile: support universal macOS builds via RUST_TARGETS
  Makefile: add $(RUST_LIB) prerequisite to osxkeychain
2026-07-19 10:42:17 -07:00
Junio C Hamano 620657c941 Merge branch 'bc/parse-options-exit-0-on-help'
Option parsing with 'git rev-parse --parseopt' and in most 'git'
subcommands has been updated to exit with 0 (instead of 129) when the
help option ('-h' or '--help') is requested directly by the user,
aligning with standard Unix convention.

* bc/parse-options-exit-0-on-help:
  parse-options: exit 0 on -h
  rev-parse: have --parseopt callers exit 0 on --help
  parse-options: add a separate case for help output on error
  t1517: skip svn tests if svn is not installed
2026-07-19 10:42:16 -07:00
Johannes Schindelin f635ab9ab4 wincred: prevent silent credential loss when storing OAuth tokens
When `git credential approve` hands the wincred helper a password
together with an `oauth_refresh_token`, the OAuth branch of
`store_credential()` writes one WCHAR past the allocation while
formatting both fields into a single `CredentialBlob`. On Windows
this trips heap verification and tears the helper down with status
`0xC0000374`; `approve` masks the failure, so the credential the
user meant to save never reaches `CredWriteW()` and the next
session prompts for it again.

The bug has the same shape as the one fixed in the previous commit:
the allocation leaves no room for the terminating NUL, and the
`sizeOfBuffer` argument to `_snwprintf_s()` is a byte count where
the API expects a WCHAR count, which lets the safe-CRT runtime
write the terminator out of bounds.

Apply the same remedy d22a488482 (wincred: avoid memory corruption,
2025-11-17) applied in `get_credential()`: allocate `(wlen + 1) *
sizeof(WCHAR)` bytes and pass `wlen + 1` as the destination
capacity in WCHARs.

This closes the second of the two heap writes tracked under
GHSA-rxqw-wxqg-g7hw.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-16 11:31:32 -07:00
Johannes Schindelin 936eb75730 wincred: avoid memory corruption when erasing a credential
The earlier d22a488482 (wincred: avoid memory corruption, 2025-11-17)
repaired only get_credential(); match_cred_password() has the same
defect and is reached on `git credential reject`. When Git asks the
helper to erase a stored credential whose password was supplied by
the caller, the helper copies the candidate's password into a freshly
allocated buffer for comparison. That copy overruns the allocation
by one WCHAR of NUL, which on uninstrumented Windows manifests as
process termination with status 0xC0000374. Because the helper can
die before reaching CredDeleteW(), `git credential reject` masks the
failure and the rejected credential remains stored.

CredentialBlobSize is documented as a byte count, so for an N-WCHAR
blob it equals N * sizeof(WCHAR). The pre-fix code allocated that
many bytes and asked wcsncpy_s to copy N wide characters, but
wcsncpy_s always appends a terminating NUL WCHAR, writing one WCHAR
past the allocation. The destination-capacity argument was also
passed in bytes rather than in WCHAR elements as the API requires,
so the safe-CRT runtime never rejected the copy.

See GHSA-rxqw-wxqg-g7hw.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-16 11:31:29 -07:00
Shardul Natu 1a62c1fc8b contrib: wire up osxkeychain in contrib/Makefile on macOS
When running "make test" with TEST_CONTRIB_TOO=yes (which is default in
macOS CI workflows), $(MAKE) -C contrib/ test is invoked. However,
contrib/Makefile only invoked tests for diff-highlight and subtree,
meaning git-credential-osxkeychain was never built or verified during
standard CI test runs.

Add a "test" target to contrib/credential/osxkeychain/Makefile that
depends on building git-credential-osxkeychain. Additionally, wire up
credential/osxkeychain in contrib/Makefile under "all", "test", and
"clean" whenever running on macOS (Darwin).

This ensures that running "make test" or "make all" in contrib on macOS
automatically builds and links git-credential-osxkeychain, preventing
future build or symbol linking regressions from slipping through CI.

Signed-off-by: Shardul Natu <snatu@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07 21:58:55 -07:00
brian m. carlson cdaf12f762 parse-options: exit 0 on -h
The standard philosophy for Unix software when a help option (such as
--help) is specified is that the software should exit 0, printing the
help output to standard output, since the standard output is for
user-requested output and the program performed the requested task
successfully.  If the user specifies an incorrect option, then the help
output should be printed to standard error (since the user has made a
mistake) and it should exit unsuccessfully.

Most of our commands currently exit 129 on receiving the -h option to
print the short help, which does not line up with the standard
philosophy above.  Let's change that to exit 0 instead.

This requires changes to a variety of tests which previously wanted the
129 exit code, so update them.  Note that because git diff does its own
option parsing, it still exits with 129, so update some of the tests to
expect either exit status.

Some commands also now pass with -h but not --help-all, so handle those
cases differently for those commands.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-07 17:48:57 -07:00
Ian Jackson 20b117c1eb git-subtree: Bail out if we find output from Rust rewrite (test)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06 07:36:38 -07:00
Ian Jackson cd6ad979ab git-subtree: Bail out if we find output from Rust rewrite
This is going to be forward compatible, but not backward compatible:
projects are expected to adopt the new tool, but not go back to this
old one.

CC: Colin Stagner <ask+git@howdoi.land>
CC: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-07-06 07:36:38 -07:00
Junio C Hamano 5255d04a9c Merge branch 'wy/docs-typofixes'
Various typos, grammatical errors, and duplicated words in both
documentation and code comments have been corrected.

* wy/docs-typofixes:
  docs: fix typos and grammar
2026-06-16 09:01:03 -07:00
Junio C Hamano c534ec3a5d Merge branch 'mf/revision-max-count-oldest'
"git rev-list" (and "git log" family of commands) learned a new "--max-count-oldest"
that picks oldest N commits in the range instead of the usual newest.

* mf/revision-max-count-oldest:
  bash-completions: add --max-count-oldest
  revision.c: implement --max-count-oldest
2026-06-16 09:01:02 -07:00
Mirko Faina ff7901eca3 bash-completions: add --max-count-oldest
Add missing completion for log --max-count-oldest

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-11 11:54:40 -07:00
Junio C Hamano a58e51dddf Merge branch 'gh/jump-auto-mode'
The 'git-jump' command (in contrib/) has been taught to automatically
pick a mode (merge, diff, or ws) when invoked without arguments.

* gh/jump-auto-mode:
  git-jump: pick a mode automatically when invoked without arguments
2026-06-09 10:04:51 +09:00
Junio C Hamano 4d11b9c218 Merge branch 'pt/fsmonitor-linux'
The fsmonitor daemon has been implemented for Linux.

* pt/fsmonitor-linux:
  fsmonitor: convert shown khash to strset in do_handle_client
  fsmonitor: add tests for Linux
  fsmonitor: add timeout to daemon stop command
  fsmonitor: close inherited file descriptors and detach in daemon
  run-command: add close_fd_above_stderr option
  fsmonitor: implement filesystem change listener for Linux
  fsmonitor: rename fsm-settings-darwin.c to fsm-settings-unix.c
  fsmonitor: rename fsm-ipc-darwin.c to fsm-ipc-unix.c
  fsmonitor: use pthread_cond_timedwait for cookie wait
  compat/win32: add pthread_cond_timedwait
  fsmonitor: fix hashmap memory leak in fsmonitor_run_daemon
  fsmonitor: fix khash memory leak in do_handle_client
  t9210, t9211: disable GIT_TEST_SPLIT_INDEX for scalar clone tests
2026-05-31 10:00:38 +09:00
Weijie Yuan dc6068df67 docs: fix typos and grammar
Fix several spelling mistakes, subject-verb agreement issues, and
duplicated words.

Signed-off-by: Weijie Yuan <wy@wyuan.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-30 07:07:27 +09:00
Greg Hurrell 74216ffe0a git-jump: pick a mode automatically when invoked without arguments
When `git jump` is invoked with no positional arguments (and no
arguments after `--stdout`) it currently prints usage and exits with
status 1.

But there are two situations where we can usefully infer the most
valuable and likely mode that a user would want to use, and select it
automatically:

1. When there are unmerged paths in the index, the user likely
   wants `git jump merge`.

2. When the working tree has unstaged changes, the user likely
   wants `git jump diff`.

In this commit we teach `git jump` a new "auto" mode which detects these
cases and dispatches to the corresponding mode automatically. The user
can either explicitly spell out `git jump auto`, or just leave it at
`git jump` (because "auto" is the default).

If none of the interesting cases listed above applies, then auto mode
falls back to the existing usage-and-exit behavior.

Signed-off-by: Greg Hurrell <greg.hurrell@datadoghq.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-21 23:01:04 +09:00
Johannes Schindelin cefcada1d3 mingw: drop the build-system plumbing for nedmalloc
With the previous commit removing every opt-in, the build-system
plumbing for nedmalloc has nothing left to switch on. Remove it so
that the upcoming deletion of the compat/nedmalloc/ tree is a pure
file removal.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-09 11:19:23 +09:00
Johannes Schindelin c9eb040e4b mingw: stop using nedmalloc
The vendored nedmalloc allocator under compat/nedmalloc/ has been
unmaintained upstream for a very long time: the original repository at
https://github.com/ned14/nedmalloc received its last commit on July 5,
2014, and was archived (made read-only) by its owner on March 15, 2019.
Our copy has been carried forward unchanged ever since.

The Git for Windows commit that introduced mimalloc as a replacement
on Windows ("mingw: use mimalloc", 2019-06-24, present in the Git for
Windows branch thicket but not upstream) already observed at that time
that nedmalloc had ceased to see any updates for several years.

This came to a head when the Git for Windows SDK upgraded to GCC 16:
the `add_segment()` function in `compat/nedmalloc/malloc.c.h` declares
`int nfences = 0` and only references it inside an `assert()`, which
GCC 16 now flags as `-Wunused-but-set-variable`. Combined with the
`-Werror` enabled by `DEVELOPER=1`, this turns into a hard build
failure:

	compat/nedmalloc/malloc.c.h: In function 'add_segment':
	compat/nedmalloc/malloc.c.h:3897:7: error: variable 'nfences' set but not used [-Werror=unused-but-set-variable=]
	 3897 |   int nfences = 0;
	      |       ^~~~~~~
	cc1.exe: all warnings being treated as errors

The same source built without complaint under GCC 15.2.0; the
regression was bisected to the SDK package update at
https://github.com/git-for-windows/git-sdk-64/commit/188d93dd455
(`mingw-w64-x86_64-gcc 15.2.0-14 -> 16.1.0-1`), with the failing CI
run captured at
https://github.com/git-for-windows/git-sdk-64/actions/runs/25244795074.

Rather than patch the unmaintained vendored sources to silence the
warning, stop opting into nedmalloc altogether on Windows. The
platform allocator is what every non-MINGW build already uses, and a
fresh build of git.git's master against a minimal Git for Windows SDK
upgraded to GCC 16 completes successfully.

The compat/nedmalloc/ subtree itself is removed by subsequent commits
in this series.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-09 11:19:22 +09:00
Paul Tarjan ce48de8b2c fsmonitor: implement filesystem change listener for Linux
Implement the built-in fsmonitor daemon for Linux using the inotify
API, bringing it to feature parity with the existing Windows and macOS
implementations.

The implementation uses inotify rather than fanotify because fanotify
requires either CAP_SYS_ADMIN or CAP_PERFMON capabilities, making it
unsuitable for an unprivileged user-space daemon.  While inotify has
the limitation of requiring a separate watch on every directory (unlike
macOS's FSEvents, which can monitor an entire directory tree with a
single watch), it operates without elevated privileges and provides
the per-file event granularity needed for fsmonitor.

The listener uses inotify_init1(O_NONBLOCK) with a poll loop that
checks for events with a 50-millisecond timeout, keeping the inotify
queue well-drained to minimize the risk of overflows.  Bidirectional
hashmaps map between watch descriptors and directory paths for efficient
event resolution.  Directory renames are tracked using inotify's cookie
mechanism to correlate IN_MOVED_FROM and IN_MOVED_TO event pairs; a
periodic check detects stale renames where the matching IN_MOVED_TO
never arrived, forcing a resync.

New directory creation triggers recursive watch registration to ensure
all subdirectories are monitored.  The IN_MASK_CREATE flag is used
where available to prevent modifying existing watches, with a fallback
for older kernels.  When IN_MASK_CREATE is available and
inotify_add_watch returns EEXIST, it means another thread or recursive
scan has already registered the watch, so it is safe to ignore.

Remote filesystem detection uses statfs() to identify network-mounted
filesystems (NFS, CIFS, SMB, FUSE, etc.) via their magic numbers.
Mount point information is read from /proc/mounts and matched against
the statfs f_fsid to get accurate, human-readable filesystem type names
for logging.  When the .git directory is on a remote filesystem, the
IPC socket falls back to $HOME or a user-configured directory via the
fsmonitor.socketDir setting.

Based-on-patch-by: Eric DeCosta <edecosta@mathworks.com>
Based-on-patch-by: Marziyeh Esipreh <marziyeh.esipreh@gmail.com>
Signed-off-by: Paul Tarjan <github@paulisageek.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-15 08:44:33 -07:00
Paul Tarjan 7422200bfa fsmonitor: rename fsm-settings-darwin.c to fsm-settings-unix.c
The fsmonitor settings logic in fsm-settings-darwin.c is not
Darwin-specific and will be reused by the upcoming Linux
implementation.  Rename it to fsm-settings-unix.c to reflect that it
is shared by all Unix platforms.

Update the build files (meson.build and CMakeLists.txt) to use
FSMONITOR_OS_SETTINGS for fsm-settings, matching the approach already
used for fsm-ipc.

Based-on-patch-by: Eric DeCosta <edecosta@mathworks.com>
Based-on-patch-by: Marziyeh Esipreh <marziyeh.esipreh@gmail.com>
Signed-off-by: Paul Tarjan <github@paulisageek.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-15 08:44:33 -07:00
Paul Tarjan ff384ebfad fsmonitor: rename fsm-ipc-darwin.c to fsm-ipc-unix.c
The fsmonitor IPC path logic in fsm-ipc-darwin.c is not
Darwin-specific and will be reused by the upcoming Linux
implementation.  Rename it to fsm-ipc-unix.c to reflect that it
is shared by all Unix platforms.

Introduce FSMONITOR_OS_SETTINGS (set to "unix" for non-Windows, "win32"
for Windows) as a separate variable from FSMONITOR_DAEMON_BACKEND so
that the build files can distinguish between platform-specific files
(listen, health, path-utils) and shared Unix files (ipc, settings).

Move fsm-ipc to the FSMONITOR_OS_SETTINGS section in the Makefile, and
switch fsm-path-utils to use FSMONITOR_DAEMON_BACKEND since path-utils
is platform-specific (there will be separate darwin and linux versions).

Based-on-patch-by: Eric DeCosta <edecosta@mathworks.com>
Based-on-patch-by: Marziyeh Esipreh <marziyeh.esipreh@gmail.com>
Signed-off-by: Paul Tarjan <github@paulisageek.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-15 08:44:33 -07:00
Junio C Hamano 9c30dddefd Revert "cmake: use writev(3p) wrapper as needed"
This reverts commit 89152af176ea94ea8f3249115b6e00827fbbeb70; let's
not use writev() for now.
2026-04-09 14:47:28 -07:00
Junio C Hamano ac340a635d Merge branch 'js/cmake-needs-writev-compat-too'
Build instruction for recently added writev() compatibility wrapper
has been also added to cmake.

* js/cmake-needs-writev-compat-too:
  cmake: use writev(3p) wrapper as needed
2026-04-03 15:24:45 -07:00