Skip to content

🧨 dotgit mode fails on new repos with reftable format β€” unsupported extension name extensions.refstorageΒ #1391

Description

@vegerot

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: ~/.gitconfig has feature.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

  1. Enable experimental features in global git config: πŸ“

    [feature]
      experimental = true
    
  2. 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/config
    

    Config shows:

    [extensions]
      refstorage = reftable
    

    And .git/reftable/ exists. .git/refs/heads does not.

  3. Run sl in repo: πŸ•ΉοΈ

    cd /tmp/reftable-test && sl status
    

    This fails with error above.

  4. Also reproduce in reporter path: πŸ”

    cd ~/code/github.com/git/git.git/ && sl status
    

πŸ”¬ Root Cause

  • Git 2.55 enables init.defaultRefFormat=reftable when feature.experimental=true. See Documentation/config/feature.adoc:16. πŸ“š

    When this flag is set, git clone and git init create repos with extensions.refstorage = reftable and store refs in .git/reftable/ tables.

  • Sapling uses libgit2 via git2 = "0.20.4" in eden/scm/lib/gitstore/Cargo.toml:24. This version does not support extensions.refstorage. git2::Repository::open in eden/scm/lib/gitstore/src/gitstore.rs:98 fails. 🧩

  • Low level ref reader in eden/scm/lib/gitcompat/src/refs.rs:141 only reads loose files under refs/ and packed-refs. It does not read reftable format. πŸ“‚

πŸ“Ž Related Code

  • eden/scm/lib/gitstore/src/gitstore.rs:98 - opens repo with libgit2
  • eden/scm/lib/gitstore/Cargo.toml:24 - git2 = "0.20.4"
  • eden/scm/lib/gitcompat/src/refs.rs:141 - populate_packed_references
  • eden/scm/lib/gitcompat/src/refs.rs:210 - populate_loose_directory_references

πŸ“ˆ Impact

  • Any user with feature.experimental=true (or explicit init.defaultRefFormat=reftable) gets new clones that do not work with sl.
  • feature.experimental is popular. Git will likely make reftable default in future. Impact will grow. ⚠️

πŸ› οΈ Suggested Fix

  1. Update libgit2 to version that supports reftable. Check if libgit2 main branch already supports reftable. ⬆️

  2. Update gitcompat/src/refs.rs to support reftable backend:

    • Option A: shell out to git refs / git for-each-ref / git show-ref for ref list. Then Sapling uses Git binary which supports reftable. πŸ”§
    • Option B: add reftable parser in Rust, or use gitoxide which supports reftable. πŸ¦€
  3. Alternatively, detect reftable and show clear error with migration hint. πŸ’‘

βœ… Workaround For Users

Until fix is available:

  • Force files format for new repos. Add to ~/.gitconfig: πŸ”§

    [init]
      defaultRefFormat = files
    
  • Migrate existing broken repos: πŸš‘

    git refs migrate --ref-format=files
    

    This converts .git/reftable/ back to .git/refs/ and sets repositoryformatversion = 0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions