Summary
bit gc and bit prune abort in any shallow clone. The reachability walk runs past the shallow boundary into the parent commits that were never fetched.
Repro
bit --no-git-fallback clone -q --depth 2 "file://$PWD/origin.git" w
bit --no-git-fallback -C w gc # gc failed: Missing commit object (exit 1)
bit --no-git-fallback -C w prune # exit 1
Real git succeeds for both. Reproduces at every depth (1, 2, 4) and over both the local and HTTP transports, and also after committing on top of the shallow tip.
Cause
modules/bit_lib/src/gc.mbt walks from the ref tips with no boundary:
- line 86 —
repack_git_dir
- line 107 —
gc_git_dir
- line 157
all call collect_reachable_objects_from_commits(db, rfs, roots), which raises InvalidObject("Missing commit object") as soon as it reaches a commit whose object is absent.
#183 added an optional shallow~ parameter to those collectors for exactly this case, but the gc path was not wired to pass @repo.read_shallow_boundaries.
Expected
gc and prune treat the commits in .git/shallow as parentless and complete normally, keeping every object the repository holds.
Summary
bit gcandbit pruneabort in any shallow clone. The reachability walk runs past the shallow boundary into the parent commits that were never fetched.Repro
Real git succeeds for both. Reproduces at every depth (1, 2, 4) and over both the local and HTTP transports, and also after committing on top of the shallow tip.
Cause
modules/bit_lib/src/gc.mbtwalks from the ref tips with no boundary:repack_git_dirgc_git_dirall call
collect_reachable_objects_from_commits(db, rfs, roots), which raisesInvalidObject("Missing commit object")as soon as it reaches a commit whose object is absent.#183 added an optional
shallow~parameter to those collectors for exactly this case, but the gc path was not wired to pass@repo.read_shallow_boundaries.Expected
gcandprunetreat the commits in.git/shallowas parentless and complete normally, keeping every object the repository holds.