]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
2 weeks agomingw: implement `stat()` with symlink support
Karsten Blees [Fri, 9 Jan 2026 20:04:59 +0000 (20:04 +0000)] 
mingw: implement `stat()` with symlink support

With respect to symlinks, the current `mingw_stat()` implementation is
almost identical to `mingw_lstat()`: except for the file type (`st_mode
& S_IFMT`), it returns information about the link rather than the target.

Implement `mingw_stat()` by opening the file handle requesting minimal
permissions, and then calling `GetFileInformationByHandle()` on it. This
way, all links are resolved by the Windows file system layer.

Signed-off-by: Karsten Blees <karsten.blees@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 weeks agomingw: don't call `GetFileAttributes()` twice in `mingw_lstat()`
Karsten Blees [Fri, 9 Jan 2026 20:04:58 +0000 (20:04 +0000)] 
mingw: don't call `GetFileAttributes()` twice in `mingw_lstat()`

The Win32 API function `GetFileAttributes()` cannot handle paths with
trailing dir separators. The current `mingw_stat()`/`mingw_lstat()`
implementation calls `GetFileAttributes()` twice if the path has
trailing slashes (first with the original path that was passed as
function parameter, and and a second time with a path copy with trailing
'/' removed).

With the conversion to wide Unicode, we get the length of the path for
free, and also have a (wide char) buffer that can be modified. This
makes it easy to avoid that extraneous Win32 API call.

Signed-off-by: Karsten Blees <karsten.blees@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 weeks agoMerge branch 'js/prep-symlink-windows' into js/symlink-windows
Junio C Hamano [Sat, 10 Jan 2026 02:32:29 +0000 (18:32 -0800)] 
Merge branch 'js/prep-symlink-windows' into js/symlink-windows

* js/prep-symlink-windows:
  trim_last_path_component(): avoid hard-coding the directory separator
  strbuf_readlink(): support link targets that exceed 2*PATH_MAX
  strbuf_readlink(): avoid calling `readlink()` twice in corner-cases
  init: do parse _all_ core.* settings early
  mingw: do resolve symlinks in `getcwd()`
  t7800: work around the MSYS path conversion on Windows
  t6423: introduce Windows-specific handling for symlinking to /dev/null
  t1305: skip symlink tests that do not apply to Windows
  t1006: accommodate for symlink support in MSYS2
  t0600: fix incomplete prerequisite for a test case
  t0301: another fix for Windows compatibility
  t0001: handle `diff --no-index` gracefully
  mingw: special-case `open(symlink, O_CREAT | O_EXCL)`
  apply: symbolic links lack a "trustable executable bit"
  t9700: accommodate for Windows paths

2 weeks agotrim_last_path_component(): avoid hard-coding the directory separator
Karsten Blees [Fri, 9 Jan 2026 20:05:09 +0000 (20:05 +0000)] 
trim_last_path_component(): avoid hard-coding the directory separator

Currently, this function hard-codes the directory separator as the
forward slash.

However, on Windows the backslash character is valid, too. And we want
to call this function in the upcoming support for symlinks on Windows
with the symlink targets (which naturally use the canonical directory
separator on Windows, which is _not_ the forward slash).

Prepare that function to be useful also in that context.

Signed-off-by: Karsten Blees <karsten.blees@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 weeks agostrbuf_readlink(): support link targets that exceed 2*PATH_MAX
Johannes Schindelin [Fri, 9 Jan 2026 20:05:08 +0000 (20:05 +0000)] 
strbuf_readlink(): support link targets that exceed 2*PATH_MAX

The `strbuf_readlink()` function refuses to read link targets that
exceed 2*PATH_MAX (even if a sufficient size was specified by the
caller).

The reason that that limit is 2*PATH_MAX instead of PATH_MAX is that
the symlink targets do not need to be normalized. After running
`ln -s a/../a/../a/../a/../b c`, the target of the symlink `c` will not
be normalized to `b` but instead be much longer. As such, symlink
targets' lengths can far exceed PATH_MAX.

They are frequently much longer than 2*PATH_MAX on Windows, which
actually supports paths up to 32,767 characters, but sets PATH_MAX to
260 for backwards compatibility. For full details, see
https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation

Let's just hard-code the limit used by `strbuf_readlink()` to 32,767 and
make it independent of the current platform's PATH_MAX.

Based-on-a-patch-by: Karsten Blees <karsten.blees@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 weeks agostrbuf_readlink(): avoid calling `readlink()` twice in corner-cases
Karsten Blees [Fri, 9 Jan 2026 20:05:07 +0000 (20:05 +0000)] 
strbuf_readlink(): avoid calling `readlink()` twice in corner-cases

