Commit Graph

81684 Commits (aebf83d00a707e6ba232f07dc439ddcf8cf4bbbd)

Author SHA1 Message Date
Harald Nordgren 3372505ee8 git-gui: silence install recipes under "make -s"
Several install and uninstall recipes embed "echo" calls that fire as
part of the recipe itself, so the install banners (DEST, INSTALL,
LINK, REMOVE) were visible whenever the variables expand non-empty.

Guard the whole "ifndef V" block on "-s" so the loud variants are
selected only when "-s" is absent and V=1 is unset. The existing
"-s" check also had its findstring arguments in the wrong order
(needle "-s" never fit in haystack "s"), so swap them while moving
the check to wrap the block.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-06 13:45:19 +02:00
Alexander Monakov d1b72b29e9 doc: fix typo in GIT_ALTERNATE_OBJECT_DIRECTORIES
One file accidentally spelled GIT_ALTERNATE_OBJECT_DIRECTORIES with
REPOSITORIES instead of DIRECTORIES. Fix the typo.

Signed-off-by: Alexander Monakov <amonakov@ispras.ru>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-06 11:04:03 +09:00
Lucas Seiki Oshiro 4a1eb9304a Documentation: remove redundant 'instead' in --subject-prefix
The documentation for --subject-prefix has two words "instead" in
the same sentence, making it a little bit confusing to read.

Change the order of the phrase to a more natural "Use [...]
instead of [...]" structure.

Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 22:44:36 +09:00
Johannes Schindelin 363f1d8b3a mingw: really handle SIGINT
Previously, we did not install any handler for Ctrl+C, but now we really
want to because the MSYS2 runtime learned the trick to call the
ConsoleCtrlHandler when Ctrl+C was pressed.

With this, hitting Ctrl+C while `git log` is running will only terminate
the Git process, but not the pager. This finally matches the behavior on
Linux and on macOS.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 22:39:57 +09:00
Johannes Schindelin 179f122aea mingw: kill child processes in a gentler way
The TerminateProcess() function does not actually leave the child
processes any chance to perform any cleanup operations. This is bad
insofar as Git itself expects its signal handlers to run.

A symptom is e.g. a left-behind .lock file that would not be left behind
if the same operation was run, say, on Linux.

To remedy this situation, we use an obscure trick: we inject a thread
into the process that needs to be killed and to let that thread run the
ExitProcess() function with the desired exit status. Thanks J Wyman for
describing this trick.

The advantage is that the ExitProcess() function lets the atexit
handlers run. While this is still different from what Git expects (i.e.
running a signal handler), in practice Git sets up signal handlers and
atexit handlers that call the same code to clean up after itself.

In case that the gentle method to terminate the process failed, we still
fall back to calling TerminateProcess(), but in that case we now also
make sure that processes spawned by the spawned process are terminated;
TerminateProcess() does not give the spawned process a chance to do so
itself.

Please note that this change only affects how Git for Windows tries to
terminate processes spawned by Git's own executables. Third-party
software that *calls* Git and wants to terminate it *still* need to make
sure to imitate this gentle method, otherwise this patch will not have
any effect.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 22:39:57 +09:00
Tuomas Ahola e6145d1241 docs: fix typos
Fix some typos and grammar errors in comments and documentation files.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 22:27:24 +09:00
Junio C Hamano f985a6ec65 Merge branch 'ps/odb-source-loose' into ps/odb-source-packed
* ps/odb-source-loose:
  odb/source-loose: drop pointer to the "files" source
  odb/source-loose: stub out remaining callbacks
  odb/source-loose: wire up `write_object_stream()` callback
  object-file: refactor writing objects to use loose source
  odb/source-loose: wire up `write_object()` callback
  loose: refactor object map to operate on `struct odb_source_loose`
  odb/source-loose: wire up `freshen_object()` callback
  odb/source-loose: drop `odb_source_loose_has_object()`
  odb/source-loose: wire up `count_objects()` callback
  odb/source-loose: wire up `find_abbrev_len()` callback
  odb/source-loose: wire up `for_each_object()` callback
  odb/source-loose: wire up `read_object_stream()` callback
  odb/source-loose: wire up `read_object_info()` callback
  odb/source-loose: wire up `close()` callback
  odb/source-loose: wire up `reprepare()` callback
  odb/source-loose: start converting to a proper `struct odb_source`
  odb/source-loose: store pointer to "files" instead of generic source
  odb/source-loose: move loose source into "odb/" subsystem
2026-06-05 22:26:06 +09:00
Patrick Steinhardt 42b9d3dc9d setup: construct object database in `apply_repository_format()`
With the preceding changes we now always construct the repository's
object database before applying the repository format. Remove this
duplication by constructing it in `apply_repository_format()` instead.

Note that we create the object database _after_ having set up the
repository's hash algorithm, but _before_ setting the compat hash
algorithm. This is intentional:

  - Constructing the object database may require knowledge of its
    intended object format.

  - Setting up the compatibility hash requires the object database to be
    initialized already, because we immediately read the loose object
    map.

The first point is sensible, the second maybe a little less so. Ideally,
it should be the responsibility of the object database itself to
initialize any data structures required for the compatibility hash. But
this would require further changes, so this is kept as-is for now.

Further note that this requires us to move handling of the environment
variables GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES into
the repository format, as well. This allows the caller more flexibility
around whether or not those environment variables are being honored, as
we want to respect them in "setup.c", but not in "repository.c".

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:39 +09:00
Patrick Steinhardt a84a9d4acd repository: stop reading loose object map twice on repo init
When initializing a repository via `repo_init()` we end up reading the
loose object map twice:

  - `apply_repository_format()` calls `repo_set_compat_hash_algo()`,
    which in turn calls `repo_read_loose_object_map()` if we have a
    compatibility hash configured.

  - `repo_init()` calls `repo_read_loose_object_map()` directly a second
    time.

Drop the second read of the loose object map in `repo_init()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:39 +09:00
Patrick Steinhardt d87de311ff setup: stop initializing object database without repository
The function `setup_git_directory_gently()` is responsible for
discovering and setting up a Git repository based on various environment
variables and the current working directory. The result is thus a fully
usable Git repository.

One oddity of this function is that we may set up the object database
even in the case where we don't have a repository, namely in the case
where the `GIT_DIR_EXPLICIT` environment variable is set but points to a
non-existent repository. If so, we call `setup_git_env_internal()` with
the value of the environment variable so that the repository's Git
directory is configured, even if it points to a non-existent directory.

Historically though, this function didn't only configure the repository,
but also initialized the object database. We retained this behaviour
from a preceding commit, even though it really doesn't make much sense
in the first place -- there is no repository, so we don't have an object
database either. There seemingly isn't much of a reason to construct the
object database, as we typically won't try to read objects when we don't
have an object database.

There's one exception though: git-index-pack(1) may run outside of a
repository, which can be used to perform consistency checks for a
packfile. The code path is _almost_ working: we already know to call
`parse_object_buffer()`, which can read objects without an object
database being available. And that works for all object types except for
commits, because `parse_commit_buffer()` calls `parse_commit_graph()`,
and that function doesn't handle the case where we don't have an object
database.

Fix this instance to check for the object database instead of checking
for the Git directory having been initialized. With this fixed, we can
now stop constructing an object database completely.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:38 +09:00
Patrick Steinhardt aae4ebc895 setup: stop creating the object database in `setup_git_env()`
In the preceding commit we have stopped creating the object database in
`repo_set_gitdir()`. But the logic is still somewhat confusing as we
still end up creating it conditionally in `setup_git_dir()`, which is
called multiple times.

Drop the conditional logic and instead create the object database in all
places where we have discovered and configured a repository.

This leads to even more duplication than we already had in the preceding
commit, but an alert reader may notice that we now (almost) always call
`odb_new()` directly before having called `apply_repository_format()`.
The only exception to this is `setup_git_directory_gently()`, where we
also call the function when _not_ applying the repository format. This
will be fixed in the next commit, and once that's done we can then unify
creation of the object database into `apply_repository_format()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:38 +09:00
Patrick Steinhardt 6a2fbab4c9 repository: stop initializing the object database in `repo_set_gitdir()`
The function `repo_set_gitdir()` obviously sets the Git directory for a
given repository. Less obviously though, the function also configures a
couple of auxiliary settings.

One such thing is that we create the object database in this function.
This logic only happens conditionally though, as `set_git_dir()` may be
called multiple times during repository setup, and we don't want to
create the object database multiple times. This is somewhat tangled and
hard to follow.

Remove the logic from `repo_set_gitdir()` and instead initialize the
object database outside of it. This leads to some duplication right now,
but that duplication will be removed in a subsequent step where we will
start initializing the object database as part of applying the repo's
format.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:38 +09:00
Patrick Steinhardt 3d884b0b56 setup: deduplicate logic to apply repository format
After having discovered the repository format we then apply it to the
repository so that it knows to use the proper repository extensions. The
logic to apply the format is duplicated across three callsites, which
makes it rather painfull to add new extensions.

Introduce a new function `apply_repository_format()` that takes a repo
and applies a given format to it and adapt all callsites to use it.
This function is also the new caller of `verify_repository_format()` so
that we can ensure that we never apply an invalid repository format.
The verification we have in `read_and_verify_repository_format()` is
thus redundant now and dropped.

Rename `read_and_verify_repository_format()` accordingly. While at it,
also rename `check_repository_format()` to clarify that it doesn't only
_check_ the format, but that it also applies it.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:38 +09:00
Patrick Steinhardt 452ad8db6d setup: drop `setup_git_env()`
The `setup_git_env()` function is a trivial wrapper around
`setup_git_env_internal()` and has a single call site only. Drop the
function.

While at it, drop stale documentation in "environment.h" that points to
this function, even though it hasn't been exposed to callers outside of
"setup.c" since 43ad1047a9 (setup: stop using `the_repository` in
`setup_git_env()`, 2026-03-27) anymore.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:38 +09:00
Patrick Steinhardt 027e3b3d38 t0001: plug test gaps for git-init(1) with GIT_OBJECT_DIRECTORY
In subsequent commits we'll rework how we set up the repository. This is
a somewhat intricate and thus fragile sequence; there's many things that
can go subtly wrong, and there are lots of interesting interactions that
one can discover.

One such discovered edge case was the interaction between git-init(1)
and the "GIT_OBJECT_DIRECTORY" environment variable. When set, the
behaviour is that the object directory should be created at the path
that the variable points to. This behaviour is documented as such in
its man page:

  If the object storage directory is specified via the
  GIT_OBJECT_DIRECTORY environment variable then the sha1 directories
  are created underneath; otherwise, the default $GIT_DIR/objects
  directory is used.

Curiously enough though we don't seem to have any tests that exercise
this directly, and thus a subsequent commit inadvertently would have
broken this expectation.

Plug this test gap.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:38 +09:00
Patrick Steinhardt 389c83025d t: let prove fail when parsing invalid TAP output
To make the result of our tests accessible we use the TAP protocol. This
protocol is parsed by either prove or by Meson. Unfortunately, these two
tools differ when it comes to their strictness when parsing the
protocol:

  - Prove by default happily accepts lines not specified by the
    protocol.

  - Meson will also accept such lines, but prints a big and ugly warning
    message.

We have fixed our test suite in the past to not print invalid TAP lines
anymore via b1dc2e796e (Merge branch 'ps/meson-tap-parse', 2025-06-17).
But as none of our tools perform a strict check it's still possible for
broken tests to sneak back in, like for example in 362f69547f (Merge
branch 'ps/t1006-tap-fix', 2025-07-16). This doesn't hurt at all when
using prove, but it's quite annoying when using Meson due to the
generated warnings.

Unfortunately, there doesn't seem to be a portable way to make all tools
complain about violations of the TAP format. The TAP 14 specification
has added pragmas to the protocol that would allow us to say `pragma
+strict`, and the effect of that would be to treat invalid TAP lines as
a test failure. But the release of TAP 14 is still rather recent, and
Test-Harness for example only gained support for it in version 3.48,
which was released in 2023.

In fact though, this pragma was already introduced as an inofficial
extension of the TAP protocol with Test-Harness 3.10, released in 2008.
So while not all tools understand the pragma, at least prove does for a
long time.

Unconditionally enable the pragma when using prove so that we'll detect
tests that emit broken TAP output right away. This would have detected
the issues fixed in preceding commits:

    $ prove t7527-builtin-fsmonitor.sh
    t7527-builtin-fsmonitor.sh .. All 69 subtests passed
            (less 6 skipped subtests: 63 okay)

    Test Summary Report
    -------------------
    t7527-builtin-fsmonitor.sh (Wstat: 0 Tests: 69 Failed: 0)
      Parse errors: Unknown TAP token: "Initialized empty Git repository in /tmp/git/test_fsmonitor_smoke/.git/"

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt c2d2d173ae t/lib-git-p4: silence output when killing p4d and its watchdog
When stopping the p4d watchdog process via "kill -9", the shell may
print a job-control notification like:

  ./test-lib.sh: line 1269: 57960 Killed: 9               while true; do
      if test $nr_tries_left -eq 0; then
          kill -9 $p4d_pid; exit 1;
      fi; sleep 1; nr_tries_left=$(($nr_tries_left - 1));
  done 2> /dev/null 4>&2  (wd: ~)

This message is printed asynchronously by the shell when it reaps the
process. While harmless right now, this will cause breakage once we
enable strict parsing of the TAP protocol in a subsequent commit.

Fix this by using `wait` so that we can synchronously reap the watchdog
process and swallow the diagnostic.

While at it, deduplicate the logic we have in `stop_p4d_and_watchdog ()`
and `stop_and_cleanup_p4d ()`.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt d11968661e t/test-lib: silence EBUSY errors on Windows during test cleanup
When tests have finished we clean up the trash directory via `rm -rf`.
On Windows this can fail with EBUSY in cases where a process still holds
some of the files open, for example when we have spawned a daemonized
process that wasn't properly terminated. We thus retry several times,
but every failure will result in error messages being printed, and that
in turn breaks the TAP output format.

One such case where this is causing issues is in t921x, which contains
tests related to Scalar. Some tests spawn the fsmonitor daemon, and we
never properly terminate it.

The obvious fix would be to ensure that we never leak any processes, but
that gets ugly fast. Instead, let's work around the issue by silencing
error messages printed by the `rm -rf` calls. We already know to print
an error when the retry loop fails, so we don't loose much.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt b1688db759 t7810: turn MB_REGEX check into a lazy prereq
In t7810 we verify whether the system has proper multibyte locale
support by executing `test-tool regex` with a unicode character. When
this check fails though we'll output an error that breaks the TAP
format.

Fix this issue by turning the logic into a lazy prerequisite.

Reported-by: Jeff King <peff@peff.net>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt bf3ed750cb t7527: fix broken TAP output
Before running the tests in t7527 we first verify whether the fsmonitor
even works, which seems to depend on the actual filesystem that is in
use. The verification executes outside of any prerequisite or test body,
so its stdout/stderr is not being redirected.

The consequence of this is that any command that prints to stdout/stderr
may break the TAP specification by printing invalid lines. And in fact
we already do that, as git-init(1) prints the path to the created Git
repository by default.

Fix this issue by moving the logic into a lazy prerequisite.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt 43a6a005c8 ci: unify Linux images across GitLab and GitHub
The image for the "linux-breaking-changes" job has drifted apart across
GitHub and GitLab. Adapt it to use "ubuntu:rolling" on both systems.

With this change there's only one difference remaining: GitHub uses
"ubuntu:focal" for the "linux32" job while GitLab uses "ubuntu:20.04".
These are different names for the same image, so there is no actual
difference here. Adjust GitHub to use the "20.04" tag -- this matches
all the other jobs which use version numbers, and you don't have to
learn Ubuntu's release names by heart.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt f0ba41bae8 gitlab-ci: add missing Linux jobs
The GitLab CI definitions are missing jobs for AlmaLinux and Debian,
both of which exist in GitHub Workflows. Plug this gap.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:49:00 +09:00
Patrick Steinhardt 9708b3dc95 gitlab-ci: rearrange Linux jobs to match GitHub's order
Rearrange the order of Linux jobs that we have defined in GitLab CI so
that it matches the order on GitHub's side. This makes it easier to
compare whether the list of jobs actually matches on both sides.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 21:48:59 +09:00
Harald Nordgren 03c29e2e98 config: improve diagnostic for "set" with missing value
"git config set pull.rebase=false" currently fails with "wrong
number of arguments", and the implicit form "git config
pull.rebase=false" fails with "invalid key". Neither points at
the real problem: the value is missing.

Report that directly, and when the argument has the shape
"<valid-key>=<value>", also suggest the split form:

    $ git config set pull.rebase=false
    error: missing value to set to the variable 'pull.rebase=false'
    hint: did you mean "git config set pull.rebase false"?

When the prefix before "=" is not a valid key, drop the hint:

    $ git config set foo=bar
    error: missing value to set to a variable with an invalid name 'foo=bar'

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:39:54 +09:00
Harald Nordgren 9b03e2790a config: add git_config_key_is_valid() for quiet validation
Move the body of git_config_parse_key() into a static helper
do_parse_config_key() that takes a "quiet" flag and treats
store_key as optional.  git_config_parse_key() becomes a thin
wrapper.

Add git_config_key_is_valid() for callers that only need to
know whether a key is well-formed.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:39:54 +09:00
Mirko Faina bb4ce23284 revision.c: implement --max-count-oldest
"--max-count" is a commit limiting option and sets a maximum amount
of commits to be shown. If a user wants to see only the first N
commits of the history (the oldest commits) they'd have to do
something like

    git log $(git rev-list HEAD | tail -n N | head -n 1)

This is not very user-friendly.

Teach get_revision() the --max-count-oldest option.

Signed-off-by: Mirko Faina <mroik@delayed.space>
[jc: fixed up t4202 <xmqq7boy4o05.fsf@gitster.g>]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:37:52 +09:00
Olamide Caleb Bello 8407abf02a environment: move "warn_on_object_refname_ambiguity" into `struct repo_config_values`
The `core.warnAmbiguousRefs` configuration was previously stored in a
global `int` variable, making it shared across repository instances
and risking cross‑repository state leakage.

Store it instead in `repo_config_values`, where eagerly‑parsed
repository configuration lives. This option is parsed eagerly because
ambiguity warnings influence how users interpret object references in
many commands; a lazy parse could cause these warnings to behave
inconsistently or to appear for the wrong repository, confusing users
and hindering libification. This preserves the existing behavior while
tying the value to the repository from which it was read, avoiding
cross‑repository state leakage and continuing the effort to reduce
reliance on global configuration state.

