Skip to content

Commit fc39be5

Browse files
NonLogicalDevjpgrayson
authored andcommitted
Enable basic support for worktreeconfig to unblock sparse checkout.
`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 #195 Signed-off-by: Oleg Utkin <[email protected]>
1 parent 5e7fb34 commit fc39be5

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

src/main.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,31 @@ const COMMAND_ERROR: i32 = 2;
4242
/// Process exit code for when a command halts due to merge conflicts.
4343
const CONFLICT_ERROR: i32 = 3;
4444

45+
/// Initialize [`git2`] library.
46+
///
47+
/// [`git2`] library by default fails any operation if it encounters any extensions configured in a repo.
48+
/// StackedGit is using [`git2`] library as an interface to object database and for looking alias lookup from git configuration.
49+
///
50+
/// As a workaround until `worktreeconfig` extension is supported upstream, add it to whitelisted extensions.
51+
///
52+
/// # Safety
53+
/// * Modifying whitelisted extensions in [`git2`] is like modifying a static mut variable (unsafe).
54+
/// * This function must be called at initialization time (before git2 library usage) and should be called only once.
55+
unsafe fn init_libgit2() -> Result<()> {
56+
git2::opts::set_extensions(&["worktreeconfig"])
57+
.context("Failed to set worktreeconfig extension")
58+
}
59+
60+
#[cfg(test)]
61+
mod test {
62+
use super::*;
63+
64+
#[test]
65+
fn test_me() {
66+
unsafe { init_libgit2() }.expect("success");
67+
}
68+
}
69+
4570
/// Create base [`clap::Command`] instance.
4671
///
4772
/// The base [`clap::Command`] returned by this function is intended to be supplemented
@@ -168,6 +193,11 @@ fn main() -> ! {
168193
} else if matches.get_flag("help-option") {
169194
full_app_help(argv, None, color_choice)
170195
} else if let Some((sub_name, sub_matches)) = matches.subcommand() {
196+
// Initialize git2 library only in case a subcommand is matched.
197+
// The operation to initialize LibGit2 with extension is quite fast but still
198+
// takes a non-negligible amount of time.
199+
unsafe { init_libgit2() }.expect("Failed libgit2 init");
200+
171201
// If the name matches any known subcommands, then only the Command for that
172202
// particular command is constructed and the costs of searching for aliases
173203
// and constructing all subcommands' Command instances are avoided.

0 commit comments

Comments
 (0)