The `strbuf_readlink()` function calls `readlink()`` twice if the hint
argument specifies the exact size of the link target (e.g. by passing
stat.st_size as returned by `lstat()`). This is necessary because
`readlink(..., hint) == hint` could mean that the buffer was too small.

Use `hint + 1` as buffer size to prevent this.

Signed-off-by: Karsten Blees <karsten.blees@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 weeks agoinit: do parse _all_ core.* settings early
Johannes Schindelin [Fri, 9 Jan 2026 20:05:06 +0000 (20:05 +0000)] 
init: do parse _all_ core.* settings early

In Git for Windows, `has_symlinks` is set to 0 by default. Therefore, we
need to parse the config setting `core.symlinks` to know if it has been
set to `true`. In `git init`, we must do that before copying the
templates because they might contain symbolic links.

Even if the support for symbolic links on Windows has not made it to
upstream Git yet, we really should make sure that all the `core.*`
settings are parsed before proceeding, as they might very well change
the behavior of `git init` in a way the user intended.

This fixes https://github.com/git-for-windows/git/issues/3414

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 weeks agomingw: do resolve symlinks in `getcwd()`
Johannes Schindelin [Fri, 9 Jan 2026 20:05:05 +0000 (20:05 +0000)] 
mingw: do resolve symlinks in `getcwd()`

As pointed out in https://github.com/git-for-windows/git/issues/1676,
the `git rev-parse --is-inside-work-tree` command currently fails when
the current directory's path contains symbolic links.

The underlying reason for this bug is that `getcwd()` is supposed to
resolve symbolic links, but our `mingw_getcwd()` implementation did not.

We do have all the building blocks for that, though: the
`GetFinalPathByHandleW()` function will resolve symbolic links. However,
we only called that function if `GetLongPathNameW()` failed, for
historical reasons: the latter function was supported for a long time,
but the former API function was introduced only with Windows Vista, and
we used to support also Windows XP. With that support having been
dropped, we are free to call the symbolic link-resolving function right
away.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoMerge branch 'js/test-symlink-windows' into js/prep-symlink-windows
Junio C Hamano [Wed, 17 Dec 2025 23:20:25 +0000 (08:20 +0900)] 
Merge branch 'js/test-symlink-windows' into js/prep-symlink-windows

* js/test-symlink-windows:
  t7800: work around the MSYS path conversion on Windows
  t6423: introduce Windows-specific handling for symlinking to /dev/null
  t1305: skip symlink tests that do not apply to Windows
  t1006: accommodate for symlink support in MSYS2
  t0600: fix incomplete prerequisite for a test case
  t0301: another fix for Windows compatibility
  t0001: handle `diff --no-index` gracefully
  mingw: special-case `open(symlink, O_CREAT | O_EXCL)`
  apply: symbolic links lack a "trustable executable bit"
  t9700: accommodate for Windows paths

5 weeks agot7800: work around the MSYS path conversion on Windows
Johannes Schindelin [Wed, 17 Dec 2025 14:18:46 +0000 (14:18 +0000)] 
t7800: work around the MSYS path conversion on Windows

Git's test suite's relies on Unix shell scripting, which is
understandable, of course, given Git's firm roots (and indeed, ongoing
focus) on Linux.

This fact, combined with Unix shell scripting's natural
habitat -- which is, naturally... *drumroll*... Unix --
often has unintended side effects, where developers expect the test
suite to run in a Unix environment, which is an incorrect assumption.

One instance of this problem can be observed in the 'difftool --dir-diff
handles modified symlinks' test case in `t7800-difftool.sh`, which
assumes that all absolute paths start with a forward slash. That
assumption is incorrect in general, e.g. on Windows, where absolute
paths have many shapes and forms, none of which starts with a forward
slash.

The only saving grace is that this test case is currently not run on
Windows because of the `SYMLINK` prerequisite. However, I am currently
working towards upstreaming symbolic link support from Git for Windows
to upstream Git, which will put a crack into that saving grace.

Let's change that test case so that it does not rely on absolute paths
(which are passed to the "external command" `ls` as parameters and are
therefore part of its output, and which the test case wants to filter
out before verifying that the output is as expected) starting with a
forward slash. Let's instead rely on the much more reliable fact that
`ls` will output the path in a line that ends in a colon, and simply
filter out those lines by matching said colon instead.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot6423: introduce Windows-specific handling for symlinking to /dev/null
Johannes Schindelin [Wed, 17 Dec 2025 14:18:45 +0000 (14:18 +0000)] 
t6423: introduce Windows-specific handling for symlinking to /dev/null

The device `/dev/null` does not exist on Windows, it's called `NUL`
there. Calling `ln -s /dev/null my-symlink` in a symlink-enabled MSYS2
Bash will therefore literally link to a file or directory called `null`
that is supposed to be in the current drive's top-level `dev` directory.
Which typically does not exist.

The test, however, really wants the created symbolic link to point to
the NUL device. Let's instead use the `mklink` utility on Windows to
perform that job, and keep using `ln -s /dev/null <target>` on
non-Windows platforms.

While at it, add the missing `SYMLINKS` prereq because this test _still_
would not pass on Windows before support for symbolic links is
upstreamed from Git for Windows.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot1305: skip symlink tests that do not apply to Windows
Johannes Schindelin [Wed, 17 Dec 2025 14:18:44 +0000 (14:18 +0000)] 
t1305: skip symlink tests that do not apply to Windows

In Git for Windows, the gitdir is canonicalized so that even when the
gitdir is specified via a symbolic link, the `gitdir:` conditional
include will only match the real directory path.

Unfortunately, t1305 codifies a different behavior in two test cases,
which are hereby skipped on Windows.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot1006: accommodate for symlink support in MSYS2
Johannes Schindelin [Wed, 17 Dec 2025 14:18:43 +0000 (14:18 +0000)] 
t1006: accommodate for symlink support in MSYS2

The MSYS2 runtime (which inherits this trait from the Cygwin runtime,
and which is used by Git for Windows' Bash to emulate POSIX
functionality on Windows, the same Bash that is also used to run Git's
test suite on Windows) has a mode where it can create native symbolic
links on Windows.

Naturally, this is a bit of a strange feature, given that Cygwin goes
out of its way to support Unix-like paths even if no Win32 program
understands those, and the symbolic links have to use Win32 paths
instead (which Win32 programs understand very well).

As a consequence, the symbolic link targets get normalized before the
links are created.

This results in certain quirks that Git's test suite is ill equipped to
accommodate (because Git's test suite expects to be able to use
Unix-like paths even on Windows).

The test script t1006-cat-file.sh contains two prime examples, two test
cases that need to skip a couple assertions because they are simply
wrong in the context of Git for Windows.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot0600: fix incomplete prerequisite for a test case
Johannes Schindelin [Wed, 17 Dec 2025 14:18:42 +0000 (14:18 +0000)] 
t0600: fix incomplete prerequisite for a test case

The 'symref transaction supports symlinks' test case is guarded by the
`SYMLINK` prerequisite because `core.prefersymlinkrefs = true` requires
symbolic links to be supported.

However, the `preferSymlinkRefs` feature is not supported on Windows,
therefore this test case needs the `MINGW` prerequisite, too.

There's a couple more cases where we set this config key:

  - In a subsequent test in t0600, but there we explicitly set it to
    "false". So this would naturally be supported by Windows.

  - In t7201 we set the value to `yes`, but we never verify that the
    written reference is a symbolic link in the first place. I guess
    that we could rather remove setting the configuration value here, as
    we are about to deprecate support for symrefs via symbolic links in
    the first place. But that's certainly outside of the scope of this
    patch.

  - In t9903 we do the same, but likewise, we don't check whether the
    written file is a symbolic link.

Therefore this seems to be the only instance where the tests actually
need to be adapted.

Helped-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot0301: another fix for Windows compatibility
Johannes Schindelin [Wed, 17 Dec 2025 14:18:41 +0000 (14:18 +0000)] 
t0301: another fix for Windows compatibility

Just like 0fdcfa2f9f5 (t0301: fixes for windows compatibility,
2021-09-14) explained, we should not call `mkdir -m<mode>` in the test
suite because that would fail on Windows.

There was one forgotten instance of this which was hidden by a `SYMLINK`
prerequisite. Currently, this prevents this test case from being
executed on Windows, but with the upcoming support for symbolic links,
it would become a problem.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot0001: handle `diff --no-index` gracefully
Johannes Schindelin [Wed, 17 Dec 2025 14:18:40 +0000 (14:18 +0000)] 
t0001: handle `diff --no-index` gracefully

The test case 're-init to move gitdir symlink' wants to compare the
contents of `newdir/.git`, which is a symbolic link pointing to a file.
However, `git diff --no-index`, which is used by `test_cmp` on Windows,
does not resolve symlinks; It shows the symlink _target_ instead (with a
file mode of 120000). That is totally unexpected by the test case, which
as a consequence fails, meaning that it's a bug in the test case itself.

Co-authored-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agomingw: special-case `open(symlink, O_CREAT | O_EXCL)`
Johannes Schindelin [Wed, 17 Dec 2025 14:18:39 +0000 (14:18 +0000)] 
mingw: special-case `open(symlink, O_CREAT | O_EXCL)`

The `_wopen()` function would gladly follow a symbolic link to a
non-existent file and create it when given above-mentioned flags.

Git expects the `open()` call to fail, though. So let's add yet another
work-around to pretend that Windows behaves according to POSIX, see:
https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html#:~:text=If%20O_CREAT%20and%20O_EXCL%20are,set%2C%20the%20result%20is%20undefined.

This is required to let t4115.8(--reject removes .rej symlink if it
exists) pass on Windows when enabling the MSYS2 runtime's symbolic link
support.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoapply: symbolic links lack a "trustable executable bit"
Johannes Schindelin [Wed, 17 Dec 2025 14:18:38 +0000 (14:18 +0000)] 
apply: symbolic links lack a "trustable executable bit"

When 0482c32c334b (apply: ignore working tree filemode when
!core.filemode, 2023-12-26) fixed `git apply` to stop warning about
executable files, it inadvertently changed the code flow also for
symbolic links and directories.

Let's narrow the scope of the special `!trust_executable_git` code path
to apply only to regular files.

This is needed to let t4115.5(symlink escape when creating new files)
pass on Windows when symbolic link support is enabled in the MSYS2
runtime.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agot9700: accommodate for Windows paths
Johannes Schindelin [Wed, 17 Dec 2025 14:18:37 +0000 (14:18 +0000)] 
t9700: accommodate for Windows paths

Ever since fe53bbc9beb (Git.pm: Always set Repository to absolute path
if autodetecting, 2009-05-07), the t9700 test _must_ fail on Windows
because of that age-old Unix paths vs Windows paths problem.

The underlying root cause is that Git cannot run with a regular Win32
variant of Perl, the assumption that every path is a Unix path is just
too strong in Git's Perl code.

As a consequence, Git for Windows is basically stuck with using the
MSYS2 variant of Perl which uses a POSIX emulation layer (which is a
friendly fork of Cygwin) _and_ a best-effort Unix <-> Windows paths
conversion whenever crossing the boundary between MSYS2 and regular
Win32 processes. It is best effort only, though, using heuristics to
automagically convert correctly in most cases, but not in all cases.

In the context of this here patch, this means that asking `git.exe` for
the absolute path of the `.git/` directory will return a Win32 path
because `git.exe` is a regular Win32 executable that has no idea about
Unix-ish paths. But above-mentioned commit introduced a test that wants
to verify that this path is identical to the one that the Git Perl
module reports (which refuses to use Win32 paths and uses Unix-ish paths
instead). Obviously, this must fail because no heuristics can kick in at
that layer.

This test failure has not even been caught when Git introduced Windows
support in its CI definition in 2e90484eb4a (ci: add a Windows job to
the Azure Pipelines definition, 2019-01-29), as all tests relying on
Perl had to be disabled even from the start (because the CI runs would
otherwise have resulted in prohibitively long runtimes, not because
Windows is super slow per se, but because Git's test suite keeps
insisting on using technology that requires a POSIX emulation layer,
which _is_ super slow on Windows).

To work around this failure, let's use the `cygpath` utility to convert
the absolute `gitdir` path into the form that the Perl code expects.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoThe 10th batch
Junio C Hamano [Wed, 17 Dec 2025 05:11:28 +0000 (14:11 +0900)] 
The 10th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoMerge branch 'kh/doc-send-email-paragraph-fix'
Junio C Hamano [Wed, 17 Dec 2025 05:11:53 +0000 (14:11 +0900)] 
Merge branch 'kh/doc-send-email-paragraph-fix'

Docfix.

* kh/doc-send-email-paragraph-fix:
  doc: send-email: fix broken list continuation

5 weeks agoMerge branch 'mh/doc-config-gui-gcwarning'
Junio C Hamano [Wed, 17 Dec 2025 05:11:53 +0000 (14:11 +0900)] 
Merge branch 'mh/doc-config-gui-gcwarning'

Docfix.

* mh/doc-config-gui-gcwarning:
  config: document 'gui.GCWarning'

5 weeks agoMerge branch 'kh/doc-pre-commit-fix'
Junio C Hamano [Wed, 17 Dec 2025 05:11:53 +0000 (14:11 +0900)] 
Merge branch 'kh/doc-pre-commit-fix'

Docfix.

* kh/doc-pre-commit-fix:
  doc: join default pre-commit paragraphs

5 weeks agoMerge branch 'jc/capability-leak'
Junio C Hamano [Wed, 17 Dec 2025 05:11:52 +0000 (14:11 +0900)] 
Merge branch 'jc/capability-leak'

Leakfix.

* jc/capability-leak:
  connect: plug protocol capability leak

5 weeks agoThe ninth batch
Junio C Hamano [Tue, 16 Dec 2025 02:08:23 +0000 (11:08 +0900)] 
The ninth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoMerge branch 'rs/ban-mktemp'
Junio C Hamano [Tue, 16 Dec 2025 02:08:34 +0000 (11:08 +0900)] 
Merge branch 'rs/ban-mktemp'

Rewrite the only use of "mktemp()" that is subject to TOCTOU race
and Stop using the insecure "mktemp()" function.

* rs/ban-mktemp:
  compat: remove gitmkdtemp()
  banned.h: ban mktemp(3)
  compat: remove mingw_mktemp()
  compat: use git_mkdtemp()
  wrapper: add git_mkdtemp()

5 weeks agoMerge branch 'gf/win32-pthread-cond-init'
Junio C Hamano [Tue, 16 Dec 2025 02:08:34 +0000 (11:08 +0900)] 
Merge branch 'gf/win32-pthread-cond-init'

Emulation code clean-up.

* gf/win32-pthread-cond-init:
  win32: pthread_cond_init should return a value

5 weeks agoMerge branch 'ps/object-read-stream'
Junio C Hamano [Tue, 16 Dec 2025 02:08:34 +0000 (11:08 +0900)] 
Merge branch 'ps/object-read-stream'

The "git_istream" abstraction has been revamped to make it easier
to interface with pluggable object database design.

* ps/object-read-stream:
  streaming: drop redundant type and size pointers
  streaming: move into object database subsystem
  streaming: refactor interface to be object-database-centric
  streaming: move logic to read packed objects streams into backend
  streaming: move logic to read loose objects streams into backend
  streaming: make the `odb_read_stream` definition public
  streaming: get rid of `the_repository`
  streaming: rely on object sources to create object stream
  packfile: introduce function to read object info from a store
  streaming: move zlib stream into backends
  streaming: create structure for filtered object streams
  streaming: create structure for packed object streams
  streaming: create structure for loose object streams
  streaming: create structure for in-core object streams
  streaming: allocate stream inside the backend-specific logic
  streaming: explicitly pass packfile info when streaming a packed object
  streaming: propagate final object type via the stream
  streaming: drop the `open()` callback function
  streaming: rename `git_istream` into `odb_read_stream`

5 weeks agoThe eighth batch
Junio C Hamano [Sun, 14 Dec 2025 08:04:17 +0000 (17:04 +0900)] 
The eighth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 weeks agoMerge branch 'je/doc-data-model'
Junio C Hamano [Sun, 14 Dec 2025 08:04:38 +0000 (17:04 +0900)] 
Merge branch 'je/doc-data-model'

Docfix.

* je/doc-data-model:
  doc: remove stray text in Git data model

5 weeks agoMerge branch 'lo/repo-struct-z'
Junio C Hamano [Sun, 14 Dec 2025 08:04:37 +0000 (17:04 +0900)] 
Merge branch 'lo/repo-struct-z'

"git repo struct" learned to take "-z" as a synonym to "--format=nul".

* lo/repo-struct-z:
  repo: add -z as an alias for --format=nul to git-repo-structure
  repo: use [--format=... | -z] instead of [-z] in git-repo-info synopsis
  repo: remove blank line from Documentation/git-repo.adoc

5 weeks agoMerge branch 'kh/advise-w-git-help-in-branch'
Junio C Hamano [Sun, 14 Dec 2025 08:04:37 +0000 (17:04 +0900)] 
Merge branch 'kh/advise-w-git-help-in-branch'

A help message from "git branch" now mentions "git help" instead of
"man" when suggesting to read some documentation.

* kh/advise-w-git-help-in-branch:
  branch: advice using git-help(1) instead of man(1)

5 weeks agoMerge branch 'je/doc-pull'
Junio C Hamano [Sun, 14 Dec 2025 08:04:37 +0000 (17:04 +0900)] 
Merge branch 'je/doc-pull'

Doc fixup.

* je/doc-pull:
  doc: git-pull: fix 'git --rebase abort' typo

5 weeks agoMerge branch 'tc/meson-cross-compile-fix'
Junio C Hamano [Sun, 14 Dec 2025 08:04:37 +0000 (17:04 +0900)] 
Merge branch 'tc/meson-cross-compile-fix'

Build fix.

* tc/meson-cross-compile-fix:
  meson: use is_cross_build() where possible
  meson: only detect ICONV_OMITS_BOM if possible
  meson: ignore subprojects/.wraplock

5 weeks agoMerge branch 'js/last-modified-with-sparse-checkouts'
Junio C Hamano [Sun, 14 Dec 2025 08:04:36 +0000 (17:04 +0900)] 
Merge branch 'js/last-modified-with-sparse-checkouts'

"git last-modified" used to mishandle "--" to mark the beginning of
pathspec, which has been corrected.

* js/last-modified-with-sparse-checkouts:
  last-modified: support sparse checkouts

5 weeks agoMerge branch 'rs/diff-index-find-copies-harder-optim'
Junio C Hamano [Sun, 14 Dec 2025 08:04:36 +0000 (17:04 +0900)] 
Merge branch 'rs/diff-index-find-copies-harder-optim'

Halve the memory consumed by artificial filepairs created during
"git diff --find-copioes-harder", also making the operation run
faster.

* rs/diff-index-find-copies-harder-optim:
  diff-index: don't queue unchanged filepairs with diff_change()

5 weeks agoMerge branch 'tc/last-modified-active-paths-optimization'
Junio C Hamano [Sun, 14 Dec 2025 08:04:36 +0000 (17:04 +0900)] 
Merge branch 'tc/last-modified-active-paths-optimization'

Recent optimization to "last-modified" command introduced use of
uninitialized block of memory, which has been corrected.

* tc/last-modified-active-paths-optimization:
  last-modified: fix use of uninitialized memory

6 weeks agoThe seventh batch
Junio C Hamano [Mon, 8 Dec 2025 22:53:51 +0000 (07:53 +0900)] 
The seventh batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoMerge branch 'en/replay-doc-revision-range'
Junio C Hamano [Mon, 8 Dec 2025 22:54:56 +0000 (07:54 +0900)] 
Merge branch 'en/replay-doc-revision-range'

The use of "revision" (a connected set of commits) has been
clarified in the "git replay" documentation.

* en/replay-doc-revision-range:
  Documentation/git-replay.adoc: fix errors around revision range

6 weeks agoMerge branch 'yc/xdiff-patience-optim'
Junio C Hamano [Mon, 8 Dec 2025 22:54:55 +0000 (07:54 +0900)] 
Merge branch 'yc/xdiff-patience-optim'

The way patience diff finds LCS has been optimized.

* yc/xdiff-patience-optim:
  xdiff: optimize patience diff's LCS search

6 weeks agoMerge branch 'bc/zsh-testsuite'
Junio C Hamano [Mon, 8 Dec 2025 22:54:54 +0000 (07:54 +0900)] 
Merge branch 'bc/zsh-testsuite'

A few tests have been updated to work under the shell compatible
mode of zsh.

* bc/zsh-testsuite:
  t5564: fix test hang under zsh's sh mode
  t0614: use numerical comparison with test_line_count

6 weeks agoMerge branch 'pw/replay-exclude-gpgsig-fix'
Junio C Hamano [Mon, 8 Dec 2025 22:54:53 +0000 (07:54 +0900)] 
Merge branch 'pw/replay-exclude-gpgsig-fix'

"git replay" forgot to omit the "gpgsig-sha256" extended header
from the resulting commit the same way it omits "gpgsig", which has
been corrected.

* pw/replay-exclude-gpgsig-fix:
  replay: do not copy "gpgsign-sha256" header

6 weeks agoconfig: document 'gui.GCWarning'
Matthew Hughes [Mon, 8 Dec 2025 19:04:35 +0000 (19:04 +0000)] 
config: document 'gui.GCWarning'

While investigating the config options set by 'scalar' I noticed this
one wasn't documented.

Signed-off-by: Matthew Hughes <matthewhughes934@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agodoc: send-email: fix broken list continuation
Kristoffer Haugsbakk [Mon, 8 Dec 2025 17:41:01 +0000 (18:41 +0100)] 
doc: send-email: fix broken list continuation

The list continuation has to be “immediately adjacent to the block
being attached”.[1]

[1]: https://web.archive.org/web/20251208172615/https://docs.asciidoctor.org/asciidoc/latest/lists/continuation/

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agoconnect: plug protocol capability leak
Junio C Hamano [Sun, 7 Dec 2025 04:40:46 +0000 (13:40 +0900)] 
connect: plug protocol capability leak

When pushing to a set of remotes using a nickname for the group, the
client initializes the connection to each remote, talks to the
remote and reads and parses capabilities line, and holds the
capabilities in a file-scope static variable server_capabilities_v1.

There are a few other such file-scope static variables, and these
connections cannot be parallelized until they are refactored to a
structure that keeps track of active connections.

Which is *not* the theme of this patch ;-)

For a single connection, the server_capabilities_v1 variable is
initialized to NULL (at the program initialization), populated when
we talk to the other side, used to look up capabilities of the other
side possibly multiple times, and the memory is held by the variable
until program exit, without leaking.  When talking to multiple remotes,
however, the server capabilities from the second connection overwrites
without freeing the one from the first connection, which leaks.

    ==1080970==ERROR: LeakSanitizer: detected memory leaks

    Direct leak of 421 byte(s) in 2 object(s) allocated from:
#0 0x5615305f849e in strdup (/home/gitster/g/git-jch/bin/bin/git+0x2b349e) (BuildId: 54d149994c9e85374831958f694bd0aa3b8b1e26)
#1 0x561530e76cc4 in xstrdup /home/gitster/w/build/wrapper.c:43:14
#2 0x5615309cd7fa in process_capabilities /home/gitster/w/build/connect.c:243:27
#3 0x5615309cd502 in get_remote_heads /home/gitster/w/build/connect.c:366:4
#4 0x561530e2cb0b in handshake /home/gitster/w/build/transport.c:372:3
#5 0x561530e29ed7 in get_refs_via_connect /home/gitster/w/build/transport.c:398:9
#6 0x561530e26464 in transport_push /home/gitster/w/build/transport.c:1421:16
#7 0x561530800bec in push_with_options /home/gitster/w/build/builtin/push.c:387:8
#8 0x5615307ffb99 in do_push /home/gitster/w/build/builtin/push.c:442:7
#9 0x5615307fe926 in cmd_push /home/gitster/w/build/builtin/push.c:664:7
#10 0x56153065673f in run_builtin /home/gitster/w/build/git.c:506:11
#11 0x56153065342f in handle_builtin /home/gitster/w/build/git.c:779:9
#12 0x561530655b89 in run_argv /home/gitster/w/build/git.c:862:4
#13 0x561530652cba in cmd_main /home/gitster/w/build/git.c:984:19
#14 0x5615308dda0a in main /home/gitster/w/build/common-main.c:9:11
#15 0x7f051651bca7 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

    SUMMARY: AddressSanitizer: 421 byte(s) leaked in 2 allocation(s).

Free the capablities data for the previous server before overwriting
it with the next server to plug this leak.

The added test fails without the freeing with SANITIZE=leak; I
somehow couldn't get it fail reliably with SANITIZE=leak,address
though.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agodoc: join default pre-commit paragraphs
Kristoffer Haugsbakk [Mon, 8 Dec 2025 07:27:11 +0000 (08:27 +0100)] 
doc: join default pre-commit paragraphs

Join two paragraphs that start with the standard “The default <hook>,
when enabled” into one and put it at the end of the “pre-commit”
section.

The trailing whitespace paragraph was added in the first commit for the
doc, in 6d35cc76 (Document hooks., 2005-09-02). Then 3e14dd2c (mention
use of "hooks.allownonascii" in "man githooks", 2019-02-20) updated the
“pre-commit” section to mention the non-ASCII check that was added in
d00e364d.[1] But this paragraph was added one-past the original
“default” paragraph, after the env. variable paragraph, and starts
exactly the same. That causes the flow of this section to feel
off (paragraphs in order):

1. Invoked by <cmd> and what parameters it takes
2. The default 'pre-commit' hook catches introduction of trailing
   whitespace
3. `GIT_EDITOR=:`
4. The default pre-commit' hook catches introduction of non-ASCII
   filenames

Let’s instead join these two paragrahs and explain the whole behavior of
the default script.

† 1: Extend sample pre-commit hook to check for non ascii filenames,
     2009-05-19

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agocompat: remove gitmkdtemp()
René Scharfe [Sat, 6 Dec 2025 13:35:39 +0000 (14:35 +0100)] 
compat: remove gitmkdtemp()

gitmkdtemp() has become a trivial wrapper around git_mkdtemp().  Remove
this now unnecessary layer of indirection.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agobanned.h: ban mktemp(3)
René Scharfe [Sat, 6 Dec 2025 13:29:43 +0000 (14:29 +0100)] 
banned.h: ban mktemp(3)

Older versions of mktemp(3) generate easily guessable file names.  The
function checks if the generated name is used, which is unreliable, as
a file with that name might then be created by some other process before
we can do it ourselves.  The function was dropped from POSIX due to its
security problems.  Forbid its use.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agocompat: remove mingw_mktemp()
René Scharfe [Sat, 6 Dec 2025 13:28:26 +0000 (14:28 +0100)] 
compat: remove mingw_mktemp()

Remove the mktemp(3) compatibility function now that its last caller was
removed by the previous commit.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agocompat: use git_mkdtemp()
René Scharfe [Sat, 6 Dec 2025 13:27:47 +0000 (14:27 +0100)] 
compat: use git_mkdtemp()

A file might appear at the path returned by mktemp(3) before we call
mkdir(2).  Use the more robust git_mkdtemp() instead, which retries a
number of times and doesn't need to call lstat(2).

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 weeks agowrapper: add git_mkdtemp()
René Scharfe [Sat, 6 Dec 2025 13:27:39 +0000 (14:27 +0100)] 
wrapper: add git_mkdtemp()

Extend git_mkstemps_mode() to optionally call mkdir(2) instead of
open(2), then use that ability to create a mkdtemp(3) replacement,
git_mkdtemp().  We'll start using it in the next commit.

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agoThe sixth batch
Junio C Hamano [Fri, 5 Dec 2025 05:49:13 +0000 (14:49 +0900)] 
The sixth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agoMerge branch 'rs/config-set-multi-error-message-fix'
Junio C Hamano [Fri, 5 Dec 2025 05:49:59 +0000 (14:49 +0900)] 
Merge branch 'rs/config-set-multi-error-message-fix'

The error message given by "git config set", when the variable
being updated has more than one values defined, used old style "git
config" syntax with an incorrect option in its hint, both of which
have been corrected.

* rs/config-set-multi-error-message-fix:
  config: fix suggestion for failed set of multi-valued option

7 weeks agoMerge branch 'rs/config-unset-opthelp-fix'
Junio C Hamano [Fri, 5 Dec 2025 05:49:59 +0000 (14:49 +0900)] 
Merge branch 'rs/config-unset-opthelp-fix'

The option help text given by "git config unset -h" described
the "--all" option to "replace", not "unset", multiple variables,
which has been corrected.

* rs/config-unset-opthelp-fix:
  config: fix short help of unset flags

7 weeks agoMerge branch 'ps/object-source-management'
Junio C Hamano [Fri, 5 Dec 2025 05:49:58 +0000 (14:49 +0900)] 
Merge branch 'ps/object-source-management'

Code refactoring around object database sources.

* ps/object-source-management:
  odb: handle recreation of quarantine directories
  odb: handle changing a repository's commondir
  chdir-notify: add function to unregister listeners
  odb: handle initialization of sources in `odb_new()`
  http-push: stop setting up `the_repository` for each reference
  t/helper: stop setting up `the_repository` repeatedly
  builtin/index-pack: fix deferred fsck outside repos
  oidset: introduce `oidset_equal()`
  odb: move logic to disable ref updates into repo
  odb: refactor `odb_clear()` to `odb_free()`
  odb: adopt logic to close object databases
  setup: convert `set_git_dir()` to have file scope
  path: move `enter_repo()` into "setup.c"

7 weeks agoMerge branch 'cc/fast-import-strip-if-invalid'
Junio C Hamano [Fri, 5 Dec 2025 05:49:58 +0000 (14:49 +0900)] 
Merge branch 'cc/fast-import-strip-if-invalid'

"git fast-import" learns "--strip-if-invalid" option to drop
invalid cryptographic signature from objects.

* cc/fast-import-strip-if-invalid:
  fast-import: add 'strip-if-invalid' mode to --signed-commits=<mode>
  commit: refactor verify_commit_buffer()
  fast-import: refactor finalize_commit_buffer()

7 weeks agoMerge branch 'js/ci-show-breakage-in-dockerized-jobs'
Junio C Hamano [Fri, 5 Dec 2025 05:49:58 +0000 (14:49 +0900)] 
Merge branch 'js/ci-show-breakage-in-dockerized-jobs'

Dockerised jobs at the GitHub Actions CI have been taught to show
more details of failed tests.

* js/ci-show-breakage-in-dockerized-jobs:
  ci(dockerized): do show the result of failing tests again

7 weeks agoMerge branch 'kh/doc-committer-date-is-author-date'
Junio C Hamano [Fri, 5 Dec 2025 05:49:57 +0000 (14:49 +0900)] 
Merge branch 'kh/doc-committer-date-is-author-date'

The "--committer-date-is-author-date" option of "git am/rebase" is
a misguided one.  The documentation is updated to discourage its
use.

* kh/doc-committer-date-is-author-date:
  doc: warn against --committer-date-is-author-date

7 weeks agoMerge branch 'jc/optional-path'
Junio C Hamano [Fri, 5 Dec 2025 05:49:56 +0000 (14:49 +0900)] 
Merge branch 'jc/optional-path'

"git config get --path" segfaulted on an ":(optional)path" that
does not exist, which has been corrected.

* jc/optional-path:
  config: really treat missing optional path as not configured
  config: really pretend missing :(optional) value is not there
  config: mark otherwise unused function as file-scope static

7 weeks agoMerge branch 'js/strip-scalar-too'
Junio C Hamano [Fri, 5 Dec 2025 05:49:56 +0000 (14:49 +0900)] 
Merge branch 'js/strip-scalar-too'

"make strip" has been taught to strip "scalar" as well as "git".

* js/strip-scalar-too:
  make strip: include `scalar`

7 weeks agoMerge branch 'en/xdiff-cleanup-2'
Junio C Hamano [Fri, 5 Dec 2025 05:49:56 +0000 (14:49 +0900)] 
Merge branch 'en/xdiff-cleanup-2'

Code clean-up.

* en/xdiff-cleanup-2:
  xdiff: rename rindex -> reference_index
  xdiff: change rindex from long to size_t in xdfile_t
  xdiff: make xdfile_t.nreff a size_t instead of long
  xdiff: make xdfile_t.nrec a size_t instead of long
  xdiff: split xrecord_t.ha into line_hash and minimal_perfect_hash
  xdiff: use unambiguous types in xdl_hash_record()
  xdiff: use size_t for xrecord_t.size
  xdiff: make xrecord_t.ptr a uint8_t instead of char
  xdiff: use ptrdiff_t for dstart/dend
  doc: define unambiguous type mappings across C and Rust

7 weeks agorepo: add -z as an alias for --format=nul to git-repo-structure
Lucas Seiki Oshiro [Thu, 4 Dec 2025 20:10:12 +0000 (17:10 -0300)] 
repo: add -z as an alias for --format=nul to git-repo-structure

Other Git commands that have nul-terminated output, such as git-config,
git-status, git-ls-files, and git-repo-info have a flag `-z` for using
the null character as the record separator.

Add the `-z` flag to git-repo-structure as an alias for `--format=nul`,
making it consistent with the behavior of the other commands.

Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agorepo: use [--format=... | -z] instead of [-z] in git-repo-info synopsis
Lucas Seiki Oshiro [Thu, 4 Dec 2025 20:10:11 +0000 (17:10 -0300)] 
repo: use [--format=... | -z] instead of [-z] in git-repo-info synopsis

The flag -z is only an alias for --format=null and even though --format
and -z can be used together and repeated, only the last one is
considered.

Replace `[-z]` in the synopsis of git-repo-info by
`[--format=... | -z]`, expliciting that the use of one of those flags
replace the other.

Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agorepo: remove blank line from Documentation/git-repo.adoc
Lucas Seiki Oshiro [Thu, 4 Dec 2025 20:10:10 +0000 (17:10 -0300)] 
repo: remove blank line from Documentation/git-repo.adoc

There was an extra blank line in git-repo-structure documentation, which
led to an unwawnted '+' character after generating an HTML or PDF from
that page. This can be seen, for example, in Git 2.52.0 online docs [1].

Remove that extra line.

[1] https://git-scm.com/docs/git-repo/2.52.0

Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agomeson: use is_cross_build() where possible
Toon Claes [Wed, 3 Dec 2025 14:53:31 +0000 (15:53 +0100)] 
meson: use is_cross_build() where possible

In previous commit the first use of meson.can_run_host_binaries() was
introduced. This is a guard around compiler.run() to ensure it's
actually possible to execute the provided.

In other places we've been having the same issue, but here `not
meson.is_cross_build()` is used as guard. This does the trick, but it
also prevents the code from running even when an exe_wrapper is
configured.

Switch to using meson.can_run_host_binaries() here as well.

There is another place left that still uses `not
meson.is_cross_build()`, but here it's a guard around fs.exists(). That
function will always run on the build machine, so checking for
cross-compilation is still in place here.

Signed-off-by: Toon Claes <toon@iotcl.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agomeson: only detect ICONV_OMITS_BOM if possible
Toon Claes [Tue, 2 Dec 2025 10:48:09 +0000 (11:48 +0100)] 
meson: only detect ICONV_OMITS_BOM if possible

In our Meson setup it automatically detects whether ICONV_OMITS_BOM
should be defined. To check this, a piece of code is compiled and ran.

When cross-compiling, it's not possible to run this piece of code. Guard
this test with a can_run_host_binaries() check to ensure it can run.

Signed-off-by: Toon Claes <toon@iotcl.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agomeson: ignore subprojects/.wraplock
Toon Claes [Tue, 2 Dec 2025 10:48:08 +0000 (11:48 +0100)] 
meson: ignore subprojects/.wraplock

When asking Meson to wrap subprojects, it generates a .wraplock file in
the subprojects/ directory. Ignore this file.

See also https://github.com/mesonbuild/meson/issues/14948.

Signed-off-by: Toon Claes <toon@iotcl.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agolast-modified: support sparse checkouts
Johannes Schindelin [Sat, 29 Nov 2025 13:43:46 +0000 (13:43 +0000)] 
last-modified: support sparse checkouts

In a sparse checkout, a user might want to run `last-modified` on a
directory outside the worktree.

And even in non-sparse checkouts, a user might need to run that command
on a directory that does not exist in the worktree.

These use cases should be supported via the `--` separator between
revision and file arguments, which is even advertised in the
documentation. This patch fixes a tiny bug that prevents that from
working.

This fixes https://github.com/git-for-windows/git/issues/5978

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Acked-by: Derrick Stolee <stolee@gmail.com>
Acked-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agodoc: git-pull: fix 'git --rebase abort' typo
Julia Evans [Wed, 3 Dec 2025 15:34:55 +0000 (15:34 +0000)] 
doc: git-pull: fix 'git --rebase abort' typo

An earlier commit e9d221b0 (doc: git-pull: clarify how to exit a
conflicted merge, 2025-10-15) misspelt `git rebase --abort` to
`git --rebase abort`.  Fix it.

Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agodoc: remove stray text in Git data model
Julia Evans [Tue, 2 Dec 2025 18:11:24 +0000 (18:11 +0000)] 
doc: remove stray text in Git data model

I meant to delete this sentence fragment when rewriting this paragraph,
but accidentally left it in. It's repetitive (since it was meant to be
deleted) and it's causing some formatting issues with the note.

Signed-off-by: Julia Evans <julia@jvns.ca>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agobranch: advice using git-help(1) instead of man(1)
Kristoffer Haugsbakk [Tue, 2 Dec 2025 15:56:51 +0000 (16:56 +0100)] 
branch: advice using git-help(1) instead of man(1)

8fbd903e (branch: advise about ref syntax rules, 2024-03-05) added
an advice about checking git-check-ref-format(1) for the ref syntax
rules. The advice uses man(1). But git(1) is a multi-platform tool and
man(1) may not be available on some platforms. It might also be slightly
jarring to see a suggestion for running a command which is not from
the Git suite.

Let’s instead use git-help(1) in order to stay inside the land of
git(1). This also means that `help.format` (for `man`, `html` or other
formats) will be used if set.

Also change to using single quotes (') to quote the command since that
is more conventional.

While here let’s also update the test to use `{SQ}`, which is more
readable and easier to edit.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agoThe fifth batch
Junio C Hamano [Mon, 1 Dec 2025 02:31:24 +0000 (18:31 -0800)] 
The fifth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agoMerge branch 'jk/asan-bonanza'
Junio C Hamano [Mon, 1 Dec 2025 02:31:41 +0000 (18:31 -0800)] 
Merge branch 'jk/asan-bonanza'

Various issues detected by Asan have been corrected.

* jk/asan-bonanza:
  t: enable ASan's strict_string_checks option
  fsck: avoid parse_timestamp() on buffer that isn't NUL-terminated
  fsck: remove redundant date timestamp check
  fsck: avoid strcspn() in fsck_ident()
  fsck: assert newline presence in fsck_ident()
  cache-tree: avoid strtol() on non-string buffer
  Makefile: turn on NO_MMAP when building with ASan
  pack-bitmap: handle name-hash lookups in incremental bitmaps
  compat/mmap: mark unused argument in git_munmap()

7 weeks agoMerge branch 'je/doc-data-model'
Junio C Hamano [Mon, 1 Dec 2025 02:31:40 +0000 (18:31 -0800)] 
Merge branch 'je/doc-data-model'

Add a new manual that describes the data model.

* je/doc-data-model:
  doc: add an explanation of Git's data model

7 weeks agoMerge branch 'jc/whitespace-incomplete-line'
Junio C Hamano [Mon, 1 Dec 2025 02:31:40 +0000 (18:31 -0800)] 
Merge branch 'jc/whitespace-incomplete-line'

Both "git apply" and "git diff" learn a new whitespace error class,
"incomplete-line".

* jc/whitespace-incomplete-line:
  attr: enable incomplete-line whitespace error for this project
  diff: highlight and error out on incomplete lines
  apply: check and fix incomplete lines
  whitespace: allocate a few more bits and define WS_INCOMPLETE_LINE
  apply: revamp the parsing of incomplete lines
  diff: update the way rewrite diff handles incomplete lines
  diff: call emit_callback ecbdata everywhere
  diff: refactor output of incomplete line
  diff: keep track of the type of the last line seen
  diff: correct suppress_blank_empty hack
  diff: emit_line_ws_markup() if/else style fix
  whitespace: correct bit assignment comments

7 weeks agoMerge branch 'ja/doc-synopsis-style'
Junio C Hamano [Mon, 1 Dec 2025 02:31:39 +0000 (18:31 -0800)] 
Merge branch 'ja/doc-synopsis-style'

Doc mark-up updates.

* ja/doc-synopsis-style:
  doc: pull-fetch-param typofix
  doc: convert git push to synopsis style
  doc: convert git pull to synopsis style
  doc: convert git fetch to synopsis style

7 weeks agoMerge branch 'lo/repo-info-all'
Junio C Hamano [Mon, 1 Dec 2025 02:31:39 +0000 (18:31 -0800)] 
Merge branch 'lo/repo-info-all'

"git repo info" learned "--all" option.

* lo/repo-info-all:
  repo: add --all to git-repo-info
  repo: factor out field printing to dedicated function

7 weeks agodiff-index: don't queue unchanged filepairs with diff_change()
René Scharfe [Sun, 30 Nov 2025 11:47:17 +0000 (12:47 +0100)] 
diff-index: don't queue unchanged filepairs with diff_change()

diff_cache() queues unchanged filepairs if the flag find_copies_harder
is set, and uses diff_change() for that.  This function allocates a
filespec for each side, does a few other things that are unnecessary for
unchanged filepairs and always sets the diff_flag has_changes, which is
simply misleading in this case.

Add a new streamlined function for queuing unchanged filepairs and
use it in show_modified(), which is called by diff_cache() via
oneway_diff() and do_oneway_diff().  It allocates only a single filespec
for each filepair and uses it twice with reference counting.  This has a
measurable effect if there are a lot of them, like in the Linux repo:

Benchmark 1: ./git_v2.52.0 -C ../linux diff --cached --find-copies-harder
  Time (mean ± σ):      31.8 ms ±   0.2 ms    [User: 24.2 ms, System: 6.3 ms]
  Range (min … max):    31.5 ms …  32.3 ms    85 runs

Benchmark 2: ./git -C ../linux diff --cached --find-copies-harder
  Time (mean ± σ):      23.9 ms ±   0.2 ms    [User: 18.1 ms, System: 4.6 ms]
  Range (min … max):    23.5 ms …  24.4 ms    111 runs

Summary
  ./git -C ../linux diff --cached --find-copies-harder ran
    1.33 ± 0.01 times faster than ./git_v2.52.0 -C ../linux diff --cached --find-copies-harder

Signed-off-by: René Scharfe <l.s.r@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agolast-modified: fix use of uninitialized memory
Toon Claes [Fri, 28 Nov 2025 16:37:13 +0000 (17:37 +0100)] 
last-modified: fix use of uninitialized memory

git-last-modified(1) uses a scratch bitmap to keep track of paths that
have been changed between commits. To avoid reallocating a bitmap on
each call of process_parent(), the scratch bitmap is kept and reused.
Although, it seems an incorrect length is passed to memset(3).

`struct bitmap` uses `eword_t` to for internal storage. This type is
typedef'd to uint64_t. To fully zero the memory used by the bitmap,
multiply the length (saved in `struct bitmap::word_alloc`) by the size
of `eword_t`.

Reported-by: Anders Kaseorg <andersk@mit.edu>
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 weeks agoDocumentation/git-replay.adoc: fix errors around revision range
Elijah Newren [Sat, 29 Nov 2025 04:44:24 +0000 (04:44 +0000)] 
Documentation/git-replay.adoc: fix errors around revision range

There was significant confusion in the git-replay manual about what
constitutes a revision range.  As noted in f302c1e4aa09 (revisions(7):
clarify that most commands take a single revision range, 2021-05-18):

   Commands that are specifically designed to take two distinct ranges
   (e.g. "git range-diff R1 R2" to compare two ranges) do exist, but they
   are exceptions. Unless otherwise noted, all "git" commands that operate
   on a set of commits work on a single revision range.

`git replay` is not an exception, but a few places in the manual were
written as though it were.  These appear to have come in revisions to
the original series, between v3->v4 (see
https://lore.kernel.org/git/CAP8UFD3bpLrVW97DH7j=V9H2GsTSAkksC9L3QujQERFk_kLnZA@mail.gmail.com/
, "More than one <revision-range> can be passed") and between v6->v7
(https://lore.kernel.org/git/20231115143327.2441397-1-christian.couder@gmail.com/,
"Takes ranges of commits"), and I missed both of these revisions when
reviewing.  Fix them now.

There was also a reference to the "Commit Limiting options below", but
this page has no such section of options; strike the misleading
reference.

It is worth noting that we are documenting existing behavior, rather
than optimal behavior.  Junio has multiple times suggested introducing
alternative ways to walk revisions and use them in `git replay
--advance`, e.g. at
  * https://lore.kernel.org/git/xmqqy1mqo6kv.fsf@gitster.g/
  * https://lore.kernel.org/git/xmqq8rb3is8c.fsf@gitster.g/
  * https://lore.kernel.org/git/xmqqtsydj2zk.fsf@gitster.g/ (item (2))
If/when we introduce some new revision walking flag that implements one
of these alternate types of revision walks, we can update the --advance
option and this manual appropriately.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 weeks agoxdiff: optimize patience diff's LCS search
Yee Cheng Chin [Thu, 27 Nov 2025 02:16:06 +0000 (02:16 +0000)] 
xdiff: optimize patience diff's LCS search

The find_longest_common_sequence() function in patience diff is
inefficient as it calls binary_search() for every unique line it
encounters when deciding where to put it in the sequence. From
instrumentation (using xctrace) on popular repositories, binary_search()
takes up 50-60% of the run time within patience_diff() when performing a
diff.

To optimize this, add a boundary condition check before binary_search()
is called to see if the encountered unique line is located after the
entire currently tracked longest subsequence. If so, skip the
unnecessary binary search and simply append the entry to the end of
sequence. Given that most files compared in a diff are usually quite
similar to each other, this condition is very common, and should be hit
much more frequently than the binary search.

Below are some end-to-end performance results by timing `git log
--shortstat --oneline -500 --patience` on different repositories with
the old and new code. Generally speaking this seems to give at least
8-10% speed up. The "binary search hit %" column describes how often the
algorithm enters the binary search path instead of the new faster path.
Even in the WebKit case we can see that it's quite rare (1.46%).

| Repo     | Speed difference | binary search hit % |
|----------|------------------|---------------------|
| vim      | 1.27x            | 0.01%               |
| pytorch  | 1.16x            | 0.02%               |
| cpython  | 1.14x            | 0.06%               |
| ripgrep  | 1.14x            | 0.03%               |
| git      | 1.13x            | 0.12%               |
| vscode   | 1.09x            | 0.10%               |
| WebKit   | 1.08x            | 1.46%               |

The benchmarks were done using hyperfine, on an Apple M1 Max laptop,
with git compiled with `-O3 -flto`.

Signed-off-by: Yee Cheng Chin <ychin.git@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 weeks agot5564: fix test hang under zsh's sh mode
brian m. carlson [Fri, 28 Nov 2025 01:21:06 +0000 (01:21 +0000)] 
t5564: fix test hang under zsh's sh mode

This test starts a SOCKS server in Perl in the background and then kills
it after the tests are done.  However, when using zsh (in sh mode) in
the tests, the start_socks function hangs until the background process
is killed.

Note that this does not reproduce in a simple shell script, so there is
likely some interaction between job handling, our heavy use of eval in
the test framework, and possibly other complexities of our test
framework.  What is clear, however, is that switching from a compound
statement to a subshell fixes the problem entirely and the test passes
with no problem, so do that.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 weeks agot0614: use numerical comparison with test_line_count
brian m. carlson [Fri, 28 Nov 2025 01:21:05 +0000 (01:21 +0000)] 
t0614: use numerical comparison with test_line_count

In this comparison, we want to know whether the number of lines is
greater than 1.  Our test_line_count function passes the first argument
as the comparison operator to test, so what we want is a numerical
comparison, not a string comparison.  While this does not produce a
functional problem now, it could very well if we expected two or more
items, in which case the value "10" would not match when it should.

Furthermore, the "<" and ">" comparisons are new in POSIX 1003.1-2024
and we don't want to require such a new version of POSIX since many
popular and supported operating systems were released before that
version of POSIX was released.

Finally, zsh's builtin test operator does not like the greater-than sign
in "test", since it is only supported in the double-bracket extension.
This has been reported and will be addressed in a future version, but
since our code is also technically incorrect, as well as not very
compatible, let's fix it by using a numeric comparison.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 weeks agoThe fourth batch
Junio C Hamano [Wed, 26 Nov 2025 18:22:08 +0000 (10:22 -0800)] 
The fourth batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 weeks agoMerge branch 'gf/win32-pthread-cond-wait-err'
Junio C Hamano [Wed, 26 Nov 2025 18:32:43 +0000 (10:32 -0800)] 
Merge branch 'gf/win32-pthread-cond-wait-err'

Emulation code clean-up.

* gf/win32-pthread-cond-wait-err:
  win32: return error if SleepConditionVariableCS fails

8 weeks agoMerge branch 'jk/ci-windows-meson-test-fix'
Junio C Hamano [Wed, 26 Nov 2025 18:32:43 +0000 (10:32 -0800)] 
Merge branch 'jk/ci-windows-meson-test-fix'

"Windows+meson" job at the GitHub Actions CI was hard to debug, as
it did not show and save failed test artifacts, which has been
corrected.

* jk/ci-windows-meson-test-fix:
  ci(windows-meson-test): handle options and output like other test jobs
  unit-test: ignore --no-chain-lint

8 weeks agoMerge branch 'pw/worktree-list-display-width-fix'
Junio C Hamano [Wed, 26 Nov 2025 18:32:42 +0000 (10:32 -0800)] 
Merge branch 'pw/worktree-list-display-width-fix'

"git worktree list" attempts to show paths to worktrees while
aligning them, but miscounted display columns for the paths when
non-ASCII characters were involved, which has been corrected.

* pw/worktree-list-display-width-fix:
  worktree list: quote paths
  worktree list: fix column spacing

8 weeks agoMerge branch 'js/wincred-get-credential-alloc-fix'
Junio C Hamano [Wed, 26 Nov 2025 18:32:42 +0000 (10:32 -0800)] 
Merge branch 'js/wincred-get-credential-alloc-fix'

Under-allocation fix.

* js/wincred-get-credential-alloc-fix:
  wincred: avoid memory corruption

8 weeks agoMerge branch 'js/cmake-libgit-fix'
Junio C Hamano [Wed, 26 Nov 2025 18:32:42 +0000 (10:32 -0800)] 
Merge branch 'js/cmake-libgit-fix'

Makefile based build have recently been updated to build a
libgit.a that also has reftable and xdiff objects; CMake based
build procedure has been updated to match.

* js/cmake-libgit-fix:
  cmake: stop trying to build the reftable and xdiff libraries

8 weeks agoMerge branch 'js/mingw-assign-comma-fix'
Junio C Hamano [Wed, 26 Nov 2025 18:32:41 +0000 (10:32 -0800)] 
Merge branch 'js/mingw-assign-comma-fix'

The "return errno = EFOO, -1" construct, which is heavily used in
compat/mingw.c and triggers warnings under "-Wcomma", has been
rewritten to avoid the warnings.

* js/mingw-assign-comma-fix:
  mingw: avoid the comma operator

8 weeks agoMerge branch 'js/ci-github-setup-go-update'
Junio C Hamano [Wed, 26 Nov 2025 18:32:41 +0000 (10:32 -0800)] 
Merge branch 'js/ci-github-setup-go-update'

Update a version of action used at the GitHub Actrions CI.

* js/ci-github-setup-go-update:
  ci: bump actions/setup-go from 5 to 6

8 weeks agoMerge branch 'jk/test-mktemp-leakfix'
Junio C Hamano [Wed, 26 Nov 2025 18:32:41 +0000 (10:32 -0800)] 
Merge branch 'jk/test-mktemp-leakfix'

Test leakfix.

* jk/test-mktemp-leakfix:
  test-mktemp: plug memory and descriptor leaks

8 weeks agoMerge branch 'rs/xmkstemp-simplify'
Junio C Hamano [Wed, 26 Nov 2025 18:32:40 +0000 (10:32 -0800)] 
Merge branch 'rs/xmkstemp-simplify'

Code simplification.

* rs/xmkstemp-simplify:
  wrapper: simplify xmkstemp()

8 weeks agoMerge branch 'ad/blame-diff-algorithm'
Junio C Hamano [Wed, 26 Nov 2025 18:32:40 +0000 (10:32 -0800)] 
Merge branch 'ad/blame-diff-algorithm'

"git blame" learns "--diff-algorithm=<algo>" option.

* ad/blame-diff-algorithm:
  blame: make diff algorithm configurable
  xdiff: add 'minimal' to XDF_DIFF_ALGORITHM_MASK

8 weeks agoMerge branch 'en/ort-rename-another-fix'
Junio C Hamano [Wed, 26 Nov 2025 18:32:40 +0000 (10:32 -0800)] 
Merge branch 'en/ort-rename-another-fix'

Yet another corner case fix around renames in the "ort" merge
strategy.

* en/ort-rename-another-fix:
  merge-ort: fix failing merges in special corner case
  merge-ort: remove debugging crud
  t6429: update comment to mention correct tool

8 weeks agoci(dockerized): do show the result of failing tests again
Johannes Schindelin [Mon, 17 Nov 2025 17:04:24 +0000 (17:04 +0000)] 
ci(dockerized): do show the result of failing tests again

The quality of tests and test suites is most apparent not when
everything passes, but in how quickly bugs can be identified,
analyzed, and resolved after test failures occur.

As such, it is an unfortunate side effect of 2a21098b98a (github: adapt
containerized jobs to be rootless, 2025-01-10) that the output of failed
test cases, which was shown before that change directly in the build
logs, is now no longer shown at all.

The reason is a side effect of trying to run the build and the tests
with permissions other than the `root` user, but without providing the
prerequisite permissions to signal what tests failed and whose output
hence needs to be included in the logs.

The way this signaling works is for the workflow to write into
special-purpose files whose path is specific to the current workflow
step and which can be accessed via the `$GITHUB_ENV` environment
variable, which differs between workflow steps. It is this file that is
missing write permission for the `builder` user that was introduced in
above-mentioned commit.

The solution is simple: make the file world-writable.

Technically, this write permission should be removed after the step has
completed, if proper security practices were to be upheld, but since
nothing uses that file again, it does not matter, and the fix is more
succinct this way.

This commit is best viewed with `--color-words`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
[jc: squashed Elijah's rewrite of the first paragraph of the log message]
[jc: updated chmod to match "world-writable" in the log message]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 weeks agoMerge branch 'master' of https://github.com/j6t/gitk
Junio C Hamano [Wed, 26 Nov 2025 17:35:09 +0000 (09:35 -0800)] 
Merge branch 'master' of https://github.com/j6t/gitk

* 'master' of https://github.com/j6t/gitk:
  gitk: add external diff file rename detection
  gitk: show unescaped file names on 'rename' and 'copy' lines
  gitk: fix a 'continue' statement outside a loop to 'return'
  gitk: persist position and size of the Tags and Heads window
  Revert "gitk: Only restore window size from ~/.gitk, not position"

8 weeks agoreplay: do not copy "gpgsign-sha256" header
Phillip Wood [Wed, 26 Nov 2025 14:33:37 +0000 (14:33 +0000)] 
replay: do not copy "gpgsign-sha256" header

When "git replay" replays a commit it copies the extended headers
across from the original commit. However, if the original commit
was signed, we do not want to copy the header associated with the
signature is it wont be valid for the new commit. The code already
knows to avoid coping the "gpgsig" header but does not know to avoid
copying the "gpgsig-sha256" header.  Add that header to the list of
exclusions to match what "git commit --amend" does.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 weeks agofast-import: add 'strip-if-invalid' mode to --signed-commits=<mode>
Christian Couder [Mon, 17 Nov 2025 04:34:50 +0000 (05:34 +0100)] 
fast-import: add 'strip-if-invalid' mode to --signed-commits=<mode>

Tools like `git filter-repo`[1] use `git fast-export` and
`git fast-import` to rewrite repository history. When rewriting
history using one such tool though, commit signatures might become
invalid because the commits they sign changed due to the changes
in the repository history made by the tool between the fast-export
and the fast-import steps.

Note that as far as signature handling goes:

  * Since fast-export doesn't know what changes filter-repo may make
to the stream, it can't know whether the signatures will still be
valid.

  * Since filter-repo doesn't know what history canonicalizations
fast-export performed (and it performs a few), it can't know whether
the signatures will still be valid.

  * Therefore, fast-import is the only process in the pipeline that
can know whether a specified signature remains valid.

Having invalid signatures in a rewritten repository could be
confusing, so users rewritting history might prefer to simply
discard signatures that are invalid at the fast-import step.

For example a common use case is to rewrite only "recent" history.
While specifying commit ranges corresponding to "recent" commits
could work, users worry about getting it wrong and want to just
automatically rewrite everything, expecting older commit signatures
to be untouched.

To let them do that, let's add a new 'strip-if-invalid' mode to the
`--signed-commits=<mode>` option of `git fast-import`.

It would be interesting for the `--signed-tags=<mode>` option to
have this mode too, but we leave that for a future improvement.

It might also be possible for `git fast-export` to have such a mode
in its `--signed-commits=<mode>` and `--signed-tags=<mode>`
options, but the use cases for it are much less clear, so we also
leave that for possible future improvements.

For now let's just die() if 'strip-if-invalid' is passed to these
options where it hasn't been implemented yet.

[1]: https://github.com/newren/git-filter-repo

Helped-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
8 weeks agoMerge branch 'tb/external-diff-renamed'
Johannes Sixt [Wed, 26 Nov 2025 15:04:14 +0000 (16:04 +0100)] 
Merge branch 'tb/external-diff-renamed'

* tb/external-diff-renamed:
  gitk: add external diff file rename detection