Skip to content

fetch: add fetch.haveRefs config to force "haves" advertisement#2075

Open
derrickstolee wants to merge 5 commits intogitgitgadget:masterfrom
derrickstolee:have-refs
Open

fetch: add fetch.haveRefs config to force "haves" advertisement#2075
derrickstolee wants to merge 5 commits intogitgitgadget:masterfrom
derrickstolee:have-refs

Conversation

@derrickstolee
Copy link
Copy Markdown

TBD

The 'fetch follows tags by default' test sorts using 'sort -k 4', but
for-each-ref output only has 3 columns. This relies on sort treating
records with fewer fields as having an empty fourth field, which may
produce unstable results depending on locale. Use 'sort -k 3' to match
the actual number of columns in the output.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Add a new multi-valued config option 'remote.<name>.haveRefs' that
specifies ref patterns whose tips should always be sent as 'have'
commits during fetch negotiation with that remote.

Parse the option in handle_config() following the same pattern as
remote.<name>.serverOption. Store the values in a string_list on struct
remote so they are available per-remote.

This commit only adds the config infrastructure; the actual negotiation
logic will use it in a subsequent commit.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
When negotiating with a remote during 'git fetch', the client advertises
a list of commits that exist locally. In repos with many references,
this list of 'haves' can be truncated. Depending on data shape, dropping
certain references may be expensive.

Add support for the multi-valued config option remote.<name>.haveRefs,
which specifies ref patterns whose tips should always be sent as 'have'
commits during fetch negotiation with that specific remote.

Each value is either an exact ref name (e.g. refs/heads/release) or a
glob pattern (e.g. refs/heads/release/*). The pattern syntax is the same
as for --negotiation-tip.

Thread the have_refs list from the remote config through the transport
layer into the fetch-pack negotiation code. All three negotiation paths
are updated:
 - v0/v1 protocol (find_common)
 - v2 protocol (do_fetch_pack_v2 / send_fetch_request)
 - push negotiation (negotiate_using_fetch)

If --negotiation-tip is used, then the have set is first restricted by
that option and then increased to include the tips specified by the
remote.<name>.haveRefs config values.

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

Signed-off-by: Derrick Stolee <stolee@gmail.com>
@gitgitgadget
Copy link
Copy Markdown

gitgitgadget bot commented Mar 27, 2026

There is an issue in commit c8af9be:
t5516: fix test order flakiness

  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget bot commented Mar 27, 2026

There is an issue in commit 05e72d0:
remote: add haveRefs config to struct remote

  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget bot commented Mar 27, 2026

There is an issue in commit 2ce0af4:
fetch-pack: respect remote.<name>.haveRefs during negotiation

  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget bot commented Mar 27, 2026

There is an issue in commit 10185e1:
send-pack: pass remote name for push negotiation

  • Commit not signed off

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget bot commented Mar 27, 2026

There are issues in commit c71fb04:
docs: describe remote.<name>.haveRefs config option

  • Commit not signed off
  • Lines in the body of the commit messages should be wrapped between 60 and 76 characters.
    Indented lines, and lines without whitespace, are exempt

When push.negotiate is enabled, send-pack spawns a 'git fetch
--negotiate-only' subprocess to discover common commits. Previously this
subprocess received only the remote URL, which meant it could not find
per-remote config like remote.<name>.haveRefs.

Add a remote_name field to send_pack_args, set it from the transport
layer where the remote struct is available, and pass the remote name
(falling back to the URL) to the negotiation subprocess. This allows the
subprocess to resolve remote.<name>.haveRefs for the correct remote.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Document the new remote.<name>.haveRefs multi-valued config option in
Documentation/config/remote.adoc. Also update Documentation/fetch-options.adoc
to mention that --negotiation-tip restrictions do not apply to haveRefs.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
@gitgitgadget
Copy link
Copy Markdown

gitgitgadget bot commented Mar 27, 2026

There is an issue in commit ea23b22:
docs: describe remote.<name>.haveRefs config option

  • Lines in the body of the commit messages should be wrapped between 60 and 76 characters.
    Indented lines, and lines without whitespace, are exempt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant