Repository navigation
Description
tl;dr: I enabled feature.experimental in my global git config, and now whenever I clone a new repo with git clone, sapling's dotgit mode fails.
AI Slop
Muse Spark 1.1's Issue Summary
Sapling dotgit mode does not work in new repos cloned with git clone when Git uses reftable ref storage. Old repos still work. π¨
π Environment
- Git:
2.55.0.141.g55526a1826.dirty - Sapling:
SAPLING_VERSION 0.2 - Config:
~/.gitconfighasfeature.experimental = true - OS:
darwin
π₯ Error Message
abort: When constructing alloc::boxed::Box<dyn storemodel::StoreOutput> from dyn storemodel::StoreInfo, after being ignored by ["eager"], "git" reported error: opening git store: unsupported extension name extensions.refstorage; class=Repository (6)
Error comes from eden/scm/lib/gitstore/src/gitstore.rs:98 (GitStore::open -> git2::Repository::open).
π Reproduction Steps
-
Enable experimental features in global git config: π
[feature] experimental = true -
Clone any repo with
git clone. Example: π₯rm -rf /tmp/reftable-test git clone https://github.com/git/git.git /tmp/reftable-test cat /tmp/reftable-test/.git/configConfig shows:
[extensions] refstorage = reftableAnd
.git/reftable/exists..git/refs/headsdoes not. -
Run
slin repo: πΉοΈcd /tmp/reftable-test && sl statusThis fails with error above.
-
Also reproduce in reporter path: π
cd ~/code/github.com/git/git.git/ && sl status
π¬ Root Cause
-
Git 2.55 enables
init.defaultRefFormat=reftablewhenfeature.experimental=true. SeeDocumentation/config/feature.adoc:16. πWhen this flag is set,
git cloneandgit initcreate repos withextensions.refstorage = reftableand store refs in.git/reftable/tables. -
Sapling uses
libgit2viagit2 = "0.20.4"ineden/scm/lib/gitstore/Cargo.toml:24. This version does not supportextensions.refstorage.git2::Repository::openineden/scm/lib/gitstore/src/gitstore.rs:98fails. π§© -
Low level ref reader in
eden/scm/lib/gitcompat/src/refs.rs:141only reads loose files underrefs/andpacked-refs. It does not readreftableformat. π
π Related Code
eden/scm/lib/gitstore/src/gitstore.rs:98- opens repo with libgit2eden/scm/lib/gitstore/Cargo.toml:24-git2 = "0.20.4"eden/scm/lib/gitcompat/src/refs.rs:141-populate_packed_referenceseden/scm/lib/gitcompat/src/refs.rs:210-populate_loose_directory_references
π Impact
- Any user with
feature.experimental=true(or explicitinit.defaultRefFormat=reftable) gets new clones that do not work withsl. feature.experimentalis popular. Git will likely makereftabledefault in future. Impact will grow.β οΈ
π οΈ Suggested Fix
-
Update
libgit2to version that supportsreftable. Check iflibgit2main branch already supports reftable. β¬οΈ -
Update
gitcompat/src/refs.rsto supportreftablebackend:- Option A: shell out to
git refs/git for-each-ref/git show-reffor ref list. Then Sapling uses Git binary which supports reftable. π§ - Option B: add reftable parser in Rust, or use
gitoxidewhich supports reftable. π¦
- Option A: shell out to
-
Alternatively, detect reftable and show clear error with migration hint. π‘
β Workaround For Users
Until fix is available:
-
Force
filesformat for new repos. Add to~/.gitconfig: π§[init] defaultRefFormat = files -
Migrate existing broken repos: π
git refs migrate --ref-format=filesThis converts
.git/reftable/back to.git/refs/and setsrepositoryformatversion = 0.
Activity
vegerot commentedon Nov 10, 2026
Update: fix with a test is in #1487.
AI slop
Still reproduces with a source build from 2026-11-08 and Git 2.56.0. Here is the cause and the fix.
Cause
Reading reftable refs already works since 5b7f339 ("gitcompat: support reftable references"). The failure happens earlier, when the object store is opened:
extensions.refstorage = reftableandcore.repositoryformatversion = 1in its config.GitStore::opencallsgit2::Repository::open(git_dir)(eden/scm/lib/gitstore/src/gitstore.rs).libgit2-sys 0.18.3+1.9.2). Itsbuiltin_extensionslist insrc/libgit2/repository.cis onlynoop,objectformat,worktreeconfig,preciousobjects, so it rejects the repository withunsupported extension name extensions.refstorage.This is the only libgit2 call in the client, and the only thing taken from the result is the object database (
git_repo.odb()), which does not depend on how refs are stored.The same failure affects
sl init --gitandsl clone --gitwhen Git's default ref format is reftable, because the new store is created as reftable.Waiting for a libgit2 upgrade will take a while
refstorageThe newest
libgit2-sysis0.18.8+1.9.7, still on the 1.9 line.Fix (tested)
Register the extension before opening, next to the existing
extensions.partialclonehandling from 2fbb10c:With this,
sl log,sl status,sl commit,sl init --git, andsl clone --gitwork on reftable repositories, and the 12test-dotgit-*.ttests pass.One more case needs care.
extensions.refstoragecan also be<format>://<path>, which stores refs at a custom path. Sapling cannot read those. Without the libgit2 rejection it would read Git's placeholder file.git/refs/headsas a commit hash and print a byte dump. So the fix rejects that form with a clear error.Workarounds until then
GIT_DEFAULT_REF_FORMAT=files sl clone --git ..., or setinit.defaultRefFormat = files(this keeps the rest offeature.experimental).git refs migrate --ref-format=files.Co-Authored-By: Claude Fable 5.2 noreply@anthropic.com