Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions eden/scm/lib/gitstore/src/gitstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ impl GitStore {
/// `open` a Git bare repo at `git_dir`. Gain access to its odb (object database).
pub fn open(git_dir: &Path, config: &dyn Config) -> Result<Self> {
let mut git = BareGit::from_git_dir_and_config(git_dir.to_owned(), config);
// libgit2 < 2.0 rejects reftable repos ("unsupported extension name
// extensions.refstorage"). GitStore only uses libgit2 for the odb. References
// are read by gitcompat, which supports reftable. So tolerating the extension
// is enough.
// SAFETY: This sets a libgit2 global. Every caller sets the same value.
unsafe { git2::opts::set_extensions(&["refstorage"])? };
let git_repo = match git2::Repository::open(git_dir) {
Ok(repo) => repo,
Err(err) if err.message() == "unsupported extension name extensions.partialclone" => {
Expand Down Expand Up @@ -135,6 +141,15 @@ impl GitStore {
}
Err(err) => return Err(err.into()),
};
// "<format>://<path>" stores references at a custom path. gitcompat cannot
// read those, so keep rejecting them, like libgit2 did.
if let Ok(value) = git_repo.config()?.get_string("extensions.refstorage") {
if value.contains("://") {
anyhow::bail!(
"Git references stored at a custom path are not supported (extensions.refstorage = {value:?})"
);
}
}
let odb = git_repo.odb()?;

// Git's negotiation algorithm works on commit reference level and can add significant
Expand Down
21 changes: 21 additions & 0 deletions eden/scm/tests/test-dotgit-reftable.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#require git no-eden no-windows

$ . $TESTDIR/git.sh
$ git init -q -b main --ref-format=reftable repo
$ cd repo
$ echo first > a
$ git add a
$ git commit -q -m first

Read a repo that stores references in the reftable format.

$ sl log -T '{desc}\n'
first

Write a commit that Git can read.

$ echo second > a
$ sl commit -q -m second
$ git log --format=%s
second
first
Loading