Skip to content

Keep the history of existing clones when old commits are deleted - #6

Merged
Kaliumhexacyanoferrat merged 1 commit into
mainfrom
fix/shallow-history-of-existing-clones
Oct 5, 2026
Merged

Kaliumhexacyanoferrat merged 1 commit into
mainfrom
fix/shallow-history-of-existing-clones

Conversation

@Kaliumhexacyanoferrat

Copy link
Copy Markdown
Owner

A repository whose oldest commits were deleted (retention, see Truncated histories) announced the oldest remaining commit as a shallow boundary to every client - also to a clone made before the deletion, which still has the deleted parents. Git refuses to update a complete clone to commits behind a shallow root:

warning: rejected refs/remotes/origin/main because shallow roots are not allowed to be updated

so such a clone could not fetch anything newer, contrary to what the docs promise ("Clients that already have older commits keep them").

The fix: the commits the history refers to but no longer has - the missing parents of the oldest remaining commits, found by walking the newest 10,000 commits from the references - are now known by their ids. A client that says it has one is acknowledged as having it (so it keeps sending it for the rest of the stateless negotiation), and a commit based on it is no shallow boundary for that client. Fresh clones still get a shallow history.

  • RepositoryContext.GetTruncatedAsync() collects those ids, once per request
  • FetchPlanner.FindCommonAsync acknowledges them, GetOwnedAsync counts them as owned, and PlanAsync leaves out the shallow line where the client has the history
  • TestRetentionKeepsTheHistoryOfExistingClones (protocol 0 and 2): a clone made before versions were deleted pulls the newer ones, stays complete and passes git fsck --strict; a new clone is shallow
  • Docs: How It Works and Serving Content say what happens to existing clones
  • Version 0.1.1

Found while building git access for GenHTTP Lambda, which prunes old versions per tier.

🤖 Generated with Claude Code

A repository whose oldest commits were deleted announced the oldest
remaining commit as a shallow boundary to every client - also to a clone
made before, which still has the deleted parents. Git refuses to update
a complete clone to commits behind a shallow root ("shallow roots are not
allowed to be updated"), so such a clone could not fetch anything newer.

The commits the history refers to but no longer has are now known by
their ids: a client that has one is acknowledged as having it, and a
commit based on it is no shallow boundary for that client.

Bumps the version to 0.1.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Kaliumhexacyanoferrat
Kaliumhexacyanoferrat merged commit baf8fed into main Oct 5, 2026
3 checks passed
@Kaliumhexacyanoferrat
Kaliumhexacyanoferrat deleted the fix/shallow-history-of-existing-clones branch October 5, 2026 08:54
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