Commit Graph

1025 Commits

Author SHA1 Message Date
Junio C Hamano
84803ed2ca Merge branch 'jt/config-lock-timeout' into seen
Configuration file locking now retries for a short period, avoiding
failures when multiple processes attempt to update the configuration
simultaneously.

* jt/config-lock-timeout:
  config: retry acquiring config.lock, configurable via core.configLockTimeout
2026-06-17 05:40:10 -07:00
Junio C Hamano
86a98bff79 Merge branch 'kh/doc-replay-config' into jch
Doc update for "git replay" to actually refer to its configuration
variables.

* kh/doc-replay-config:
  doc: replay: move “default” to the right-hand side
  doc: replay: use a nested description list
  doc: replay: improve config description
  doc: link to config for git-replay(1)
2026-06-17 05:40:02 -07:00
Junio C Hamano
2225c278b0 Merge branch 'mh/fetch-follow-remote-head-config' into jch
The `fetch.followRemoteHEAD` configuration variable has been added to
provide a default for the per-remote `remote.<name>.followRemoteHEAD`
setting.

* mh/fetch-follow-remote-head-config:
  fetch: fixup a misaligned comment
  fetch: add configuration variable fetch.followRemoteHEAD
  fetch: refactor do_fetch handling of followRemoteHEAD
  fetch: rename function report_set_head
  t5510: cleanup remote in followRemoteHEAD dangling ref test
  doc: explain fetchRemoteHEADWarn advice
  fetch: fixup set_head advice for warn-if-not-branch
2026-06-17 05:40:02 -07:00
Junio C Hamano
fa2958e8eb Merge branch 'ta/doc-config-adoc-fixes' into jch
Various AsciiDoc markup fixes in 'git config' documentation and
related files to ensure lists and formatting are rendered correctly.

* ta/doc-config-adoc-fixes:
  doc: git-config: escape erroneous highlight markup
  doc: config/sideband: fix description list delimiter
  doc: config: terminate runaway lists
2026-06-17 05:40:00 -07:00
Junio C Hamano
932e625742 Merge branch 'cc/promisor-auto-config-url-more' into jch
The handling of promisor-remote protocol capability has been
loosened to allow the other side to add to the list of promisor
remotes via the promisor.acceptFromServerURL configuration
variable.

* cc/promisor-auto-config-url-more:
  doc: promisor: improve acceptFromServer entry
  promisor-remote: auto-configure unknown remotes
  promisor-remote: trust known remotes matching acceptFromServerUrl
  promisor-remote: introduce promisor.acceptFromServerUrl
  promisor-remote: add 'local_name' to 'struct promisor_info'
  urlmatch: add url_normalize_pattern() helper
  urlmatch: change 'allow_globs' arg to bool
  t5710: simplify 'mkdir X' followed by 'git -C X init'
2026-06-17 05:39:59 -07:00
Matt Hunter
c3bfc5ace6 fetch: add configuration variable fetch.followRemoteHEAD
'fetch.followRemoteHEAD' is added as a generic setting used by all
remotes for which 'remote.<name>.followRemoteHEAD' is undefined.  If
both variables are undefined, a builtin default of "create" is in
effect, matching the previous behavior.

As mentioned in the previous patch, 'fetch.followRemoteHEAD' supports
all of the values that its 'remote' counterpart does _except_
warn-if-not-$branch, due to its tighter coupling to individual remote
repositories.

Documentation and advice messages for both of the followRemoteHEAD
variables are reworded to better capture the relationship between the
two.

The added tests assert feature parity between the two followRemoteHEAD
variables, as well as the fact that 'remote.<name>.followRemoteHEAD'
always supersedes this new configurable default.

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Matt Hunter <m@lfurio.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-16 15:42:32 -07:00
Matt Hunter
b1f7a90aee doc: explain fetchRemoteHEADWarn advice
When the user sets 'remote.<name>.followRemoteHEAD' to
'warn[-if-not-$branch]', git-fetch will report when a fetched HEAD
disagrees with the locally-configured remote's HEAD.  This additional
advice instructs the user how to deal with these warnings, but was
previously undocumented in git-config.

Signed-off-by: Matt Hunter <m@lfurio.us>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-16 15:42:31 -07:00
Junio C Hamano
4c2c7677e4 Merge branch 'ta/typofixes'
Typofixes

* ta/typofixes:
  docs: fix typos
2026-06-16 09:01:03 -07:00
Tuomas Ahola
042221cccb doc: config/sideband: fix description list delimiter
Signed-off-by: Tuomas Ahola <taahol@utu.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-11 12:08:17 -07:00
Tuomas Ahola
3eb61fda62 doc: config: terminate runaway lists
There are many places in git-config(1) where paragraphs that should
logically come after a list are instead appended to the last item of
the list.  This is a well-documented quirk of AsciiDoc, and can be
mitigated by enclosing the list in an open block:

	--
	* first item
	* last item
	--
	+
	New paragraph after the list.

Fix the issue accordingly.

Signed-off-by: Tuomas Ahola <taahol@utu.fi>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-11 12:08:17 -07:00
Junio C Hamano
4d96a1280b Merge branch 'ib/doc-push-default-simple'
The documentation for `push.default = simple` has been clarified to
better explain its behavior, making it clear that it pushes the
current branch to a same-named branch on the remote, and detailing
the upstream requirements for centralized workflows.

* ib/doc-push-default-simple:
  doc: clarify push.default=simple behavior
2026-06-09 10:04:51 +09:00
Junio C Hamano
212d25596d Merge branch 'ja/doc-synopsis-style-again'
A batch of documentation pages has been updated to use the modern
synopsis style.

* ja/doc-synopsis-style-again:
  doc: convert git-imap-send synopsis and options to new style
  doc: convert git-apply synopsis and options to new style
  doc: convert git-am synopsis and options to new style
  doc: convert git-grep synopsis and options to new style
  doc: git bisect: clarify the usage of the synopsis vs actual command
  doc: convert git-bisect to synopsis style
2026-06-07 23:58:25 +09:00
Kristoffer Haugsbakk
60575c76a5 doc: replay: move “default” to the right-hand side
This is now a description list (see previous commit) and parentheticals
like this do not go on the left-hand side. Moving it to the other side
makes it stand out just as much and is also more consistent with the
rest of the documentation.

Let’s also do the same for the `replay.refAction` description list.
That makes the two desc. lists identical in the first sentence. Let’s
add a comment about that for future editors.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 23:16:26 +09:00
Kristoffer Haugsbakk
2f169b5c22 doc: replay: improve config description
First of all, this unordered list for `replay.refAction` introduces
a term with a colon. This is exactly what a description list is,
structurally. Let’s be stylistically consistent and use the desc.
list markup construct. Let’s also drop the harmless but unneeded
indentation.

We can reuse the `::` delimiter since we use an open block.
But for consistency use the typical nested description list
delimiter, namely `;;`.

Second, let’s replace the inline-verbatim `git replay` with a link
to git-replay(1), since we are naming the command. But make that
conditional so that we avoid a self-link inside git-replay(1).[1]

† 1: See e.g. e7b3a768 (doc: git-init: rework config item
     init.templateDir, 2024-03-10) for another example of
     avoiding self-linking

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-06-05 23:16:26 +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
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
Junio C Hamano
4d11b9c218 Merge branch 'pt/fsmonitor-linux'
The fsmonitor daemon has been implemented for Linux.

* pt/fsmonitor-linux:
  fsmonitor: convert shown khash to strset in do_handle_client
  fsmonitor: add tests for Linux
  fsmonitor: add timeout to daemon stop command
  fsmonitor: close inherited file descriptors and detach in daemon
  run-command: add close_fd_above_stderr option
  fsmonitor: implement filesystem change listener for Linux
  fsmonitor: rename fsm-settings-darwin.c to fsm-settings-unix.c
  fsmonitor: rename fsm-ipc-darwin.c to fsm-ipc-unix.c
  fsmonitor: use pthread_cond_timedwait for cookie wait
  compat/win32: add pthread_cond_timedwait
  fsmonitor: fix hashmap memory leak in fsmonitor_run_daemon
  fsmonitor: fix khash memory leak in do_handle_client
  t9210, t9211: disable GIT_TEST_SPLIT_INDEX for scalar clone tests
2026-05-31 10:00:38 +09:00
Christian Couder
8f32e6f343 doc: promisor: improve acceptFromServer entry
The entry for the `promisor.acceptFromServer` in
"Documentation/config/promisor.adoc" has a number of issues:

- it's not clear if new remotes and URLs can be created,
- it looks like a big block of text,
- it's not easy to see all the options,
- it's not easy to see which option is the default one,
- for "knownName", it says "advertised by the client" instead of
  "advertised by the server",
- it doesn't refer to the new related `acceptFromServerUrl`
  option.

Let's address all these issues by rewording large parts of it
and using bullet points for the different options.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-28 05:20:15 +09:00
Christian Couder
7a56394fc6 promisor-remote: auto-configure unknown remotes
Previous commits have introduced the `promisor.acceptFromServerUrl`
config variable to allowlist some URLs advertised by a server through
the "promisor-remote" protocol capability.

However the new `promisor.acceptFromServerUrl` mechanism, like the old
`promisor.acceptFromServer` mechanism, still requires a remote to
already exist in the client's local configuration before it can be
accepted. This places a significant manual burden on users to
pre-configure these remotes, and creates friction for administrators
who have to troubleshoot or manually provision these setups for their
teams.

To eliminate this burden, let's automatically create a new `[remote]`
section in the client's config when a server advertises an unknown
remote whose URL matches a `promisor.acceptFromServerUrl` glob pattern.

Concretely, let's add four helpers:

 - sanitize_remote_name(): turn an arbitrary URL-derived string into a
   valid remote name by replacing non-alphanumeric characters,
   collapsing runs of '-', and prepending "promisor-auto-".

 - promisor_remote_name_from_url(): normalize the URL and extract
   host+port+path to build a human-readable base name, then pass it
   through sanitize_remote_name().

 - configure_auto_promisor_remote(): write the remote.*.url,
   remote.*.promisor and remote.*.advertisedAs keys to the repo
   config.

 - handle_matching_allowed_url(): pick the final name (user-supplied
   alias or auto-generated), handle collisions by appending "-1",
   "-2", etc., then call configure_auto_promisor_remote().

Let's also add should_accept_new_remote_url() which reuses the
url_matches_accept_list() helper introduced in a previous commit to
find a matching pattern, then delegates to handle_matching_allowed_url()
to create the remote.

And then let's call should_accept_new_remote_url() from the '!item'
(unknown remote) branch of should_accept_remote(), setting
`reload_config` so that the newly-written config is picked up.

Finally let's document all that by:

 - expanding the `promisor.acceptFromServerUrl` entry to describe
   auto-creation, the optional "name=" prefix syntax, the
   "promisor-auto-*" generation rules, and numeric-suffix collision
   handling, and by
 - adding a "remote.<name>.advertisedAs" entry to "remote.adoc".

Also let's extend the precedence paragraph added by a previous commit
to mention this new acceptance path: until now, the only way for
`promisor.acceptFromServerUrl` to trigger acceptance was to allow
field updates for a known remote. With this commit, it can also trigger
auto-creation of a previously-unknown remote whose advertised URL
matches the allowlist.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-28 05:20:15 +09:00
Christian Couder
5dd8043581 promisor-remote: trust known remotes matching acceptFromServerUrl
A previous commit introduced the `promisor.acceptFromServerUrl` config
variable along with the machinery to parse and validate the URL glob
patterns and optional remote name prefixes it contains. However, these
URL patterns are not yet tied into the client's acceptance logic.

When a promisor remote is already configured locally, its fields (like
authentication tokens) may occasionally need to be refreshed by the
server. If `promisor.acceptFromServer` is set to the secure default
("None"), these updates are rejected, potentially causing future
fetches to fail.

To enable such targeted updates for trusted URLs, let's use the URL
patterns from `promisor.acceptFromServerUrl` as an additional URL
based allowlist.

Concretely, let's check the advertised URLs against the URL glob
patterns by introducing a new small helper function called
url_matches_accept_list(), which iterates over the glob patterns and
returns the first matching allowed_url entry (or NULL).

The URL matching is done component by component: scheme and port are
compared exactly, the host and path are matched with wildmatch().
Before matching, the advertised URL is passed through url_normalize()
so that case variations in the scheme/host, percent-encoding tricks,
and ".." path segments cannot bypass the allowlist.

The username and password components of the URL are intentionally
ignored during matching to allow servers to rotate them, though using
the 'token' field of the capability is preferred over embedding
credentials in the URL.

Let's then use this helper in should_accept_remote() so that a known
remote whose URL matches the allowlist is accepted.

To prepare for this new logic, let's also:

 - Add an 'accept_urls' parameter to should_accept_remote().

 - Replace the BUG() guard in the ACCEPT_KNOWN_URL case with an
   explicit 'if (accept == ACCEPT_KNOWN_URL) return' and a new
   BUG() guard in the ACCEPT_NONE case.

 - Call accept_from_server_url() from filter_promisor_remote()
   and relax its early return so that the function is entered when
   `accept_urls` has entries even if `accept == ACCEPT_NONE`.

With this, many organizations may only need something like:

  git config set --global \
          promisor.acceptFromServerUrl "https://my-org.com/*"

to accept only their own remotes. And if they need to accept additional
remotes in some specific repos, they can also set:

  git config set promisor.acceptFromServer knownUrl

and configure the additional remote manually only in the repos where
they are needed.

Let's then properly document `promisor.acceptFromServerUrl` in
"promisor.adoc" as an additive security allowlist for known remotes,
including the URL normalization behavior and the component-wise
matching, and let's mention it in "gitprotocol-v2.adoc".

Also let's clarify in the documentation how
`promisor.acceptFromServerUrl` interacts with
`promisor.acceptFromServer`:

 - Precedence: when both options are set,
   `promisor.acceptFromServerUrl` is consulted first. If a matching
   pattern leads to acceptance, the remote is accepted regardless of
   `promisor.acceptFromServer`. Otherwise the decision is left to
   `promisor.acceptFromServer`.

 - URL-mismatch guard: even when the advertised URL matches the
   allowlist, an already-existing client-side remote whose configured
   URL differs from the advertised one is not accepted through
   `promisor.acceptFromServerUrl`. `promisor.acceptFromServer=all` and
   `=knownName` keep their pre-existing, looser semantics.

The precedence paragraph is intentionally scoped here to known remotes
only (field updates). A following commit that introduces auto-creation
of unknown remotes will extend it to cover that case as well.

Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-28 05:20:15 +09:00
Junio C Hamano
8b5873a1f2 Merge branch 'tb/incremental-midx-part-3.3'
The repacking code has been refactored and compaction of MIDX layers
have been implemented, and incremental strategy that does not require
all-into-one repacking has been introduced.

* tb/incremental-midx-part-3.3:
  repack: allow `--write-midx=incremental` without `--geometric`
  repack: introduce `--write-midx=incremental`
  repack: implement incremental MIDX repacking
  packfile: ensure `close_pack_revindex()` frees in-memory revindex
  builtin/repack.c: convert `--write-midx` to an `OPT_CALLBACK`
  repack-geometry: prepare for incremental MIDX repacking
  repack-midx: extract `repack_fill_midx_stdin_packs()`
  repack-midx: factor out `repack_prepare_midx_command()`
  midx: expose `midx_layer_contains_pack()`
  repack: track the ODB source via existing_packs
  midx: support custom `--base` for incremental MIDX writes
  midx: introduce `--no-write-chain-file` for incremental MIDX writes
  midx: use `strvec` for `keep_hashes`
  midx: build `keep_hashes` array in order
  midx: use `strset` for retained MIDX files
  midx-write: handle noop writes when converting incremental chains
2026-05-27 14:15:45 +09:00
Junio C Hamano
1103041f34 Merge branch 'ds/fetch-negotiation-options'
The negotiation tip options in "git fetch" have been reworked to
allow requiring certain refs to be sent as "have" lines, and to
restrict negotiation to a specific set of refs.

* ds/fetch-negotiation-options:
  send-pack: pass negotiation config in push
  remote: add remote.*.negotiationInclude config
  fetch: add --negotiation-include option for negotiation
  negotiator: add have_sent() interface
  remote: add remote.*.negotiationRestrict config
  transport: rename negotiation_tips
  fetch: add --negotiation-restrict option
  t5516: fix test order flakiness
2026-05-27 14:15:45 +09:00
Junio C Hamano
bccafbc09c Merge branch 'tb/pseudo-merge-bugfixes'
Fixes many bugs in pseudo-merge code.

* tb/pseudo-merge-bugfixes:
  pack-bitmap: prevent pattern leak on pseudo-merge re-assignment
  Documentation: fix broken `sampleRate` in gitpacking(7)
  pack-bitmap: reject pseudo-merge "sampleRate" of 0
  pack-bitmap: parse commits in `find_pseudo_merge_group_for_ref()`
  pack-bitmap: fix pseudo-merge lookup for shared commits
  pack-bitmap: fix inverted binary search in `pseudo_merge_at()`
  pack-bitmap-write: sort pseudo-merge commit lookup table in pack order
  t5333: demonstrate various pseudo-merge bugs
  t/helper: add 'test-tool bitmap write' subcommand
2026-05-27 14:15:43 +09:00
Ivan Baluta
b2040bfafe doc: clarify push.default=simple behavior
The documentation for the 'simple' push mode currently singles out
the centralized workflow, which can cause confusion about its
behavior in other scenarios, such as triangular workflows.

Clarify that 'simple' always pushes the current branch to a branch
of the same name, but only enforces the strict upstream tracking
requirement when pushing back to the same remote being pulled from.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Ivan Baluta <ivanbaluta.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-26 20:11:29 +09:00
Jean-Noël Avila
2ef248ae45 doc: convert git-imap-send synopsis and options to new style
Convert git-imap-send from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms
- Backtick-quote all config keys in config/imap.adoc
- Backtick-quote bare config key references in prose

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-25 20:05:45 +09:00
Jean-Noël Avila
ba1c516eda doc: convert git-apply synopsis and options to new style
Convert git-apply from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms and config keys in config/apply.adoc
- Convert single-quoted inline commands ('git apply', 'diff', etc.)
- Wrap standalone placeholders in underscores (<n>, <root>, <action>)
- Backtick-quote `*.rej` and GNU `patch` tool references

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-25 20:05:44 +09:00
Jean-Noël Avila
242d3aa317 doc: convert git-am synopsis and options to new style
Convert git-am from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms
- Convert inline man page refs
- Convert inline command refs
- Convert prose placeholders:

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-25 20:05:44 +09:00
Jean-Noël Avila
25d5d60958 doc: convert git-grep synopsis and options to new style
Convert git-grep.adoc from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Change 'git grep' to git grep (no single quotes)
- Backtick-quote all OPTIONS terms
- Convert inline man page refs: grep(1) -> `grep`(1)
- Convert inline command refs: 'git diff' -> `git diff`
- Convert prose placeholders: <file> -> _<file>_

Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-25 20:05:44 +09:00
Kristoffer Haugsbakk
5c6a41e4b5 doc: hook: don’t self-link via config include
Do not link to git-hook(1) from the config options when we already are
in that doc.

This implementation is similar to the updates to git-init(1) and
git-commit(1), implemented in [1] and [2], respectively.

† 1: e7b3a768 (doc: git-init: rework config item init.templateDir,
     2024-03-10)
† 2: 819fdd6e (doc: convert git commit config to new format, 2025-01-15)

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-22 09:36:20 +09:00
Derrick Stolee
a6d92c48e4 send-pack: pass negotiation config in push
When push.negotiate is enabled, 'git push' spawns a child 'git fetch
--negotiate-only' process to find common commits.  Pass
--negotiation-include and --negotiation-restrict options from the
'remote.<name>.negotiationInclude' and
'remote.<name>.negotiationRestrict' config keys to this child process.

When negotiationRestrict is configured, it replaces the default
behavior of using all remote refs as negotiation tips. This allows
the user to control which local refs are used for push negotiation.

When negotiationInclude is configured, the specified ref patterns
are passed as --negotiation-include to ensure their tips are always
sent as 'have' lines during push negotiation.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-20 11:33:24 +09:00
Derrick Stolee
6f37fecfed remote: add remote.*.negotiationInclude config
Add a new 'remote.<name>.negotiationInclude' multi-valued config option that
provides default values for --negotiation-include when no
--negotiation-include arguments are specified over the command line.  This
is a mirror of how 'remote.<name>.negotiationRestrict' specifies defaults
for the --negotiation-restrict arguments.

Each value is either an exact ref name or a glob pattern whose tips should
always be sent as 'have' lines during negotiation. The config values are
resolved through the same resolve_negotiation_include() codepath as the CLI
options.

This option is additive with the normal negotiation process: the negotiation
algorithm still runs and advertises its own selected commits, but the refs
matching the config are sent unconditionally on top of those heuristically
selected commits.

Similar to the negotiationRestrict config, an empty value resets the value
list to allow ignoring earlier config values, such as those that might be
set in system or global config.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-20 11:33:24 +09:00
Derrick Stolee
8bb252f86c remote: add remote.*.negotiationRestrict config
In a previous change, the --negotiation-restrict command-line option of 'git
fetch' was added as a synonym of --negotiation-tip. Both of these options
restrict the set of 'haves' the client can send as part of negotiation.

This was previously not available via a configuration option. Add a new
'remote.<name>.negotiationRestrict' multi-valued config option that updates
'git fetch <name>' to use these restrictions by default.

If the user provides even one --negotiation-restrict argument, then the
config is ignored.

An empty value resets the value list to allow ignoring earlier config
values, such as those that might be set in system or global config.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-20 11:33:24 +09:00
Derrick Stolee
1a445fc60b fetch: add --negotiation-restrict option
The --negotiation-tip option to 'git fetch' and 'git pull' allows users
to specify that they want to focus negotiation on a small set of
references. This is a _restriction_ on the negotiation set, helping to
focus the negotiation when the ref count is high. However, it doesn't
allow for the ability to opportunistically select references beyond that
list.

This subtle detail that this is a 'maximum set' and not a 'minimum set'
is not immediately clear from the option name. This makes it more
complicated to add a new option that provides the complementary behavior
of a minimum set.

For now, create a new synonym option, --negotiation-restrict, that
behaves identically to --negotiation-tip. Update the documentation to
make it clear that this new name is the preferred option, but we keep
the old name for compatibility. Mark --negotiation-tip as an alias of the
new, preferred option.

Update a few warning messages with the new option, but also make them
translatable with the option name inserted by formatting. At least one
of these messages will be reused later for a new option.

Reviewed-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-20 11:33:23 +09:00
Taylor Blau
938af89260 repack: introduce --write-midx=incremental
Expose the incremental MIDX repacking mode (implemented in an earlier
commit) via a new --write-midx=incremental option for `git repack`.

Add "incremental" as a recognized argument to the --write-midx
OPT_CALLBACK, mapping it to REPACK_WRITE_MIDX_INCREMENTAL. When this
mode is active and --geometric is in use, set the midx_layer_threshold
on the pack geometry so that only packs in sufficiently large tip layers
are considered for repacking.

Two new configuration options control the compaction behavior:

 - repack.midxSplitFactor (default: 2): the factor used in the
   geometric merging condition for MIDX layers.

 - repack.midxNewLayerThreshold (default: 8): the minimum number of
   packs in the tip MIDX layer before its packs are considered as
   candidates for geometric repacking.

Add tests exercising the new mode across a variety of scenarios
including basic geometric violations, multi-round chain integrity,
branching and merging histories, cross-layer object uniqueness, and
threshold-based compaction.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-20 11:31:14 +09:00
Junio C Hamano
18581f836f Merge branch 'js/adjust-tests-to-explicitly-access-bare-repo'
Some tests assume that bare repository accesses are by default
allowed; rewrite some of them to avoid the assumption, rewrite
others to explicitly set safe.bareRepository to allow them.

* js/adjust-tests-to-explicitly-access-bare-repo:
  safe.bareRepository: default to "explicit" with WITH_BREAKING_CHANGES
  status tests: filter `.gitconfig` from status output
  ls-files tests: filter `.gitconfig` from `--others` output
  t5601: restore `.gitconfig` after includeIf test
  t1305: use `--git-dir=.` for bare repo in include cycle test
  t1300: remove global config settings injected by test-lib.sh
  t7900: do not let `$HOME/.gitconfig` interfere with XDG tests
  test-lib: allow bare repository access when breaking changes are enabled
2026-05-20 10:30:57 +09:00
Junio C Hamano
60afbae98d Merge branch 'mc/http-emptyauth-negotiate-fix'
The 'http.emptyAuth=auto' configuration now correctly attempts
Negotiate authentication before falling back to manual credentials.
This allows seamless Kerberos ticket-based authentication without
requiring users to explicitly set 'http.emptyAuth=true'.

* mc/http-emptyauth-negotiate-fix:
  doc: clarify http.emptyAuth values
  t5563: add tests for http.emptyAuth with Negotiate
  http: attempt Negotiate auth in http.emptyAuth=auto mode
  http: extract http_reauth_prepare() from retry paths
2026-05-19 09:57:43 +09:00
Jörg Thalheim
df67d73ca3 config: retry acquiring config.lock, configurable via core.configLockTimeout
Concurrent config writers race for the ".lock" file, which is taken
with open(O_EXCL) and no retry, so the losers fail right away with
"could not lock config file".

This shows up with parallel "git worktree add -b" against the same
repository: each one writes a couple of branch.* keys and the losers
fail at random. Worse, "git worktree add" doesn't propagate that
failure to its exit code, so the tracking config is silently dropped.
(The swallowed error is a separate bug.)

Retry instead of giving up on the first EEXIST. The lock is only held
while rewriting a small file, so the loser only has to wait out the
other writers. Same approach as 4ff0f01cb7 (refs: retry acquiring
reference locks for 100ms, 2017-08-21).

On the semantics: the on-disk config is read only after the lock is
taken, so writers touching different keys can't lose each other's
change. Writers touching the same key still get last-writer-wins, but
that is already the case today and would need a compare-and-swap config
API to fix. The retry only turns hard failures into successes.

Default to 1000ms, like core.packedRefsTimeout: same shape of problem,
one shared file everyone serializes through. A larger timeout only
costs anything when a stale lock is left behind by a crash, which is
rare; a smaller one fails spuriously on slow filesystems (NTFS has
been seen needing more than 100ms). Make it configurable as
core.configLockTimeout. There is no chicken-and-egg problem: we read
the config before we lock it.

microsoft/git carries a similar patch (core.configWriteLockTimeoutMS,
default off) for Scalar's tests. Defaulting to non-zero here because
the worktree case fails silently.

Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-18 09:30:29 +09:00
Junio C Hamano
c26c58de0c Merge branch 'mf/format-patch-cover-letter-format-docfix'
Docfix.

* mf/format-patch-cover-letter-format-docfix:
  Fix docs for format.commitListFormat
2026-05-17 22:58:30 +09:00
Taylor Blau
03c7a30cee pack-bitmap: reject pseudo-merge "sampleRate" of 0
The "bitmapPseudoMerge.*.sampleRate" configuration controls what
fraction of unstable commits are included in each pseudo-merge group.
The config validation accepts values in the range `[0, 1]`, but a value
of exactly 0 causes a division by zero in `select_pseudo_merges_1()`:

    if (j % (uint32_t)(1.0 / group->sample_rate))

When `sample_rate` is 0, `1.0 / 0.0` produces `+inf`, and casting
infinity to `uint32_t` is undefined behavior in C. On most platforms
this yields 0, making the subsequent modulo operation (`j % 0`) a
fatal arithmetic trap.

This path was not previously reachable because an earlier bug caused
all pseudo-merge candidates to be classified as "stable" (where the
sampling rate is not used), regardless of their actual commit date. Now
that the date classification is fixed, the unstable path is exercised
and the division by zero can fire.

Fix this by changing the validation to require a strict lower bound and
thus reject 0.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-12 10:36:18 +09:00
Junio C Hamano
7760f83b59 Merge branch 'jc/neuter-sideband-fixup'
Try to resurrect and reboot a stalled "avoid sending risky escape
sequences taken from sideband to the terminal" topic by Dscho.  The
plan is to keep it in 'next' long enough to see if anybody screams
with the "everything dropped except for ANSI color escape sequences"
default.

* jc/neuter-sideband-fixup:
  sideband: drop 'default' configuration
  sideband: offer to configure sanitizing on a per-URL basis
  sideband: add options to allow more control sequences to be passed through
  sideband: do allow ANSI color sequences by default
  sideband: introduce an "escape hatch" to allow control characters
  sideband: mask control characters
2026-05-11 13:49:05 +09:00
Junio C Hamano
718db095c2 Merge branch 'ar/parallel-hooks'
Hook scripts defined via the configuration system can now be
configured to run in parallel.

* ar/parallel-hooks:
  t1800: test SIGPIPE with parallel hooks
  hook: allow hook.jobs=-1 to use all available CPU cores
  hook: add hook.<event>.enabled switch
  hook: move is_known_hook() to hook.c for wider use
  hook: warn when hook.<friendly-name>.jobs is set
  hook: add per-event jobs config
  hook: add -j/--jobs option to git hook run
  hook: mark non-parallelizable hooks
  hook: allow pre-push parallel execution
  hook: allow parallel hook execution
  hook: parse the hook.jobs config
  config: add a repo_config_get_uint() helper
  repository: fix repo_init() memleak due to missing _clear()
2026-05-11 10:05:53 +09:00
Junio C Hamano
ead6888559 Merge branch 'ja/doc-difftool-synopsis-style'
Doc mark-up updates.

* ja/doc-difftool-synopsis-style:
  doc: convert git-describe manual page to synopsis style
  doc: convert git-shortlog manual page to synopsis style
  doc: convert git-range-diff manual page to synopsis style
  doc: convert git-difftool manual page to synopsis style
2026-05-11 10:05:52 +09:00
Matthew John Cheetham
4919938d28 doc: clarify http.emptyAuth values
The existing description of http.emptyAuth explains the purpose of the
setting but never says what values it accepts. Readers have to infer
from context (or read the source) that it takes 'true', 'false', or
'auto', and what each one means.

Document the three accepted values explicitly:

* 'auto' (the default) only sends empty credentials when the server's
  401 response advertises a mechanism that requires them, such as
  GSS-Negotiate. This matches the long-standing auto-detection
  behaviour added in 40a18fc77c (http: add an "auto" mode for
  http.emptyauth, 2017-02-25).

* 'true' unconditionally sends empty credentials on the very first
  request, before any 401 response, for callers that know they want
  this behaviour up front.

