From: "Kristofer Karlsson via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Kristofer Karlsson <krka@spotify.com>,
Kristofer Karlsson <krka@spotify.com>,
Kristofer Karlsson <krka@spotify.com>
Subject: [PATCH v2 1/2] Documentation: describe connectivity checking
Date: Mon, 28 Sep 2026 13:02:31 +0000 [thread overview]
Message-ID: <97c11449aeae924436ba22a00a2545254e988a58.1790600552.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2211.v2.git.1790600552.gitgitgadget@gmail.com>
From: Kristofer Karlsson <krka@spotify.com>
Add Documentation/technical/connectivity-check.adoc describing
the connectivity invariant and the full connectivity check.
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
---
.../technical/connectivity-check.adoc | 109 ++++++++++++++++++
1 file changed, 109 insertions(+)
create mode 100644 Documentation/technical/connectivity-check.adoc
diff --git a/Documentation/technical/connectivity-check.adoc b/Documentation/technical/connectivity-check.adoc
new file mode 100644
index 0000000000..d20bff6af6
--- /dev/null
+++ b/Documentation/technical/connectivity-check.adoc
@@ -0,0 +1,109 @@
+Connectivity checking
+=====================
+
+After receiving new objects via fetch, push (receive-pack), clone,
+or bundle, Git verifies that the new reference tips do not leave
+the repository in a state where reachable objects are missing.
+This verification is called the connectivity check.
+
+Connectivity invariant
+----------------------
+
+A repository is connected when every object reachable from its
+references is available locally (with exceptions noted below).
+
+The connectivity check maintains this invariant when references
+are updated. It trusts the existing connected state and verifies
+that the new reference tips do not introduce references to
+unavailable objects. Verification is permitted to stop when it
+reaches objects already reachable from trusted existing
+references, since their closure is already connected. These
+trusted references include local references and references from
+alternate object stores.
+
+Without this check, a truncated or corrupted transfer could leave
+a repository in a state where later history walks encounter
+missing objects.
+
+Exceptions
+~~~~~~~~~~
+
+Gitlink entries (submodule references) are excluded from
+connectivity checking. Their target objects belong to a separate
+repository.
+
+In partial clones, objects promised by a promisor remote are
+accepted as connected without requiring local existence. The
+check excludes promisor objects from traversal so that it does
+not trigger on-demand fetches for them.
+
+Full connectivity check
+-----------------------
+
+`check_connected()` (see `connected.c`) normally performs the
+connectivity check using a `rev-list` subprocess, feeding the
+new reference tips via stdin. A normal invocation is roughly:
+
+ git rev-list --objects --stdin --not --all --quiet
+ --alternate-refs [--exclude-promisor-objects]
+
+When promisor remotes are configured, `check_connected()` first
+attempts a fast path based on promisor packfiles. If it falls
+back to the `rev-list` check, `--exclude-promisor-objects` is
+added so that the traversal does not trigger on-demand fetches.
+
+Consider the following graph after a fetch, where all reference
+tips point directly to commits. For simplicity, only local
+references appear on the already-connected side; alternate refs
+play the same role. N3 is a merge commit:
+
+ /-------------L2
+ /
+ C1---B1---C2---B2-----L1
+ \ \
+ N1 N3---T2
+ \ /
+ N2-----------T1
+
+ L1, L2: local refs
+ T1, T2: incoming tips (new refs)
+ N1, N2, N3: incoming commits (N3 is a merge)
+ B1, B2: boundary commits (already connected)
+ C1, C2: already connected (but not boundary)
+
+The incoming set is the commits reachable from the incoming
+tips but not from the already-connected side. Boundary commits
+are the already-connected commits at the edge of that set. Here
+B1 is an ancestor of B2, which happens when incoming branches
+fork at different depths in the existing history.
+
+The check proceeds in three phases:
+
+1. Walk from the incoming tips (T1, T2) against the trusted
+ refs (L1, L2) to find the incoming set ({N1, N2, N3, T1, T2}).
+
+2. Walk the trees of the boundary commits (B1, B2) and mark
+ those objects uninteresting. These trees are already trusted
+ because their commits are on the already-connected side.
+
+3. Walk the trees of each incoming commit and verify that every
+ referenced object is connected, stopping at objects already
+ marked uninteresting in phase 2.
+
+Deepening fetches
+~~~~~~~~~~~~~~~~~
+
+For deepening fetches (where the shallow boundary moves), the
+full check omits `--not --all`. There is no existing-reference
+boundary at which the walk can stop. Instead, traversal follows
+the effective shallow boundary supplied for the deepened
+repository. The new content may be below the old shallow
+boundary even when the tips themselves have not changed.
+
+Non-commit tips
+~~~~~~~~~~~~~~~
+
+When a new reference points to a non-commit object, such as a
+tag, tree, or blob, that object is not part of the commit walk.
+These non-commit tips are handled by the subsequent object
+traversal.
--
gitgitgadget
next prev parent reply other threads:[~2026-09-28 13:02 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-14 9:47 [PATCH 0/2] connected: add incremental connectivity check Kristofer Karlsson via GitGitGadget
2026-09-14 9:47 ` [PATCH 1/2] Documentation: describe connectivity checking Kristofer Karlsson via GitGitGadget
2026-09-14 9:47 ` [PATCH 2/2] connected: add incremental connectivity check via rev-list Kristofer Karlsson via GitGitGadget
2026-09-14 15:26 ` Junio C Hamano
2026-09-14 17:46 ` Kristofer Karlsson
2026-09-14 15:12 ` [PATCH 0/2] connected: add incremental connectivity check Junio C Hamano
2026-09-28 13:02 ` [PATCH v2 " Kristofer Karlsson via GitGitGadget
2026-09-28 13:02 ` Kristofer Karlsson via GitGitGadget [this message]
2026-10-05 7:59 ` [PATCH v2 1/2] Documentation: describe connectivity checking Patrick Steinhardt
2026-10-05 19:17 ` Junio C Hamano
2026-10-06 5:59 ` Patrick Steinhardt
2026-10-06 10:03 ` Kristofer Karlsson
2026-10-06 10:12 ` Kristofer Karlsson
2026-09-28 13:02 ` [PATCH v2 2/2] connected: add incremental connectivity check via rev-list Kristofer Karlsson via GitGitGadget
2026-10-05 8:00 ` Patrick Steinhardt
2026-10-06 10:37 ` Kristofer Karlsson
2026-10-06 12:08 ` Patrick Steinhardt
2026-10-06 12:36 ` Kristofer Karlsson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=97c11449aeae924436ba22a00a2545254e988a58.1790600552.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=krka@spotify.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox