`dotgit` mode fails on new repos with `reftable` format — `unsupported extension name extensions.refstorage`
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 = trueClone 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 = filesMigrate existing broken repos:
git refs migrate --ref-format=filesThis converts
.git/reftable/back to.git/refs/and setsrepositoryformatversion = 0.
Source: facebook/sapling