* 'false' disables the feature entirely; mechanisms that depend on
  empty credentials, such as GSS-Negotiate, will not work in this
  mode.

Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-01 14:01:57 +09:00
Johannes Schindelin
985b38ca6c safe.bareRepository: default to "explicit" with WITH_BREAKING_CHANGES
When an attacker can convince a user to clone a crafted repository
that contains an embedded bare repository with malicious hooks, any Git
command the user runs after entering that subdirectory will discover
the bare repository and execute the hooks. The user does not even need
to run a Git command explicitly: many shell prompts run `git status`
in the background to display branch and dirty state information, and
`git status` in turn may invoke the fsmonitor hook if so configured,
making the user vulnerable the moment they `cd` into the directory. The
`safe.bareRepository` configuration variable (introduced in 8959555cee
(setup_git_directory(): add an owner check for the top-level directory,
2022-03-02)) already provides protection against this attack vector by
allowing users to set it to "explicit", but the default remained "all"
for backwards compatibility.

Since Git 3.0 is the natural point to change defaults to safer
values, flip the default from "all" to "explicit" when built with
`WITH_BREAKING_CHANGES`. This means Git will refuse to work with bare
repositories that are discovered implicitly by walking up the directory
tree. Bare repositories specified via `--git-dir` or `GIT_DIR` continue
to work, and directories that look like `.git`, worktrees, or submodule
directories are unaffected (the existing `is_implicit_bare_repo()`
whitelist handles those cases).

Users who rely on implicit bare repository discovery can restore the
previous behavior by setting `safe.bareRepository=all` in their global
or system configuration.

The test for the "safe.bareRepository in the repository" scenario
needed a more involved fix: it writes a `safe.bareRepository=all`
entry into the bare repository's own config to verify that repo-local
config does not override the protected (global) setting. Previously,
`test_config -C` was used to write that entry, but its cleanup runs `git
-C <bare-repo> config --unset`, which itself fails when the default is
"explicit" and the global config has already been cleaned up. Switching
to direct git config --file access avoids going through repository
discovery entirely.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-27 14:50:54 +09:00
Mirko Faina
7584d10bc2 Fix docs for format.commitListFormat
When renaming the option --cover-letter-format to --commit-list-format
we forgot to rename the opton in the section too. Fix it.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-22 16:16:24 -07:00
Elijah Newren
e895506107 doc: fix grammar errors in submodule description
6cc6d1b4c6 (Documentation: update add --force option + ignore=all
config, 2026-02-06) added text describing both the ignore=none and
ignore=all behaviors.  The former had minor formatting and grammatical
errors, while the latter was a bit garbled.  I have tried to tweak the
wording on the latter to make it read as I think was intended, and fixed
the minor grammatical issues with both as well.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-16 21:22:01 -07:00
Elijah Newren
31f23c958b doc: fix plural agreement in pack.preferBitmapTips
hierarchies -> hierarchy

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-16 21:22:01 -07:00
Elijah Newren
8ecf2a192a doc: fix self-referential config in sendemail.smtpSSLClientKey
a8215a2051 (send-email: add client certificate options, 2026-03-02)
added documentation for sendemail.smtpSSLClientKey that says it works
"in conjunction with `sendemail.smtpSSLClientKey`" -- referring to
itself.  It appears that `sendemail.smtpSSLClientCert` was the intended
reference; fix it.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-16 21:22:01 -07:00
Paul Tarjan
ce48de8b2c fsmonitor: implement filesystem change listener for Linux
Implement the built-in fsmonitor daemon for Linux using the inotify
API, bringing it to feature parity with the existing Windows and macOS
implementations.

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

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

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

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

Based-on-patch-by: Eric DeCosta <edecosta@mathworks.com>
Based-on-patch-by: Marziyeh Esipreh <marziyeh.esipreh@gmail.com>
Signed-off-by: Paul Tarjan <github@paulisageek.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-15 08:44:33 -07:00
Adrian Ratiu
495b7d54dc hook: allow hook.jobs=-1 to use all available CPU cores
Allow -1 as a value for hook.jobs, hook.<event>.jobs, and the -j
CLI flag to mean "use as many jobs as there are CPU cores", matching
the convention used by fetch.parallel and other Git subsystems.

The value is resolved to online_cpus() at parse time so the rest
of the code always works with a positive resolved count.

Other non-positive values (0, -2, etc) are rejected with a warning
(config) or die (CLI).

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-10 07:58:55 -07:00