Update all references to use `repo_config_values()`.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:36:48 +09:00
Olamide Caleb Bello c8a32140a7 environment: move "sparse_expect_files_outside_of_patterns" into `struct repo_config_values`
The `core.sparseCheckoutExpectFilesOutsideOfPatterns` configuration was
previously stored in a global `int` variable, making it shared across
repository instances and risking cross‑repository state leakage.

Store it instead in `repo_config_values`, where eagerly‑parsed
repository configuration lives. This option is parsed eagerly because
it controls how sparse‑checkout paths are interpreted – a fundamental
behavior that many commands rely on; a lazy parse could cause
inconsistent sparse‑checkout handling and complicate libification.
This preserves the existing behavior while tying the value to the
repository from which it was read, avoiding cross‑repository state
leakage and continuing the effort to reduce reliance on global
configuration state.

Update all references to use `repo_config_values()`.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:36:48 +09:00
Olamide Caleb Bello dfa01cee1c environment: move "core_sparse_checkout_cone" into `struct repo_config_values`
The `core.sparseCheckoutCone` configuration was previously stored in an
uninitialized global `int` variable, risking cross‑repository state
leakage.

Move it into `repo_config_values`, where eagerly‑parsed repository
configuration lives. `core.sparseCheckoutCone` is parsed eagerly
because it determines the fundamental sparse‑checkout mode and is
consulted very early during repository setup; a lazy parse could
leave the sparse‑checkout state undefined and complicate
libification. This preserves the existing behavior while tying the
value to the repository from which it was read, avoiding cross‑
repository state leakage and continuing the effort to reduce reliance
on global configuration state.

Update all references to use `repo_config_values()`.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:36:48 +09:00
Olamide Caleb Bello 6f00fc0499 environment: move "precomposed_unicode" into `struct repo_config_values`
The `core.precomposeunicode` configuration is currently stored in the
global variable `precomposed_unicode`, which makes it shared across
repository instances within a single process.

Store it instead in `repo_config_values`, where eagerly‑parsed
repository configuration lives. `core.precomposeunicode` is parsed
eagerly because it controls Unicode path normalization on macOS,
a fundamental filesystem‑level behavior that many operations depend
on; a lazy parse could lead to inconsistent results and hamper
libification. This preserves the existing behavior while tying the
value to the repository from which it was read, avoiding cross‑
repository state leakage and continuing the effort to reduce reliance
on global configuration state.

Update all references to use `repo_config_values()`.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:36:48 +09:00
Olamide Caleb Bello 8cd7402acc environment: move "pack_compression_level" into `struct repo_config_values`
The `pack_compression_level` configuration is currently stored in the
global variable `pack_compression_level`, which makes it shared across
repository instances within a single process.

Store it instead in `repo_config_values`, where eagerly‑parsed
repository configuration lives. `pack_compression_level` is parsed
eagerly because it influences packfile compression, a core operation
where a lazy parse could cause inconsistent behavior and hamper
libification. This preserves the existing eager‑parsing behavior while
tying the value to the repository from which it was read, avoiding
cross‑repository state leakage and continuing the effort to reduce
reliance on global configuration state.

Update all references to use `repo_config_values()`.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:36:48 +09:00
Olamide Caleb Bello e0f86540ab environment: move `zlib_compression_level` into `struct repo_config_values`
The `zlib_compression_level` configuration is currently stored in the
global variable `zlib_compression_level`, which makes it shared across
repository instances within a single process.

Store it instead in `repo_config_values`, where eagerly‑parsed
repository configuration lives. `zlib_compression_level` is parsed
eagerly because it determines compression behaviour for objects and
packs – core operations where a lazy parse could lead to unpredictable
results and hinder libification. This preserves the existing
eager‑parsing behavior while tying the value to the repository it
was read from, avoiding cross‑repository state leakage and continuing
the effort to reduce reliance on global configuration state.

Update all references to use `repo_config_values()`.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:36:48 +09:00
Olamide Caleb Bello 88505ed637 environment: move "check_stat" into `struct repo_config_values`
The `core.checkstat` configuration is currently stored in the global
variable `check_stat`, which makes it shared across repository
instances within a single process.

Store it instead in `repo_config_values`, where eagerly‑parsed
repository configuration lives. `core.checkstat` is parsed eagerly
because it controls how `match_stat_data()` and related functions
decide file freshness; a lazy parse could lead to unexpected
behavior or complicate libification. This preserves the existing
eager‑parsing behavior while tying the value to the repository it
was read from, avoiding cross‑repository state leakage, and
continuing the effort to reduce reliance on global configuration
state.

Update all references to use `repo_config_values()`.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:36:48 +09:00
Olamide Caleb Bello 18684282df environment: move "trust_ctime" into `struct repo_config_values`
The `core.trustctime` configuration is currently stored in the global
variable `trust_ctime`, which makes it shared across repository
instances in a single process.

Store it instead in `repo_config_values`, where eagerly‑parsed
repository configuration lives. `core.trustctime` is parsed eagerly
because it is used in low‑level stat‑matching functions
(`match_stat_data()`), where a lazy parse could cause unexpected
fatal errors, result in a performance regression and complicate
libification efforts. This preserves that behavior while tying the
value to the repository from which it was read, avoiding cross‑repository
state leakage and continuing the effort to reduce reliance on global
configuration state.

Update all references to use repo_config_values().

Mentored-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Olamide Caleb Bello <belkid98@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-03 08:36:48 +09:00
Mark Levedahl e61190e2fa git-gui: add gui and pick as explicit subcommands
git-gui accepts subcommands blame | browser | citool, and assumes the
subcommand is 'gui' if none is actually given, But, git-gui also has a
repository picker (choose_repository::pick) that can create a new
repository + worktree, or choose an existing one, switch to that, and
the run the gui. The user has no direct control over invoking the
picker, instead the picker is triggered by failure in the repository /
worktree discovery process: this includes being started in a directory
not controlled by git, which is probably the intended use case.

The picker can appear when the user has no intention of creating a new
worktree, and the user cannot use the picker to create a new worktree
inside another.

So, add two explicit subcommands:
    gui  - Run the gui if repository/worktree discovery succeeds, or die
           with an error message, but never run the picker.
    pick - First run the picker, regardless, then start the gui in
           the chosen worktree.

Nothing in this changes the prior behavior, the alternates above must be
explicitly selected to see any change.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:14 +02:00
Mark Levedahl 3fbef193c7 git-gui: check browser/blame arguments carefully
git gui offers two related commands, browser and blame, that provide
graphical interfaces driven by git ls-tree and git blame. As such, the
arguments to git-gui need to satisfy those two git commands. But,
git-gui does not assure this leading to confusing or incorrect results.
For instance 'git browser <non-existent path>' shows a blank browser
window rather than error message.

Also, commit 3e45ee1ef2 ("git-gui: Smarter command line parsing for
browser, blame", 2007-05-08) implemented code to allow giving path
before rev on the command line, and unconditionally uses the worktree to
disambiguate. As a result, the following command run in a current
git-gui checkout of the master branch shows the master branch version of
blame.tcl, when none should be shown as that file does not exist in
gitgui-0.6.0.

  git gui blame lib/blame.tcl gitgui-0.6.0

This 'file before rev' feature in git-gui mirrors ideas considered when
git's user interface was very young, but no such feature is documented
for any git command.  Rather than try to fix an idea git itself
rejected, let's just remove this broken and hopefully unused feature.

git-gui browser|blame both accept 'rev' and 'path' as command line
arguments.  rev defaults to 'HEAD' if not given, while path must be
given. path names a directory tree to ls-tree or a file to blame. path
must exist in rev for ls-tree and for blame.  In addition git blame will
include uncommitted changes from the worktree file at 'path' if rev is
not given (thus defaulting to HEAD), but still requires that the file
exists in HEAD.

So, let's clean up the parser to check that the arguments are usable.
- give a full synopsis, including '--' that may be used to separate rev and
  path. (as path is the required final arg, -- gives no extra info)
- explicitly check the number of arguments
- use rev-parse to assure a user supplied rev is valid
- use ls-tree to assure that path exists in rev
- for blame only, with no rev given and a worktree existing, also assure
  that path points to a file in the worktree

With these changes, error messages are thrown by the parser if the path
or rev are not known: no blank or erroneous displays are created. Also,
this avoids accessing the worktree except in the specific use case
supported by blame / git-blame, meaning browser|blame now also work
without a worktree.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Mark Levedahl 7c7c7ba4ce git-gui: allow specifying path '.' to the browser
Invoking "git-gui browser rev ." should show the file browser for the
commitish rev, starting at the current directory. When the current
directory is the working tree root, this errors out in normalize_relpath
because the '.' is removed, yielding an empty list as argument to [file
join ...]. git ls-tree (underlying the browser) accepts '.', so use that
as the value when in the root.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Mark Levedahl 4f5114bfac git-gui: try harder to find worktree from gitdir
git-gui, since 87cd09f43e ("git-gui: work from the .git dir",
2010-01-23), has had the intent to allow starting from inside a
repository, then switching to the parent directory if that is a valid
worktree.

This certainly hasn't worked since 2d92ab32fd ("rev-parse: make
--show-toplevel without a worktree an error", 2019-11-19) in git, but
breaking this git-gui feature was unintentional.

There are (at least) 3 cases where the gitdir can tell us where the
worktree is, and we would like all to work:

- core.worktree is set, and points to a valid worktree. This is already
  handled  by git rev-parse --show-toplevel, even when not in the worktree.
  There is nothing more to do in this case.

- the gitdir is embedded in a worktree as subdirectory .git. The parent
  is (or at least should be) a valid worktree. This worked long ago.

- the gitdir is a worktree specific directory (under
  <mainrepo>/worktrees/worktree_name), within which there is a file
  "gitdir" pointing to .git in the worktree. git gui never learned to
  handle this case.

Let's handle the latter two cases. Always check that the discovered
worktree is valid and points to the already discovered gitdir according
to git rev-parse. This avoids issues that may arise because we are
discovering from the gitdir up, rather than the worktree down, and file
system non-posix behavior or misconfiguration of git might cause
confusion.  For instance, a manually moved worktree might not be where
the gitdir points, or the gitdir might be configured with
core.bare=true.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Mark Levedahl d0e9b4959b git-gui: simplify [is_bare] to report if a worktree is known
git-gui includes proc is_bare, used in several places to make decisions
on whether a worktree exists, but also in discovery to tell if a
worktree can be supported.

But, is_bare is out of date with regard to multiple worktrees, safe
repository guards, and possibly other relevant features known to git
rev-parse. Also, is_bare caches its result on the first call, so is not
useful if a later step in the discovery process finds a worktree.

So, simplify is_bare to report whether git-gui has a worktree or is
working only from a repository.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Mark Levedahl 80b7207e68 git-gui: use git rev-parse for worktree discovery
git gui uses a combination of tcl code and git invocations to determine
the worktree and the location with respect to the worktree root
(_prefix). But, git rev-parse provides all of this information directly,
and assures full error and configuration checking are done by git
itself. The entirety of discovery in normal configurations involves

	git rev-parse --show-toplevel (gets worktree root)
	git rev-parse --show-prefix (shows location wrt the root)

An error thrown on either of these lines means the worktree discovered
by git is unusable, or git did not discover a worktree because the
current directory is inside the repository. If the user has defined
GIT_DIR or GIT_WORK_TREE, this is a user configuration error and git-gui
should stop.

Otherwise, the blame or browser subcommands can be used without a
worktree.

A separate error might occur when changing to the root of the discovered
worktree. The cause would be file system related and completely outside
of git's control, so trap that independently.

Discovery of the repository and the worktree must be guarded to trap
errors: the intent is that any configuration problems are caught during
discovery, and later processing need not include error trapping and
recovery. So, move all worktree discovery code to be immediately after
repository discovery.

This does move configuration loading to occur after worktree discovery
rather than before. None of the code executed in worktree discovery has
any option controlled by a git-gui configuration variable, so no impact
is expected. git itself will always read the repository configuration,
including worktree specific configuration data if that exists, so this
is unaffected by when git-gui loads its own config data. Also, we cannot
be sure the worktree dependent configuration can be loaded before
full discovery is complete.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Mark Levedahl edcf9188be git-gui: use rev-parse exclusively to find a repository
git-gui attempts to use env(GIT_DIR) directly as the git repository,
accepting GIT_DIR if it is a directory. Only if that fails is git
rev-parse used to discover the repository.  But, this avoids all of
git-core's validity checking on a repository, thus possibly deferring an
error to a later step, possibly unexpected. Repository validation should
be part of initial setup so that later processing does not need error
trapping for configuration errors.

Let's just invoke rev-parse so all error checking is done.

While here, let's cleanup the error handling.

Stop if an error occurs and the user set GIT_DIR or GIT_WORK_TREE.
Use of either or both of those variables is supported by git, but their
use also means the user has taken responsibility that they are correct,
so a failure is something the user must address.

Otherwise on error, continue the existing behavior and show the
repository picker. But, let's move the possible invocation of
repository_chooser::pick to a separate code block. This permits adding
separate conditions on using pick independent of repository discovery, and
will be exploited later in the series.  Note that the picker always
returns with the current directory in the root of a worktree with the
git repository is in the .git subdirectory.  The variable "picked" is
used by git-gui to automatically execute the "Explore Working Copy" menu
item after the repository picker is run.  This is controlled by config
variable gui.autoexplore, and happens after all discovery is complete.

Remove a later check on whether _gitdir is a directory: that code
cannot be reached without rev-parse already validating the repository.

_prefix is set as part of worktree discovery, but must be {} if not
running with a worktree. Initialze this as {} along with other global
variables, this is the correct value is no worktree is found.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Mark Levedahl 9902c4cc9c git-gui: use --absolute-git-dir
git-gui uses git rev-parse --git-dir to get the pathname of the
discovered git repository. The returned value can be relative, and is
'.' if the current directory is the top of the repository directory
itself.  git-gui has code to change '.' to [pwd] in this case so that
subsequent logic runs.

But, git rev-parse supports --absolute-git-dir from fac60b8925
("rev-parse: add option for absolute or relative path formatting",
2020-12-13), and included in git 2.31. git-gui requires git >= 2.36, so
this more useful form is always available. Use --absolute-git-dir to
always get an absolute path, avoiding the need for other checks, and
delete the now unneeded code to fix a relative _gitdir.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Mark Levedahl 587a4ac448 git-gui: do not change global vars in choose_repository::pick
The repository picker (choose_repository::pick, AKA pick) on success
always returns with the current directory at the root of the selected
worktree, with the global variable _gitdir holding the name of the
git repository, possibly as a relative path, and _prefix {}. The
worktree root (_gitworktree) is not filled out, and if the selection was
from the "recent" list, no validation has occurred beyond testing that
the worktree root exists. So, repository and worktree validation are
still needed to be sure the new repo + worktree is usable.

pick only supports worktrees with a .git entry in the worktree root, so
git repository and worktree discovery will work starting in the current
directory on return. In cases of error, or user abort, pick exits the
process rather than returning.

So, let's change pick to not alter any global values, with success
indicated by the process returning to the caller. In this case, the
current directory is the worktree root, with a .git entry. The caller
then proceeds with normal discovery to find and validate both repository
and worktree.

With this, pick now returns 1 in the success case, but additional work
would be necessary to return from conditions where 0 should be returned.
Checking this return value would be superfluous.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Mark Levedahl d4800b7a6e git-gui: guard set/unset of GIT_DIR and GIT_WORK_TREE
git-gui unconditionally exports _gitdir as GIT_DIR, and _gitworktree as
GIT_WORK_TREE, to the environment, and unconditionally
unsets these environment variables before invoking gitk or git-gui when
a submodule is involved. This export happens even if _gitworktree is
empty, which happens when running from a bare repository. However,
exporting GIT_WORK_TREE as empty is never valid, and causes errors in
git.

GIT_DIR must be exported if the repository is not discoverable from the
worktree (or current directory if there is no worktree). The user might
have configured this.

If there is a worktree, git-gui makes this the current directory.
However, if the repository sets core.worktree, this value can only be
overridden by GIT_WORK_TREE so the latter must be exported.

As we cannot eliminate conditions where either variable is needed, let's
implement a pair of functions to set / unset these variables without
error, and without ever exporting an empty GIT_WORK_TREE.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2026-06-02 19:13:13 +02:00
Junio C Hamano bc58f1c734 SubmittingPatches: describe cover letter
We talk about how a commit log message should look like, but do not
give advice on writing the cover letter to sell a series to the
widest possible audience.

Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-02 23:43:49 +09:00
Junio C Hamano 66ebad2775 SubmittingPatches: separate typofixes section
The existing text said something about tests (with [[tests]] to make
it easier to refer to it from elsewhere) and then flowed into a
different topic of typofixes, but it was unclear where the latter
started.  Add a similar [[typofixes]] marker to the document.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-02 23:43:48 +09:00
Luna Schwalbe 4018dc29ee doc: document and test `@` prefix for raw timestamps
The Git internal date format `<unix-timestamp> <time-zone-offset>`
fails to parse when the timestamp is less than 100,000,000 (fewer than
9 digits). This happens to avoid potential ambiguity with other date
formats such as `YYYYMMDD`, especially when used with approxidate.

To force the parser to interpret the value as a raw timestamp, it must
be prefixed with `@` (e.g., `@0 +0000`). This behavior was introduced
in 2c733fb24c (parse_date(): '@' prefix
forces git-timestamp, 2012-02-02) but was never documented.

Document the `@` prefix in `Documentation/date-formats.adoc` to make
this behavior explicit. Also add test cases to `t/t0006-date.sh` to
verify and demonstrate the difference between prefixed and unprefixed
small timestamps (e.g., `@2000` vs `2000`).

Signed-off-by: Luna Schwalbe <dev@luna.gl>
Co-authored-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-02 18:13:12 +09:00
Harald Nordgren 5cd4d0d850 config.mak.uname: avoid macOS linker warning on Xcode 16.3+
Building on macOS with Xcode 16.3 or newer emits:

    ld: warning: reducing alignment of section __DATA,__common
    from 0x8000 to 0x4000 because it exceeds segment maximum
    alignment

Pass -fno-common when "ld -v" reports ld-1167 or newer, so tentative
definitions of large arrays go into BSS instead of __DATA,__common.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-02 17:30:01 +09:00
Junio C Hamano 9ac3f193c0 The 11th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-02 16:15:29 +09:00
Junio C Hamano 95e5fbd0ef Merge branch 'kh/doc-hook'
Doc updates.

* kh/doc-hook:
  doc: hook: don’t self-link via config include
  doc: config: include existing git-hook(1) section
  doc: hook: consistently capitalize Git
  doc: hook: remove stray backtick
2026-06-02 16:15:29 +09:00