Skip to content

connected: ignore replacements in the connectivity check - #2279

Open
spkrka wants to merge 1 commit into
gitgitgadget:masterfrom
spkrka:replace-connectivity
Open

spkrka wants to merge 1 commit into
gitgitgadget:masterfrom
spkrka:replace-connectivity

Conversation

@spkrka

@spkrka spkrka commented Oct 23, 2026 •

Copy link
Copy Markdown

I noticed this while working on the incremental connectivity check
[1]. As far as I can tell from the history, check_connected() was
never meant to follow replace refs: connected.c came after the
commands that walk the object graph were taught to ignore them, and
I could not find any discussion of it.

As the commit message says, this is mainly about keeping the check
consistent with fsck, repack and upload-pack. The test demonstrates
the difference, but it takes both a replace ref for an object that
is not present locally and a sender that sends an incomplete
pack, so I do not expect anyone to have run into it.

This does not interfere with shallow boundaries: they are applied
while parsing commits, through the same internal mechanism as the
deprecated info/grafts file, and --no-replace-objects disables
neither of them.

This is independent of the incremental check series. That series
currently matches the existing behavior, and t5413 there asserts
that a replacement is followed, so whichever lands second will need
to update those tests. Once both are in, rev-list
--connectivity-check could disable replacements itself, and the
incremental verifier could drop OBJECT_INFO_LOOKUP_REPLACE.

[1] https://lore.kernel.org/git/pull.2211.v4.git.1792581744.gitgitgadget@gmail.com/

Cc: Christian Couder christian.couder@gmail.com

@spkrka
spkrka force-pushed the replace-connectivity branch from 6a4049d to 25986d3 Compare October 23, 2026 11:25
The connectivity check follows replace refs, but other operations
that depend on the repository being complete, such as fsck, prune,
pack-objects and upload-pack, do not. They were taught to ignore
replacements in dae556b (environment: add global variable to
disable replacement, 2009-01-23), as they must work with the
original objects, and check_connected() came later without doing
the same.

This is mainly about consistency: the check should verify the same
objects that the commands relying on its result will read, rather
than fix a problem seen in practice. The two can disagree, though.
If a replace ref names an object that is not yet present locally,
the check follows the replacement instead of that object when it
arrives, and accepts an incoming pack that lacks objects below it.
fsck and repack then fail. Such a replace ref can be the result of
fetching refs/replace/* without the branch that contains the
replaced commit, which fsck does not complain about, but it still
takes a sender that sends an incomplete pack.

Pass --no-replace-objects to the rev-list subprocess so that the
check examines the original objects.

The test fetches a bundle whose pack lacks a blob, into a
repository with a replace ref for the not yet present commit.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
@spkrka
spkrka force-pushed the replace-connectivity branch from 25986d3 to a5fbfa7 Compare October 23, 2026 13:18
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