Skip to content

Commit

Permalink
Enable basic support for worktreeconfig to unblock sparse checkout.
Browse files Browse the repository at this point in the history
`libgit2` library by default fails any operation if it encounters any
unrecognised extensions configured in a repo, as per Git documentation.

ref: https://git-scm.com/docs/repository-version

> If a version-1 repository specifies any extensions.* keys that the
> running git has not implemented, the operation MUST NOT proceed.
> Similarly, if the value of any known key is not understood by the
> implementation, the operation MUST NOT proceed.

If a repository is using a sparse checkout mode it force enables the
`worktreeconfig` extensions which allows setting configuration in repo
on a per worktree basis, to enable some of the sparse checkout
functionality.

Since `stg` is using `libgit2` library only as an interface to object
database and for looking up alias lookup from git configuration (i.e.
Read Only operation) and uses git cli for everything else, it is
relatively safe to ignore per worktree git configuration.

This patch adds `worktreeconfig` extension to the `libgit2` extension
whitelist.

CLOSES stacked-git#195
  • Loading branch information
NonLogicalDev committed Nov 15, 2022
1 parent 5e7fb34 commit b6a314d
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ strsim = "0.10"
tempfile = "3"
termcolor = "1.1"
thiserror = "~1.0"
once_cell = "~1.14"

bzip2 = { version = "0.4", optional = true }
curl = { version = "0.4", optional = true }
flate2 = { version = "1", optional = true }
tar = { version = "0.4", optional = true }

[features]
default = ["import-compressed", "import-url"]
default = ["import-compressed", "import-url", "git2-ext-worktreeconfig-support"]
import-compressed = ["dep:bzip2", "dep:flate2", "dep:tar"]
import-url = ["dep:curl"]
git2-ext-worktreeconfig-support = []
31 changes: 31 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,34 @@ const COMMAND_ERROR: i32 = 2;
/// Process exit code for when a command halts due to merge conflicts.
const CONFLICT_ERROR: i32 = 3;

/// Initialize [`git2`] library.
///
/// [`git2`] library by default fails any operation if it encounters any extensions configured in a repo.
/// [`stg`] is using [`git2`] library as an interface to object database and for looking alias lookup from git configuration.
///
/// As a workaround until `worktreeconfig` extension is supported upstream, add it to whitelisted extensions.
///
/// # Safety
/// * Modifying whitelisted extensions in [`git2`] is like modifying a static mut variable (unsafe).
/// * This function must be called at initialization time (before git2 library usage) and should be called only once.
unsafe fn init_libgit2() -> Result<()> {
if cfg!(feature = "git2-ext-worktreeconfig-support") {
return git2::opts::set_extensions(&["worktreeconfig"])
.context("Failed to set worktreeconfig extension");
}
Ok(())
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_me() {
unsafe { init_libgit2() }.expect("success");
}
}

/// Create base [`clap::Command`] instance.
///
/// The base [`clap::Command`] returned by this function is intended to be supplemented
Expand Down Expand Up @@ -138,6 +166,9 @@ pub(crate) fn get_full_command(
/// The name of the game is to dispatch to the appropriate subcommand or alias as
/// quickly as possible.
fn main() -> ! {
// Initialize git2 library.
unsafe { init_libgit2() }.expect("Failed libgit2 init");

let argv: Vec<OsString> = std::env::args_os().collect();

// Chicken and egg: the --color option must be parsed from argv in order to setup
Expand Down

1 comment on commit b6a314d

@arxanas
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Please sign in to comment.