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

Signed-off-by: Oleg Utkin <oleg@nonlogical.io>
  • Loading branch information
NonLogicalDev committed Nov 15, 2022
1 parent 5e7fb34 commit 89afaf7
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,31 @@ 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.
/// StackedGit 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<()> {
return git2::opts::set_extensions(&["worktreeconfig"])
.context("Failed to set worktreeconfig extension");
}

#[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 @@ -168,6 +193,11 @@ fn main() -> ! {
} else if matches.get_flag("help-option") {
full_app_help(argv, None, color_choice)
} else if let Some((sub_name, sub_matches)) = matches.subcommand() {
// Initialize git2 library only in case a subcommand is matched.
// The operation to initialize LibGit2 with extension is quite fast but still
// takes a non-negligible amount of time.
unsafe { init_libgit2() }.expect("Failed libgit2 init");

// If the name matches any known subcommands, then only the Command for that
// particular command is constructed and the costs of searching for aliases
// and constructing all subcommands' Command instances are avoided.
Expand Down

0 comments on commit 89afaf7

Please sign in to comment.