From da9c98d0c2b1527371e9ada0cf6f0f28835a4ea3 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 17 Jun 2025 20:07:41 -0700 Subject: [PATCH 1/3] Make url optional via a new "cred" feature gate for credential helpers Add an enabled-by-default feature flag for credential helpers, which are the only uses of the `url` crate. This reduces a `default-features = false` build of git2 from 54 dependencies to 17, for a configuration that many tools (e.g. anything that only cares about local repositories) can happily use. In addition to enabling it by default, make the "https" and "ssh" features depend on "cred". --- Cargo.toml | 11 +++++++---- src/cred.rs | 26 +++++++++++++++++--------- src/lib.rs | 4 +++- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 02b4ddea8e..220e7d2d6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ categories = ["api-bindings"] edition = "2018" [dependencies] -url = "2.5.4" +url = { version = "2.5.4", optional = true } bitflags = "2.1.0" libc = "0.2" log = "0.4.8" @@ -30,12 +30,15 @@ openssl-probe = { version = "0.1", optional = true } clap = { version = "4.4.13", features = ["derive"] } time = { version = "0.3.37", features = ["formatting"] } tempfile = "3.1.0" +url = "2.5.4" [features] unstable = [] -default = ["ssh", "https"] -ssh = ["libgit2-sys/ssh"] -https = ["libgit2-sys/https", "openssl-sys", "openssl-probe"] +default = ["ssh", "https", "cred"] +ssh = ["libgit2-sys/ssh", "cred"] +https = ["libgit2-sys/https", "openssl-sys", "openssl-probe", "cred"] +# Include support for credentials, which pulls in the `url` crate and all its dependencies +cred = ["dep:url"] vendored-libgit2 = ["libgit2-sys/vendored"] vendored-openssl = ["openssl-sys/vendored", "libgit2-sys/vendored-openssl"] zlib-ng-compat = ["libgit2-sys/zlib-ng-compat"] diff --git a/src/cred.rs b/src/cred.rs index 3def56ab6e..adf621b5d8 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -1,13 +1,14 @@ +#[cfg(feature = "cred")] use log::{debug, trace}; use std::ffi::CString; -use std::io::Write; use std::mem; use std::path::Path; -use std::process::{Command, Stdio}; use std::ptr; use crate::util::Binding; -use crate::{raw, Config, Error, IntoCString}; +#[cfg(feature = "cred")] +use crate::Config; +use crate::{raw, Error, IntoCString}; /// A structure to represent git credentials in libgit2. pub struct Cred { @@ -15,6 +16,7 @@ pub struct Cred { } /// Management of the gitcredentials(7) interface. +#[cfg(feature = "cred")] pub struct CredentialHelper { /// A public field representing the currently discovered username from /// configuration. @@ -118,6 +120,7 @@ impl Cred { /// successful. /// /// [1]: https://www.kernel.org/pub/software/scm/git/docs/gitcredentials.html + #[cfg(feature = "cred")] pub fn credential_helper( config: &Config, url: &str, @@ -189,6 +192,7 @@ impl Drop for Cred { } } +#[cfg(feature = "cred")] impl CredentialHelper { /// Create a new credential helper object which will be used to probe git's /// local credential configuration. @@ -292,6 +296,12 @@ impl CredentialHelper { // see https://www.kernel.org/pub/software/scm/git/docs/technical // /api-credentials.html#_credential_helpers fn add_command(&mut self, cmd: Option<&str>) { + fn is_absolute_path(path: &str) -> bool { + path.starts_with('/') + || path.starts_with('\\') + || cfg!(windows) && path.chars().nth(1).is_some_and(|x| x == ':') + } + let cmd = match cmd { Some("") | None => return, Some(s) => s, @@ -352,6 +362,9 @@ impl CredentialHelper { cmd: &str, username: &Option, ) -> (Option, Option) { + use std::io::Write; + use std::process::{Command, Stdio}; + macro_rules! my_try( ($e:expr) => ( match $e { Ok(e) => e, @@ -481,13 +494,8 @@ impl CredentialHelper { } } -fn is_absolute_path(path: &str) -> bool { - path.starts_with('/') - || path.starts_with('\\') - || cfg!(windows) && path.chars().nth(1).is_some_and(|x| x == ':') -} - #[cfg(test)] +#[cfg(feature = "cred")] mod test { use std::env; use std::fs::File; diff --git a/src/lib.rs b/src/lib.rs index 28f0887b82..62f4362f18 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,7 +88,9 @@ pub use crate::buf::Buf; pub use crate::cherrypick::CherrypickOptions; pub use crate::commit::{Commit, Parents}; pub use crate::config::{Config, ConfigEntries, ConfigEntry}; -pub use crate::cred::{Cred, CredentialHelper}; +pub use crate::cred::Cred; +#[cfg(feature = "cred")] +pub use crate::cred::CredentialHelper; pub use crate::describe::{Describe, DescribeFormatOptions, DescribeOptions}; pub use crate::diff::{Deltas, Diff, DiffDelta, DiffFile, DiffOptions}; pub use crate::diff::{DiffBinary, DiffBinaryFile, DiffBinaryKind, DiffPatchidOptions}; From 03ef1a7acde773b662f772fe66091b54acc92400 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 10 Aug 2025 17:59:31 -0700 Subject: [PATCH 2/3] Stop enabling "ssh", "https", and "cred" by default Many users of the git2 crate want to operate exclusively on local repositories, but if they don't use `default-features = false` they'll get a large set of additional dependencies they don't need. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 220e7d2d6d..05de72bcce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ url = "2.5.4" [features] unstable = [] -default = ["ssh", "https", "cred"] +default = [] ssh = ["libgit2-sys/ssh", "cred"] https = ["libgit2-sys/https", "openssl-sys", "openssl-probe", "cred"] # Include support for credentials, which pulls in the `url` crate and all its dependencies From 875a4cca7e229f5fe10f992d9ac6b96a011630fd Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 10 Aug 2025 17:58:24 -0700 Subject: [PATCH 3/3] Bump git2 to 0.21.0 due to change in default feature flags --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 2 +- git2-curl/Cargo.toml | 4 ++-- src/lib.rs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1d4d2f2fc2..62d096c5ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -357,7 +357,7 @@ dependencies = [ [[package]] name = "git2" -version = "0.20.2" +version = "0.21.0" dependencies = [ "bitflags 2.6.0", "clap", diff --git a/Cargo.toml b/Cargo.toml index 05de72bcce..16d1da36d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "git2" -version = "0.20.2" +version = "0.21.0" authors = ["Josh Triplett ", "Alex Crichton "] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/README.md b/README.md index b96234a095..ca00ad9672 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ libgit2 bindings for Rust. ```toml [dependencies] -git2 = "0.20.2" +git2 = "0.21" ``` ## Rust version requirements diff --git a/git2-curl/Cargo.toml b/git2-curl/Cargo.toml index fad60e2755..5d90885f18 100644 --- a/git2-curl/Cargo.toml +++ b/git2-curl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "git2-curl" -version = "0.21.0" +version = "0.22.0" authors = ["Josh Triplett ", "Alex Crichton "] license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/git2-rs" @@ -16,7 +16,7 @@ edition = "2018" curl = "0.4.33" url = "2.5.4" log = "0.4" -git2 = { path = "..", version = "0.20", default-features = false } +git2 = { path = "..", version = "0.21", default-features = false } [dev-dependencies] civet = "0.11" diff --git a/src/lib.rs b/src/lib.rs index 62f4362f18..ca96b06cd8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,7 +65,7 @@ //! source `Repository`, to ensure that they do not outlive the repository //! itself. -#![doc(html_root_url = "https://docs.rs/git2/0.20")] +#![doc(html_root_url = "https://docs.rs/git2/0.21")] #![allow(trivial_numeric_casts, trivial_casts)] #![deny(missing_docs)] #![warn(rust_2018_idioms)]