From 4924fc693035dc01065747cb1bfe43f00fe4d22a Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 14:43:21 -0700 Subject: [PATCH 01/75] [Clippy] Address `clippy::missing_safety_doc` in src/apply.rs Add safety documentation for `ApplyOptions::raw()` regarding using the raw pointer. --- src/apply.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/apply.rs b/src/apply.rs index 406e96286f..63455ee3f4 100644 --- a/src/apply.rs +++ b/src/apply.rs @@ -1,7 +1,6 @@ //! git_apply support //! see original: -#![allow(clippy::missing_safety_doc)] #![allow(clippy::new_without_default)] use crate::{panic, raw, util::Binding, DiffDelta, DiffHunk}; @@ -146,6 +145,11 @@ impl<'cb> ApplyOptions<'cb> { } /// Pointer to a raw git_stash_apply_options + /// + /// # Safety + /// + /// The provided pointer must not be used to manipulate the options, and + /// must not outlive the [`ApplyOptions`] instance. pub unsafe fn raw(&mut self) -> *const raw::git_apply_options { &self.raw as *const _ } From 2acbfb720b82a53f7ab18b15750cc894eb4432a4 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 14:46:08 -0700 Subject: [PATCH 02/75] [Clippy] Address `clippy::new_without_default` in src/apply.rs Add an implementation of the `Default` trait for `ApplyOptions` that delegates to `ApplyOptions::new()`. --- src/apply.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/apply.rs b/src/apply.rs index 63455ee3f4..e3202fb7e0 100644 --- a/src/apply.rs +++ b/src/apply.rs @@ -1,8 +1,6 @@ //! git_apply support //! see original: -#![allow(clippy::new_without_default)] - use crate::{panic, raw, util::Binding, DiffDelta, DiffHunk}; use libc::c_int; use std::{ffi::c_void, mem}; @@ -155,6 +153,13 @@ impl<'cb> ApplyOptions<'cb> { } } +impl<'cb> Default for ApplyOptions<'cb> { + /// Creates a new set of empty options (zeroed). + fn default() -> Self { + Self::new() + } +} + #[cfg(test)] #[allow(clippy::needless_borrows_for_generic_args)] mod tests { From 8d2f95610df3d126b601e359d22fadac9680413d Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 14:47:59 -0700 Subject: [PATCH 03/75] [Clippy] Address `clippy::redundant_closure` in src/blame.rs Simplify `BlameHunk::summary()` to use the tuple variant `Some` rather than using a closure. --- src/blame.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/blame.rs b/src/blame.rs index 3bd4aeace2..40870f6256 100644 --- a/src/blame.rs +++ b/src/blame.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use crate::util::{self, Binding}; use crate::{raw, signature, Error, ErrorClass, ErrorCode, Oid, Repository, Signature}; use libc::c_char; @@ -222,7 +220,7 @@ impl<'blame> BlameHunk<'blame> { /// `Ok(None)` may be returned if there is no summary. pub fn summary(&self) -> Result, Error> { match self.summary_bytes() { - Some(sb) => str::from_utf8(sb).map(|s| Some(s)).map_err(|e| e.into()), + Some(sb) => str::from_utf8(sb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From d39ed7b2672e539ff7ebff650c9bdca7924bce76 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 14:50:59 -0700 Subject: [PATCH 04/75] [Clippy] Address `clippy::io_other_error` in src/blob.rs In the `std::io::Write` trait implementation for `BlobWriter`, use the helper function `std::io::Error::other()` for constructing an `std::io::Error` of kind `std::io::ErrorKind::other`. --- src/blob.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/blob.rs b/src/blob.rs index c73862ddd9..3d605739f0 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -1,5 +1,3 @@ -#![allow(clippy::io_other_error)] - use std::io; use std::marker; use std::mem; @@ -139,12 +137,12 @@ impl<'repo> io::Write for BlobWriter<'repo> { if let Some(f) = write_cb { let res = f(self.raw, buf.as_ptr() as *const _, buf.len()); if res < 0 { - Err(io::Error::new(io::ErrorKind::Other, "Write error")) + Err(io::Error::other("Write error")) } else { Ok(buf.len()) } } else { - Err(io::Error::new(io::ErrorKind::Other, "no write callback")) + Err(io::Error::other("no write callback")) } } fn flush(&mut self) -> io::Result<()> { From b6ea28bad1e64a05b9c6a71571697dd0ae0b2db0 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 14:52:40 -0700 Subject: [PATCH 05/75] [Clippy] Address `clippy::missing_safety_doc` in src/branch.rs Add the missing `# Safety` heading to the existing safety documentation for `Branches::from_raw()` and expand that documentation. --- src/branch.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/branch.rs b/src/branch.rs index ffcccecfb6..1d5cf767c5 100644 --- a/src/branch.rs +++ b/src/branch.rs @@ -1,5 +1,3 @@ -#![allow(clippy::missing_safety_doc)] - use std::ffi::CString; use std::marker; use std::ptr; @@ -129,8 +127,11 @@ impl<'repo> Branch<'repo> { impl<'repo> Branches<'repo> { /// Creates a new iterator from the raw pointer given. /// + /// # Safety + /// /// This function is unsafe as it is not guaranteed that `raw` is a valid - /// pointer. + /// pointer. The caller must ensure that `raw` is a valid pointer and lives + /// as long as the [`Branches`] object. pub unsafe fn from_raw(raw: *mut raw::git_branch_iterator) -> Branches<'repo> { Branches { raw, From 6278c613f981b8ef228e852e7208d96fccc2bfb3 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 14:54:43 -0700 Subject: [PATCH 06/75] [Clippy] Address `clippy::explicit_auto_deref` in src/buf.rs Remove the explicit dereferencing in `Buf::as_str()`. --- src/buf.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/buf.rs b/src/buf.rs index 754fd93ad5..904ee6e21d 100644 --- a/src/buf.rs +++ b/src/buf.rs @@ -1,5 +1,3 @@ -#![allow(clippy::explicit_auto_deref)] - use std::ops::{Deref, DerefMut}; use std::ptr; use std::slice; @@ -38,7 +36,7 @@ impl Buf { /// Attempt to view this buffer as a string slice. pub fn as_str(&self) -> Result<&str, Error> { - str::from_utf8(&**self).map_err(|e| e.into()) + str::from_utf8(self).map_err(|e| e.into()) } } @@ -78,6 +76,7 @@ impl Drop for Buf { } #[test] +#[allow(clippy::explicit_auto_deref)] fn empty_buf() { let mut buf = Buf::new(); let x: &[u8] = &*buf; From b2e185069ab139848be8508d740899ee9c3f9a94 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 14:59:05 -0700 Subject: [PATCH 07/75] [Clippy] Address `clippy::manual_non_exhaustive` in src/build.rs Mark the `CloneLocal` enum as `#[non_exhaustive]` and remove the hidden `__Nonexhaustive` variant. Based on the libgit2 documentation of the `git_clone_local_t` type the `__Nonexhaustive` was not something that the upstream library used as an actual value. --- src/build.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/build.rs b/src/build.rs index 0b27006718..1730e24a91 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,6 +1,5 @@ //! Builder-pattern objects for configuration various git operations. -#![allow(clippy::manual_non_exhaustive)] #![allow(clippy::missing_safety_doc)] use libc::{c_char, c_int, c_uint, c_void, size_t}; @@ -128,6 +127,7 @@ impl<'cb> Default for RepoBuilder<'cb> { /// Options that can be passed to `RepoBuilder::clone_local`. #[derive(Clone, Copy)] +#[non_exhaustive] pub enum CloneLocal { /// Auto-detect (default) /// @@ -143,9 +143,6 @@ pub enum CloneLocal { /// Bypass the git-aware transport, but don't try to use hardlinks. NoLinks = raw::GIT_CLONE_LOCAL_NO_LINKS as isize, - - #[doc(hidden)] - __Nonexhaustive = 0xff, } impl<'cb> RepoBuilder<'cb> { From e2a575527addfc1d17a3eb206029d30d7d137d45 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:04:53 -0700 Subject: [PATCH 08/75] [Clippy] Address `clippy::missing_safety_doc` in src/build.rs Add the missing `# Safety` heading to the existing safety documentation for `CheckoutBuilder::configure()` and expand that documentation. --- src/build.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/build.rs b/src/build.rs index 1730e24a91..09c6838251 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,7 +1,5 @@ //! Builder-pattern objects for configuration various git operations. -#![allow(clippy::missing_safety_doc)] - use libc::{c_char, c_int, c_uint, c_void, size_t}; use std::ffi::{CStr, CString}; use std::mem; @@ -590,8 +588,14 @@ impl<'cb> CheckoutBuilder<'cb> { /// Configure a raw checkout options based on this configuration. /// + /// # Safety + /// /// This method is unsafe as there is no guarantee that this structure will - /// outlive the provided checkout options. + /// outlive the provided checkout options. The caller must ensure that + /// `opts` does not outlive the [`CheckoutBuilder`], and also that for any + /// fields configured in the `CheckoutBuilder` that are provided to the + /// `opts` as pointers, those pointers are not used if the original + /// references held in the `CheckoutBuilder` are dropped. pub unsafe fn configure(&mut self, opts: &mut raw::git_checkout_options) { opts.version = raw::GIT_CHECKOUT_OPTIONS_VERSION; opts.disable_filters = self.disable_filters as c_int; From 95fab73ac484901281aedbab4fb62cbf53687285 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:07:10 -0700 Subject: [PATCH 09/75] [Clippy] Address `clippy::needless_lifetimes` in src/call.rs Remove needless lifetimes from the implementation of the `Convert` trait for - converting references (`&T`) to constant pointers (`*const T`) - converting mutable references (`&mut T`) to mutable pointers (`*mut T`) --- src/call.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/call.rs b/src/call.rs index 210d5e3409..1a757b97ac 100644 --- a/src/call.rs +++ b/src/call.rs @@ -1,4 +1,3 @@ -#![allow(clippy::needless_lifetimes)] #![macro_use] use crate::Error; @@ -69,12 +68,12 @@ mod impls { *self as libc::c_int } } - impl<'a, T> Convert<*const T> for &'a T { + impl Convert<*const T> for &T { fn convert(&self) -> *const T { *self as *const T } } - impl<'a, T> Convert<*mut T> for &'a mut T { + impl Convert<*mut T> for &mut T { fn convert(&self) -> *mut T { &**self as *const T as *mut T } From 5843bacb91da06a78d20dc7b55bd56b072c412ca Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:09:25 -0700 Subject: [PATCH 10/75] [Clippy] Address `clippy::new_without_default` in src/cherrypick.rs Add an implementation of the `Default` trait for `CherrypickOptions` that delegates to `CherrypickOptions::new()`. --- src/cherrypick.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cherrypick.rs b/src/cherrypick.rs index 81e11e94a2..3496cf7d3c 100644 --- a/src/cherrypick.rs +++ b/src/cherrypick.rs @@ -1,5 +1,3 @@ -#![allow(clippy::new_without_default)] - use std::mem; use crate::build::CheckoutBuilder; @@ -78,3 +76,10 @@ impl<'cb> CherrypickOptions<'cb> { cherrypick_opts } } + +impl<'cb> Default for CherrypickOptions<'cb> { + /// Creates a default set of cherrypick options + fn default() -> Self { + Self::new() + } +} From a9aaab1949df0f5855caa608b607460898af070e Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:11:29 -0700 Subject: [PATCH 11/75] [Clippy] Address `clippy::redundant_closure` in src/commit.rs Simplify a few methods to use the tuple variant `Some` rather than using a closure: - `Commit::message_encoding()` - `Commit::summary()` - `Commit::body()` --- src/commit.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/commit.rs b/src/commit.rs index 7acaaddbc3..fb1ef1363d 100644 --- a/src/commit.rs +++ b/src/commit.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use std::iter::FusedIterator; use std::marker; use std::mem; @@ -84,7 +82,7 @@ impl<'repo> Commit<'repo> { pub fn message_encoding(&self) -> Result, Error> { let bytes = unsafe { crate::opt_bytes(self, raw::git_commit_message_encoding(&*self.raw)) }; match bytes { - Some(b) => str::from_utf8(b).map(|s| Some(s)).map_err(|e| e.into()), + Some(b) => str::from_utf8(b).map(Some).map_err(|e| e.into()), None => Ok(None), } } @@ -131,7 +129,7 @@ impl<'repo> Commit<'repo> { /// `Ok(None)` may be returned if there is no summary pub fn summary(&self) -> Result, Error> { match self.summary_bytes() { - Some(sb) => str::from_utf8(sb).map(|s| Some(s)).map_err(|e| e.into()), + Some(sb) => str::from_utf8(sb).map(Some).map_err(|e| e.into()), None => Ok(None), } } @@ -155,7 +153,7 @@ impl<'repo> Commit<'repo> { /// `Ok(None)` may be returned if there is no body. pub fn body(&self) -> Result, Error> { match self.body_bytes() { - Some(sb) => str::from_utf8(sb).map(|s| Some(s)).map_err(|e| e.into()), + Some(sb) => str::from_utf8(sb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From 604553a40557b7d2243918478e8cce3778beccab Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:21:54 -0700 Subject: [PATCH 12/75] [Clippy] Address `clippy::should_implement_trait` in src/config.rs Because the method with the confusing name (`ConfigEntries::next()`) is part of the public API of the crate, simply move the lint handling to that method with an `#[expect]` attribute. Doing so avoids breaking changes while also removing the `#![allow]` from the overall module, ensuring that new functions do not have confusing names. --- src/config.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index f4ab82dd64..189fc6deac 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,3 @@ -#![allow(clippy::should_implement_trait)] - use std::ffi::CString; use std::marker; use std::path::{Path, PathBuf}; @@ -601,6 +599,7 @@ impl<'cfg> ConfigEntries<'cfg> { /// Advances the iterator and returns the next value. /// /// Returns `None` when iteration is finished. + #[expect(clippy::should_implement_trait)] pub fn next(&mut self) -> Option, Error>> { let mut raw = ptr::null_mut(); drop(self.current.take()); From 700a9cda7ebfda9678eed4cb731da940572864c5 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:39:51 -0700 Subject: [PATCH 13/75] [Clippy] Address `clippy::manual_strip` in src/cred.rs Simplify `CredentialHelper::add_command()` using `str::strip_prefix()`. --- src/cred.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cred.rs b/src/cred.rs index 999570fdaa..95e0d029d4 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -1,4 +1,3 @@ -#![allow(clippy::manual_strip)] #![allow(clippy::match_result_ok)] #![allow(clippy::missing_safety_doc)] #![allow(clippy::needless_borrowed_reference)] @@ -313,8 +312,8 @@ impl CredentialHelper { Some(s) => s, }; - if cmd.starts_with('!') { - self.commands.push(cmd[1..].to_string()); + if let Some(stripped) = cmd.strip_prefix('!') { + self.commands.push(stripped.to_string()); } else if is_absolute_path(cmd) { self.commands.push(cmd.to_string()); } else { From 493cd2f9e19ffbb9a9374d83f6cbb798bcc9aa0f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:43:35 -0700 Subject: [PATCH 14/75] [Clippy] Address `clippy::match_result_ok` in src/cred.rs Simplify `CredentialHelper::config_use_http_path()` by using if-let expressions with `Results` rather than calling `Result::ok()` and matching against the resulting `Option`. --- src/cred.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cred.rs b/src/cred.rs index 95e0d029d4..7257fbc05c 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -1,4 +1,3 @@ -#![allow(clippy::match_result_ok)] #![allow(clippy::missing_safety_doc)] #![allow(clippy::needless_borrowed_reference)] #![allow(clippy::needless_borrows_for_generic_args)] @@ -276,14 +275,14 @@ impl CredentialHelper { // Discover `useHttpPath` from `config` fn config_use_http_path(&mut self, config: &Config) { let mut use_http_path = false; - if let Some(value) = config.get_bool(&self.exact_key("useHttpPath")).ok() { + if let Ok(value) = config.get_bool(&self.exact_key("useHttpPath")) { use_http_path = value; } else if let Some(value) = self .url_key("useHttpPath") .and_then(|key| config.get_bool(&key).ok()) { use_http_path = value; - } else if let Some(value) = config.get_bool("credential.useHttpPath").ok() { + } else if let Ok(value) = config.get_bool("credential.useHttpPath") { use_http_path = value; } From 2f79fcecb45265dae48d272422d6dd54775f135f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:45:27 -0700 Subject: [PATCH 15/75] [Clippy] Address `clippy::missing_safety_doc` in src/cred.rs Add safety documentation for `Cred::unwrap()`. --- src/cred.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cred.rs b/src/cred.rs index 7257fbc05c..9a4ff991fd 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -1,4 +1,3 @@ -#![allow(clippy::missing_safety_doc)] #![allow(clippy::needless_borrowed_reference)] #![allow(clippy::needless_borrows_for_generic_args)] #![allow(clippy::should_implement_trait)] @@ -169,6 +168,11 @@ impl Cred { } /// Unwrap access to the underlying raw pointer, canceling the destructor + /// + /// # Safety + /// + /// The caller must assume responsibility for freeing the credential if + /// needed. See the drop implementation for guidance. pub unsafe fn unwrap(mut self) -> *mut raw::git_cred { mem::replace(&mut self.raw, ptr::null_mut()) } From f96b066a0e90e88e02842b1e53f0714710ba775f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:46:38 -0700 Subject: [PATCH 16/75] [Clippy] Address `clippy::needless_borrowed_reference` in src/cred.rs Simplify `CredentialHelper::url_key()` to avoid needless borrows. --- src/cred.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cred.rs b/src/cred.rs index 9a4ff991fd..c9c546c450 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -1,4 +1,3 @@ -#![allow(clippy::needless_borrowed_reference)] #![allow(clippy::needless_borrows_for_generic_args)] #![allow(clippy::should_implement_trait)] @@ -330,7 +329,7 @@ impl CredentialHelper { fn url_key(&self, name: &str) -> Option { match (&self.host, &self.protocol) { - (&Some(ref host), &Some(ref protocol)) => { + (Some(host), Some(protocol)) => { Some(format!("credential.{}://{}.{}", protocol, host, name)) } _ => None, From 4a235baf8783c74dfb9c67be99eece4cb0a509ea Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:47:28 -0700 Subject: [PATCH 17/75] [Clippy] Address `clippy::needless_borrows_for_generic_args` in src/cred.rs Simplify `CredentialHelper::execute_cmd()` to avoid a needless borrow. --- src/cred.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cred.rs b/src/cred.rs index c9c546c450..a453cdbf2f 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -1,4 +1,3 @@ -#![allow(clippy::needless_borrows_for_generic_args)] #![allow(clippy::should_implement_trait)] #[cfg(feature = "cred")] @@ -399,7 +398,7 @@ impl CredentialHelper { c.creation_flags(CREATE_NO_WINDOW); } c.arg("-c") - .arg(&format!("{} get", cmd)) + .arg(format!("{} get", cmd)) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()); @@ -503,6 +502,7 @@ impl CredentialHelper { #[cfg(test)] #[cfg(feature = "cred")] +#[allow(clippy::needless_borrows_for_generic_args)] #[allow(clippy::unused_io_amount)] #[allow(clippy::useless_conversion)] mod test { From 889d37db463c09c3b3b5ab25ae6c0a84409e5d1d Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:48:12 -0700 Subject: [PATCH 18/75] [Clippy] Address `clippy::should_implement_trait` in src/cred.rs Because the method with the confusing name (`Cred::default()`) is part of the public API of the crate, simply move the lint handling to that method with an `#[expect]` attribute. Doing so avoids breaking changes while also removing the `#![allow]` from the overall module, ensuring that new functions do not have confusing names. --- src/cred.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cred.rs b/src/cred.rs index a453cdbf2f..07f78ef658 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -1,5 +1,3 @@ -#![allow(clippy::should_implement_trait)] - #[cfg(feature = "cred")] use log::{debug, trace}; use std::ffi::CString; @@ -34,6 +32,7 @@ pub struct CredentialHelper { impl Cred { /// Create a "default" credential usable for Negotiate mechanisms like NTLM /// or Kerberos authentication. + #[expect(clippy::should_implement_trait)] pub fn default() -> Result { crate::init(); let mut out = ptr::null_mut(); From bba606e3733fc57683ba275d7d8000dca61f38ca Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:53:36 -0700 Subject: [PATCH 19/75] [Clippy] Address `clippy::empty_docs` in src/diff.rs Add actual documentation to the `Addition`, `Deletion`, and `HunkHeader` variants of the `DiffLineType` enum. --- src/diff.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/diff.rs b/src/diff.rs index 6583f13e7b..d792eb6595 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -1,4 +1,3 @@ -#![allow(clippy::empty_docs)] #![allow(clippy::missing_safety_doc)] #![allow(clippy::new_without_default)] @@ -1000,9 +999,9 @@ impl<'diff> ExactSizeIterator for Deltas<'diff> {} pub enum DiffLineType { /// These values will be sent to `git_diff_line_cb` along with the line Context, - /// + /// Line was added Addition, - /// + /// Line was removed Deletion, /// Both files have no LF at end ContextEOFNL, @@ -1013,7 +1012,7 @@ pub enum DiffLineType { /// The following values will only be sent to a `git_diff_line_cb` when /// the content of a diff is being formatted through `git_diff_print`. FileHeader, - /// + /// Line represents the header of a hunk, e.g. "@@ -1,2 +0,0 @@\n" HunkHeader, /// For "Binary files x and y differ" Binary, From d7f490069293d251250892841c4c44470914749a Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:56:09 -0700 Subject: [PATCH 20/75] [Clippy] Address `clippy::missing_safety_doc` in src/diff.rs Add the missing `# Safety` heading to the existing safety documentation for `DiffOptions::raw()`. Add safety documentation for `DiffFindOptions::raw()`. --- src/diff.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/diff.rs b/src/diff.rs index d792eb6595..9c3fe759a6 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -1,4 +1,3 @@ -#![allow(clippy::missing_safety_doc)] #![allow(clippy::new_without_default)] use libc::{c_char, c_int, c_void, size_t}; @@ -955,6 +954,8 @@ impl DiffOptions { /// Acquire a pointer to the underlying raw options. /// + /// # Safety + /// /// This function is unsafe as the pointer is only valid so long as this /// structure is not moved, modified, or used elsewhere. pub unsafe fn raw(&mut self) -> *const raw::git_diff_options { @@ -1528,6 +1529,11 @@ impl DiffFindOptions { // TODO: expose git_diff_similarity_metric /// Acquire a pointer to the underlying raw options. + /// + /// # Safety + /// + /// The provided pointer must not be used to manipulate the options, and + /// must not outlive the [`DiffFindOptions`] instance. pub unsafe fn raw(&mut self) -> *const raw::git_diff_find_options { &self.raw } From 894770cc7c88e2a1977ecae1e66fb643002ed773 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 15:59:00 -0700 Subject: [PATCH 21/75] [Clippy] Address `clippy::new_without_default` in src/diff.rs Add an implementation of the `Default` trait for `DiffPatchidOptions` that delegates to `DiffPatchidOptions::new()`. --- src/diff.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/diff.rs b/src/diff.rs index 9c3fe759a6..d1eda4f4fc 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -1,5 +1,3 @@ -#![allow(clippy::new_without_default)] - use libc::{c_char, c_int, c_void, size_t}; use std::ffi::CString; use std::iter::FusedIterator; @@ -1597,6 +1595,14 @@ impl DiffPatchidOptions { } } +impl Default for DiffPatchidOptions { + /// Creates a new set of patchid options, + /// initialized to the default values + fn default() -> Self { + Self::new() + } +} + #[cfg(test)] #[allow(clippy::assign_op_pattern)] #[allow(clippy::needless_borrows_for_generic_args)] From 2ba47af2d185ea56f546c64130eee3f84ae5d3f5 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:01:50 -0700 Subject: [PATCH 22/75] [Clippy] Address `clippy::too_many_arguments` in src/email.rs Because the method that accepts too many arguments (`Email::from_diff()`) is part of the public API of the crate, simply move the lint handling to that method with an `#[expect]` attribute. Doing so avoids breaking changes while also removing the `#![allow]` from the overall module, ensuring that new functions do not have too many arguments. --- src/email.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/email.rs b/src/email.rs index 14218b06d7..4f87e056f1 100644 --- a/src/email.rs +++ b/src/email.rs @@ -1,5 +1,3 @@ -#![allow(clippy::too_many_arguments)] - use std::ffi::CString; use std::{mem, ptr}; @@ -140,6 +138,7 @@ impl Email { } /// Create a diff for a commit in mbox format for sending via email. + #[expect(clippy::too_many_arguments)] pub fn from_diff( diff: &Diff<'_>, patch_idx: usize, From 4a7521ac0beadcb669046ce71356d4a93cc9b15f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:02:29 -0700 Subject: [PATCH 23/75] [Clippy] Address `clippy::should_implement_trait` in src/error.rs Because the method with the confusing name (`Error::from_str()`) is part of the public API of the crate, simply move the lint handling to that method with an `#[expect]` attribute. Doing so avoids breaking changes while also removing the `#![allow]` from the overall module, ensuring that new functions do not have confusing names. --- src/error.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/error.rs b/src/error.rs index ba4d3afb8f..20f3c17dea 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,3 @@ -#![allow(clippy::should_implement_trait)] - use libc::c_int; use std::env::JoinPathsError; use std::error; @@ -77,6 +75,7 @@ impl Error { /// /// The error returned will have the code `GIT_ERROR` and the class /// `GIT_ERROR_NONE`. + #[expect(clippy::should_implement_trait)] pub fn from_str(s: &str) -> Error { Error { code: raw::GIT_ERROR as c_int, From d9cfd2d3737049ec25523328c1a767893b41e417 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:03:41 -0700 Subject: [PATCH 24/75] [Clippy] Address `clippy::io_other_error` in src/indexer.rs In the `std::io::Write` trait implementation for `Indexer`, use the helper function `std::io::Error::other()` for constructing an `std::io::Error` of kind `std::io::ErrorKind::other`. --- src/indexer.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/indexer.rs b/src/indexer.rs index 045d22cf90..ac65ca9bd6 100644 --- a/src/indexer.rs +++ b/src/indexer.rs @@ -1,5 +1,3 @@ -#![allow(clippy::io_other_error)] - use std::ffi::CStr; use std::path::Path; use std::{io, marker, mem, ptr}; @@ -223,7 +221,7 @@ impl io::Write for Indexer<'_> { let len = buf.len(); let res = unsafe { raw::git_indexer_append(self.raw, ptr, len, &mut self.progress) }; if res < 0 { - Err(io::Error::new(io::ErrorKind::Other, Error::last_error(res))) + Err(io::Error::other(Error::last_error(res))) } else { Ok(buf.len()) } From 9fc2de6c565acd1e1628947e3c074ee0f07f6308 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:08:56 -0700 Subject: [PATCH 25/75] [Clippy] Address `clippy::needless_lifetimes` in src/lib.rs Remove needless lifetimes from the `opt_bytes()` function. --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e44b4a39c3..c8a2c7b0b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,7 +70,6 @@ #![deny(missing_docs)] #![warn(rust_2018_idioms)] #![cfg_attr(test, deny(warnings))] -#![allow(clippy::needless_lifetimes)] #![allow(clippy::should_implement_trait)] #![allow(clippy::unnecessary_cast)] @@ -906,7 +905,7 @@ fn openssl_env_init() { ))] fn openssl_env_init() {} -unsafe fn opt_bytes<'a, T>(_anchor: &'a T, c: *const libc::c_char) -> Option<&'a [u8]> { +unsafe fn opt_bytes(_anchor: &T, c: *const libc::c_char) -> Option<&[u8]> { if c.is_null() { None } else { From eff593a94e1cc1797515d85cffeab32b8352e629 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:22:31 -0700 Subject: [PATCH 26/75] [Clippy] Address `clippy::should_implement_trait` in src/lib.rs Because the method with the confusing name (`ObjectType::from_str()`) is part of the public API of the crate, simply move the lint handling to that method with an `#[expect]` attribute. Doing so avoids breaking changes while also removing the `#![allow]` from the overall module, ensuring that new functions do not have confusing names. Since lints that are `#![allow]`ed in src/lib.rs are also allowed in other files, the removal of the `#![allow]` surfaces warnings in src/oid.rs. For now, allow the current violation at a module level, to be addressed shortly. --- src/lib.rs | 2 +- src/oid.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index c8a2c7b0b9..628fc94daa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,7 +70,6 @@ #![deny(missing_docs)] #![warn(rust_2018_idioms)] #![cfg_attr(test, deny(warnings))] -#![allow(clippy::should_implement_trait)] #![allow(clippy::unnecessary_cast)] use bitflags::bitflags; @@ -954,6 +953,7 @@ impl ObjectType { } /// Convert a string object type representation to its object type. + #[expect(clippy::should_implement_trait)] pub fn from_str(s: &str) -> Option { let raw = unsafe { call!(raw::git_object_string2type(CString::new(s).unwrap())) }; ObjectType::from_raw(raw) diff --git a/src/oid.rs b/src/oid.rs index 8bfca61180..c57fe0ea1d 100644 --- a/src/oid.rs +++ b/src/oid.rs @@ -1,3 +1,5 @@ +#![allow(clippy::should_implement_trait)] + use std::cmp::Ordering; use std::fmt; use std::hash::{Hash, Hasher}; From abe73007e2ac2f697f0d31e181c82ad8b08a066d Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:25:48 -0700 Subject: [PATCH 27/75] [Clippy] Address `clippy::missing_safety_doc` in src/merge.rs Add safety documentation for `MergeOptions::raw()`. --- src/merge.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/merge.rs b/src/merge.rs index a95754d9a2..0df9ecf566 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -1,4 +1,3 @@ -#![allow(clippy::missing_safety_doc)] #![allow(clippy::redundant_closure)] use libc::{c_char, c_uint, c_ushort, size_t}; @@ -185,6 +184,11 @@ impl MergeOptions { } /// Acquire a pointer to the underlying raw options. + /// + /// # Safety + /// + /// The provided pointer must not be used to manipulate the options, and + /// must not outlive the [`MergeOptions`] instance. pub unsafe fn raw(&self) -> *const raw::git_merge_options { &self.raw as *const _ } From 50c5ff36a36c5d4ea50ac936f534b4578aea702d Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:26:36 -0700 Subject: [PATCH 28/75] [Clippy] Address `clippy::redundant_closure` in src/merge.rs Simplify `MergeFileResult::path()` to use the tuple variant `Some` rather than using a closure. --- src/merge.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/merge.rs b/src/merge.rs index 0df9ecf566..401d68ca5a 100644 --- a/src/merge.rs +++ b/src/merge.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use libc::{c_char, c_uint, c_ushort, size_t}; use std::ffi::CString; use std::marker; @@ -369,7 +367,7 @@ impl MergeFileResult { /// returns `Ok(None)` if a filename conflict would occur pub fn path(&self) -> Result, Error> { match self.path_bytes() { - Some(pb) => str::from_utf8(pb).map(|s| Some(s)).map_err(|e| e.into()), + Some(pb) => str::from_utf8(pb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From ff07f2fd0b6ca28e8b60aac3a80e8117aa59541b Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:29:00 -0700 Subject: [PATCH 29/75] [Clippy] Address `clippy::len_without_is_empty` in src/message.rs Add new public methods `MessageTrailersStrs::is_empty()` and `MessageTrailersBytes::is_empty()` for checking if a message's trailers are empty. Internally, introduce `MessageTrailers::is_empty()` to handle the logic. --- src/message.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/message.rs b/src/message.rs index cbd929fffd..466ad0a779 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,4 +1,3 @@ -#![allow(clippy::len_without_is_empty)] #![allow(clippy::needless_borrow)] #![allow(clippy::redundant_closure)] @@ -77,6 +76,10 @@ impl MessageTrailersStrs { pub fn len(&self) -> usize { self.0.len() } + /// Whether there are no trailers + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } /// Convert to the “bytes” variant. pub fn to_bytes(self) -> MessageTrailersBytes { MessageTrailersBytes(self.0) @@ -97,6 +100,10 @@ impl MessageTrailersBytes { pub fn len(&self) -> usize { self.0.len() } + /// Whether there are no trailers + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } } struct MessageTrailers { @@ -126,6 +133,10 @@ impl MessageTrailers { fn len(&self) -> usize { self.raw.count } + /// Whether there are no trailers + fn is_empty(&self) -> bool { + self.raw.count == 0 + } } impl Drop for MessageTrailers { From dcbf3564ede32a724f2eab9c35d1962d345cad75 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:31:48 -0700 Subject: [PATCH 30/75] [Clippy] Address `clippy::needless_borrow` in src/message.rs Remove needless borrows in: - `MessageTrailersStrsIterator::next()` - `MessageTrailersStrsIterator::next_back()` - `to_str_tuple()` - `MessageTrailersBytesIterator::next()` - `MessageTrailersBytesIterator::next_back()` - `to_bytes_tuple()` --- src/message.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/message.rs b/src/message.rs index 466ad0a779..1b662d34da 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,4 +1,3 @@ -#![allow(clippy::needless_borrow)] #![allow(clippy::redundant_closure)] use core::ops::Range; @@ -177,7 +176,7 @@ impl<'pair> Iterator for MessageTrailersStrsIterator<'pair> { self.0 .range .next() - .map(|index| to_str_tuple(&self.0.trailers, index)) + .map(|index| to_str_tuple(self.0.trailers, index)) } fn size_hint(&self) -> (usize, Option) { @@ -198,12 +197,12 @@ impl DoubleEndedIterator for MessageTrailersStrsIterator<'_> { self.0 .range .next_back() - .map(|index| to_str_tuple(&self.0.trailers, index)) + .map(|index| to_str_tuple(self.0.trailers, index)) } } fn to_str_tuple(trailers: &MessageTrailers, index: usize) -> (&str, &str) { - let (rkey, rvalue) = to_raw_tuple(&trailers, index); + let (rkey, rvalue) = to_raw_tuple(trailers, index); let key = unsafe { CStr::from_ptr(rkey).to_str().unwrap() }; let value = unsafe { CStr::from_ptr(rvalue).to_str().unwrap() }; (key, value) @@ -219,7 +218,7 @@ impl<'pair> Iterator for MessageTrailersBytesIterator<'pair> { self.0 .range .next() - .map(|index| to_bytes_tuple(&self.0.trailers, index)) + .map(|index| to_bytes_tuple(self.0.trailers, index)) } fn size_hint(&self) -> (usize, Option) { @@ -240,12 +239,12 @@ impl DoubleEndedIterator for MessageTrailersBytesIterator<'_> { self.0 .range .next_back() - .map(|index| to_bytes_tuple(&self.0.trailers, index)) + .map(|index| to_bytes_tuple(self.0.trailers, index)) } } fn to_bytes_tuple(trailers: &MessageTrailers, index: usize) -> (&[u8], &[u8]) { - let (rkey, rvalue) = to_raw_tuple(&trailers, index); + let (rkey, rvalue) = to_raw_tuple(trailers, index); let key = unsafe { CStr::from_ptr(rkey).to_bytes() }; let value = unsafe { CStr::from_ptr(rvalue).to_bytes() }; (key, value) From 8cfba671b90baa45bec9d18b3d53c0e53c896140 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:34:27 -0700 Subject: [PATCH 31/75] [Clippy] Address `clippy::redundant_closure` in src/message.rs Simplify `message_trailers_strs()` to use the constructor of the tuple-like struct `MessageTrailersStrs` directly. Simpify `message_trailers_bytes()` to use the constructor of the tuple-like struct `MessageTrailersBytes` directly. --- src/message.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/message.rs b/src/message.rs index 1b662d34da..ef094f761b 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use core::ops::Range; use std::ffi::CStr; use std::ffi::CString; @@ -41,7 +39,7 @@ pub const DEFAULT_COMMENT_CHAR: Option = Some(b'#'); /// /// Use this function when you are dealing with a UTF-8-encoded message. pub fn message_trailers_strs(message: &str) -> Result { - _message_trailers(message.into_c_string()?).map(|res| MessageTrailersStrs(res)) + _message_trailers(message.into_c_string()?).map(MessageTrailersStrs) } /// Get the trailers for the given message. @@ -50,7 +48,7 @@ pub fn message_trailers_strs(message: &str) -> Result(message: S) -> Result { - _message_trailers(message.into_c_string()?).map(|res| MessageTrailersBytes(res)) + _message_trailers(message.into_c_string()?).map(MessageTrailersBytes) } fn _message_trailers(message: CString) -> Result { From 65b3df604348db1190f5c4fac73800b3be39c57f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:36:40 -0700 Subject: [PATCH 32/75] [Clippy] Address `clippy::io_error_other` in src/odb.rs In a few trait implementations, use the helper function `std::io::Error::other()` for constructing an `std::io::Error` of kind `std::io::ErrorKind::other`: * implementation of `std::io::Read` for `OdbReader` * implementation of `std::io::Write` for `OdbWriter` * implementation of `std::io::Write` for `OdbPackwriter` --- src/odb.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/odb.rs b/src/odb.rs index d854093159..6fd9393455 100644 --- a/src/odb.rs +++ b/src/odb.rs @@ -1,4 +1,3 @@ -#![allow(clippy::io_other_error)] #![allow(clippy::len_without_is_empty)] #![allow(clippy::single_match)] #![allow(clippy::should_implement_trait)] @@ -388,7 +387,7 @@ impl<'repo> io::Read for OdbReader<'repo> { let len = buf.len(); let res = unsafe { raw::git_odb_stream_read(self.raw, ptr, len) }; if res < 0 { - Err(io::Error::new(io::ErrorKind::Other, "Read error")) + Err(io::Error::other("Read error")) } else { Ok(res as _) } @@ -447,7 +446,7 @@ impl<'repo> io::Write for OdbWriter<'repo> { let len = buf.len(); let res = unsafe { raw::git_odb_stream_write(self.raw, ptr, len) }; if res < 0 { - Err(io::Error::new(io::ErrorKind::Other, "Write error")) + Err(io::Error::other("Write error")) } else { Ok(buf.len()) } @@ -514,7 +513,7 @@ impl<'repo> io::Write for OdbPackwriter<'repo> { }; } if res < 0 { - Err(io::Error::new(io::ErrorKind::Other, "Write error")) + Err(io::Error::other("Write error")) } else { Ok(buf.len()) } From c063ce00387e88aa2d02a48d2b1c2d5cda2e1da7 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:40:39 -0700 Subject: [PATCH 33/75] [Clippy] Address `clippy::len_without_is_empty` in src/odb.rs Add a new public method `OdbObject::is_empty()` for checking if an object's data is empty. --- src/odb.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/odb.rs b/src/odb.rs index 6fd9393455..23b42960c2 100644 --- a/src/odb.rs +++ b/src/odb.rs @@ -1,4 +1,3 @@ -#![allow(clippy::len_without_is_empty)] #![allow(clippy::single_match)] #![allow(clippy::should_implement_trait)] @@ -336,6 +335,11 @@ impl<'a> OdbObject<'a> { unsafe { raw::git_odb_object_size(self.raw) } } + /// Check if the data is empty + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + /// Get the object data. pub fn data(&self) -> &[u8] { let size = self.len(); From 94dd707369910204ce28c1ab4cb7100ac9e1841f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:50:12 -0700 Subject: [PATCH 34/75] [Clippy] Address `clippy::should_implement_trait` in src/odb.rs Remove the `#![allow]` attribute, apparently something has changed since I initially added it and clippy no longer complains. --- src/odb.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/odb.rs b/src/odb.rs index 23b42960c2..da3e6154e3 100644 --- a/src/odb.rs +++ b/src/odb.rs @@ -1,5 +1,4 @@ #![allow(clippy::single_match)] -#![allow(clippy::should_implement_trait)] use std::io; use std::marker; From 4598f251aa948a6d9ad3abad3c2dd14f4d6a6c72 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:51:06 -0700 Subject: [PATCH 35/75] [Clippy] Address `clippy::single_match` in src/odb.rs Simplify the `Drop` implementation for `OdbPackwriter` to use an if-let expression rather than matching to destructure the `Some` variant of the `Option`. --- src/odb.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/odb.rs b/src/odb.rs index da3e6154e3..7916b737f8 100644 --- a/src/odb.rs +++ b/src/odb.rs @@ -1,5 +1,3 @@ -#![allow(clippy::single_match)] - use std::io; use std::marker; use std::ptr; @@ -530,9 +528,8 @@ impl<'repo> Drop for OdbPackwriter<'repo> { fn drop(&mut self) { unsafe { let writepack = &*self.raw; - match writepack.free { - Some(free) => free(self.raw), - None => (), + if let Some(free) = writepack.free { + free(self.raw); }; drop(Box::from_raw(self.progress_payload_ptr)); From 8bd58e6deb5d2f0520c86989cda9784e7baa82c4 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:52:22 -0700 Subject: [PATCH 36/75] [Clippy] Address `clippy::extra_unused_lifetimes` in src/oid_array.rs Remove the unused lifetime from the `std::fmt::Debug` implementation for `OidArray`. --- src/oid_array.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/oid_array.rs b/src/oid_array.rs index 87abef2974..dfdae33bfa 100644 --- a/src/oid_array.rs +++ b/src/oid_array.rs @@ -1,7 +1,5 @@ //! Bindings to libgit2's raw `git_oidarray` type -#![allow(clippy::extra_unused_lifetimes)] - use std::ops::Deref; use crate::oid::Oid; @@ -41,7 +39,7 @@ impl Binding for OidArray { } } -impl<'repo> std::fmt::Debug for OidArray { +impl std::fmt::Debug for OidArray { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { f.debug_tuple("OidArray").field(&self.deref()).finish() } From 1609c605783aa8b35c1ed5aa996b998ea1fd9abe Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 16:53:46 -0700 Subject: [PATCH 37/75] [Clippy] Address `clippy::should_implement_trait` in src/oid.rs Because the method with the confusing name (`Oid::from_str()`) is part of the public API of the crate, simply move the lint handling to that method with an `#[expect]` attribute. Doing so avoids breaking changes while also removing the `#![allow]` from the overall module, ensuring that new functions do not have confusing names. --- src/oid.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/oid.rs b/src/oid.rs index c57fe0ea1d..01f2885756 100644 --- a/src/oid.rs +++ b/src/oid.rs @@ -1,5 +1,3 @@ -#![allow(clippy::should_implement_trait)] - use std::cmp::Ordering; use std::fmt; use std::hash::{Hash, Hasher}; @@ -94,6 +92,7 @@ impl Oid { /// /// Returns an error if the string is empty, is longer than 40 hex /// characters, or contains any non-hex characters. + #[expect(clippy::should_implement_trait)] pub fn from_str(s: &str) -> Result { Self::from_str_ext(s, ObjectFormat::Sha1) } From 20a6c6be8cbafdc6b82cdc7ea13f372e381b282f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:02:02 -0700 Subject: [PATCH 38/75] [Clippy] Address `clippy::missing_safety_doc` in src/opts.rs Add the missing `# Safety` heading to the existing safety documentation for: - `set_search_path()` - `reset_search_path()` - `get_search_path()` Add safety documentation for: - `set_verify_owner_validation()` - `set_ssl_cert_file()` - `set_ssl_cert_dir()` --- src/opts.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/opts.rs b/src/opts.rs index facf5896e5..bac124a076 100644 --- a/src/opts.rs +++ b/src/opts.rs @@ -1,7 +1,5 @@ //! Bindings to libgit2's git_libgit2_opts function. -#![allow(clippy::missing_safety_doc)] - use std::ffi::CString; use std::ptr; @@ -19,6 +17,8 @@ use crate::{raw, Buf, ConfigLevel, Error, IntoCString, ObjectType}; /// Use magic path `$PATH` to include the old value of the path /// (if you want to prepend or append, for instance). /// +/// # Safety +/// /// This function is unsafe as it mutates the global state but cannot guarantee /// thread-safety. It needs to be externally synchronized with calls to access /// the global state. @@ -41,6 +41,8 @@ where /// `level` must be one of [`ConfigLevel::System`], [`ConfigLevel::Global`], /// [`ConfigLevel::XDG`], [`ConfigLevel::ProgramData`]. /// +/// # Safety +/// /// This function is unsafe as it mutates the global state but cannot guarantee /// thread-safety. It needs to be externally synchronized with calls to access /// the global state. @@ -59,6 +61,8 @@ pub unsafe fn reset_search_path(level: ConfigLevel) -> Result<(), Error> { /// `level` must be one of [`ConfigLevel::System`], [`ConfigLevel::Global`], /// [`ConfigLevel::XDG`], [`ConfigLevel::ProgramData`]. /// +/// # Safety +/// /// This function is unsafe as it mutates the global state but cannot guarantee /// thread-safety. It needs to be externally synchronized with calls to access /// the global state. @@ -242,6 +246,11 @@ where /// Set whether or not to verify ownership before performing a repository. /// Enabled by default, but disabling this can lead to code execution vulnerabilities. +/// +/// # Safety +/// +/// This function is modifying a C global without synchronization, so it is not +/// thread safe, and should only be called before any thread is spawned. pub unsafe fn set_verify_owner_validation(enabled: bool) -> Result<(), Error> { crate::init(); let error = raw::git_libgit2_opts( @@ -256,6 +265,11 @@ pub unsafe fn set_verify_owner_validation(enabled: bool) -> Result<(), Error> { /// Set the SSL certificate-authority location to `file`. `file` is the location /// of a file containing several certificates concatenated together. +/// +/// # Safety +/// +/// This function is modifying a C global without synchronization, so it is not +/// thread safe, and should only be called before any thread is spawned. pub unsafe fn set_ssl_cert_file

(file: P) -> Result<(), Error> where P: IntoCString, @@ -275,6 +289,11 @@ where /// Set the SSL certificate-authority location to `path`. `path` is the location /// of a directory holding several certificates, one per file. +/// +/// # Safety +/// +/// This function is modifying a C global without synchronization, so it is not +/// thread safe, and should only be called before any thread is spawned. pub unsafe fn set_ssl_cert_dir

(path: P) -> Result<(), Error> where P: IntoCString, From fd5ae2651a8359de9739681d1d342f4c27c56190 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:03:05 -0700 Subject: [PATCH 39/75] [Clippy] Address `clippy::redundant_closure` in src/packbuilder.rs Simplify `PackBuilder::name()` to use the tuple variant `Some` rather than using a closure. --- src/packbuilder.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/packbuilder.rs b/src/packbuilder.rs index 8d4c3279d2..89dd84d377 100644 --- a/src/packbuilder.rs +++ b/src/packbuilder.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use libc::{c_int, c_uint, c_void, size_t}; use std::marker; use std::path::Path; @@ -204,7 +202,7 @@ impl<'repo> PackBuilder<'repo> { /// Returns `Ok(None)` if the packfile has not been written. pub fn name(&self) -> Result, Error> { match self.name_bytes() { - Some(nb) => str::from_utf8(nb).map(|s| Some(s)).map_err(|e| e.into()), + Some(nb) => str::from_utf8(nb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From 9fc8b0635a6685cbc86e428934b375db3d44d839 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:05:27 -0700 Subject: [PATCH 40/75] [Clippy] Address `clippy::len_without_is_empty` in src/rebase.rs Add a new public method `Rebase::is_empty()` for checking if an rebase has no operations to apply. --- src/rebase.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/rebase.rs b/src/rebase.rs index 1020812110..a714bd0b37 100644 --- a/src/rebase.rs +++ b/src/rebase.rs @@ -1,4 +1,3 @@ -#![allow(clippy::len_without_is_empty)] #![allow(clippy::needless_option_take)] #![allow(clippy::redundant_closure)] @@ -118,6 +117,11 @@ impl<'repo> Rebase<'repo> { unsafe { raw::git_rebase_operation_entrycount(self.raw) } } + /// Checks if ther are no rebase operations that are to be applied. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + /// Gets the original `HEAD` ref name for merge rebases. pub fn orig_head_name(&self) -> Result, Error> { let name_bytes = From 1a7ae6bbed50074cb400558848cf8bd5a4ccfc8b Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:07:23 -0700 Subject: [PATCH 41/75] [Clippy] Address `clippy::needless_option_take` in src/rebase.rs Simplify `RebaseOptions::raw()` by removing an unneeded call to `Option::take()` on a temporary value. --- src/rebase.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rebase.rs b/src/rebase.rs index a714bd0b37..777e32fd83 100644 --- a/src/rebase.rs +++ b/src/rebase.rs @@ -1,4 +1,3 @@ -#![allow(clippy::needless_option_take)] #![allow(clippy::redundant_closure)] use std::ffi::CString; @@ -86,7 +85,7 @@ impl<'cb> RebaseOptions<'cb> { /// Acquire a pointer to the underlying raw options. pub fn raw(&mut self) -> *const raw::git_rebase_options { - if let Some(opts) = self.merge_options.as_mut().take() { + if let Some(opts) = self.merge_options.as_mut() { unsafe { ptr::copy_nonoverlapping(opts.raw(), &mut self.raw.merge_options, 1); } From 3fee76ee9087dd2ad8fda71bb4f9832a39e5d0df Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:08:35 -0700 Subject: [PATCH 42/75] [Clippy] Address `clippy::redundant_closure` in src/rebase.rs Simplify a few methods to use the tuple variant `Some` rather than using a closure: - `Rebase::orig_head_name()` - `RebaseOptions::exec()` --- src/rebase.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/rebase.rs b/src/rebase.rs index 777e32fd83..986ee8c530 100644 --- a/src/rebase.rs +++ b/src/rebase.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use std::ffi::CString; use std::{marker, mem, ptr, str}; @@ -126,7 +124,7 @@ impl<'repo> Rebase<'repo> { let name_bytes = unsafe { crate::opt_bytes(self, raw::git_rebase_orig_head_name(self.raw)) }; match name_bytes { - Some(nb) => str::from_utf8(nb).map(|s| Some(s)).map_err(|e| e.into()), + Some(nb) => str::from_utf8(nb).map(Some).map_err(|e| e.into()), None => Ok(None), } } @@ -328,7 +326,7 @@ impl<'rebase> RebaseOperation<'rebase> { pub fn exec(&self) -> Result, Error> { let exec_bytes = unsafe { crate::opt_bytes(self, (*self.raw).exec) }; match exec_bytes { - Some(eb) => str::from_utf8(eb).map(|s| Some(s)).map_err(|e| e.into()), + Some(eb) => str::from_utf8(eb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From 70271b9ace2205d4887eec87d84feb35191ee525 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:09:27 -0700 Subject: [PATCH 43/75] [Clippy] Address `clippy::redundant_closure` in src/reference.rs Simplify `Reference::symbolic_target()` to use the tuple variant `Some` rather than using a closure. --- src/reference.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/reference.rs b/src/reference.rs index f69f9b6b10..bd414d5b01 100644 --- a/src/reference.rs +++ b/src/reference.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use std::cmp::Ordering; use std::ffi::CString; use std::marker; @@ -262,7 +260,7 @@ impl<'repo> Reference<'repo> { /// May return `Ok(None)` if the reference is not symbolic. pub fn symbolic_target(&self) -> Result, Error> { match self.symbolic_target_bytes() { - Some(stb) => str::from_utf8(stb).map(|s| Some(s)).map_err(|e| e.into()), + Some(stb) => str::from_utf8(stb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From e04e1440e5634ef84e4a53fea863719bff538038 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:10:14 -0700 Subject: [PATCH 44/75] [Clippy] Address `clippy::redundant_closure` in src/reflog.rs Simplify `ReflogEntry::message()` to use the tuple variant `Some` rather than using a closure. --- src/reflog.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/reflog.rs b/src/reflog.rs index 69d971e7af..b0f91e1526 100644 --- a/src/reflog.rs +++ b/src/reflog.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use libc::size_t; use std::iter::FusedIterator; use std::marker; @@ -141,7 +139,7 @@ impl<'reflog> ReflogEntry<'reflog> { /// Get the log message. pub fn message(&self) -> Result, Error> { match self.message_bytes() { - Some(mb) => str::from_utf8(mb).map(|s| Some(s)).map_err(|e| e.into()), + Some(mb) => str::from_utf8(mb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From d54058a42c3cc475a0a09729c58fcdb2939d5345 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:11:36 -0700 Subject: [PATCH 45/75] [Clippy] Address `clippy::derivable_impls` in src/remote.rs Use `#[derive(Default)]` for the `RemoteRedirect` enum, with the `Initial` variant marked as the default one. --- src/remote.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/remote.rs b/src/remote.rs index 377e66a068..384bace76d 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -1,4 +1,3 @@ -#![allow(clippy::derivable_impls)] #![allow(clippy::empty_line_after_doc_comments)] #![allow(clippy::redundant_closure)] #![allow(clippy::unwrap_or_default)] @@ -82,11 +81,13 @@ pub struct RemoteConnection<'repo, 'connection, 'cb> { /// /// By default, git will follow a redirect on the initial request /// (`/info/refs`), but not subsequent requests. +#[derive(Default)] pub enum RemoteRedirect { /// Do not follow any off-site redirects at any stage of the fetch or push. None, /// Allow off-site redirects only upon the initial request. This is the /// default. + #[default] Initial, /// Allow redirects at any stage in the fetch or push. All, @@ -813,12 +814,6 @@ impl<'repo, 'connection, 'cb> Drop for RemoteConnection<'repo, 'connection, 'cb> } } -impl Default for RemoteRedirect { - fn default() -> Self { - RemoteRedirect::Initial - } -} - impl RemoteRedirect { fn raw(&self) -> raw::git_remote_redirect_t { match self { From a42b5cc33f75b2199dd52b63f53e2d2d086c2797 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:12:45 -0700 Subject: [PATCH 46/75] [Clippy] Address `clippy::empty_line_after_doc_comments` in src/remote.rs Remove the empty line after the doc comment for `FetchOptions::depth()`. --- src/remote.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/remote.rs b/src/remote.rs index 384bace76d..9d4e146bcd 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -1,4 +1,3 @@ -#![allow(clippy::empty_line_after_doc_comments)] #![allow(clippy::redundant_closure)] #![allow(clippy::unwrap_or_default)] @@ -594,7 +593,6 @@ impl<'cb> FetchOptions<'cb> { /// Set fetch depth, a value less or equal to 0 is interpreted as pull /// everything (effectively the same as not declaring a limit depth). - // FIXME(blyxyas): We currently don't have a test for shallow functions // because libgit2 doesn't support local shallow clones. // https://github.com/rust-lang/git2-rs/pull/979#issuecomment-1716299900 From 5937bce702bbe50b08976b35829368e4d3e93e94 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:13:45 -0700 Subject: [PATCH 47/75] [Clippy] Address `clippy::redundant_closure` in src/remote.rs Simplify a few methods to use the tuple variant `Some` rather than using a closure: - `Remote::name()` - `Remote::pushurl()` --- src/remote.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/remote.rs b/src/remote.rs index 9d4e146bcd..ef490b080b 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -1,4 +1,3 @@ -#![allow(clippy::redundant_closure)] #![allow(clippy::unwrap_or_default)] use raw::git_strarray; @@ -135,7 +134,7 @@ impl<'repo> Remote<'repo> { /// Returns `Ok(None)` if this remote has not yet been named. pub fn name(&self) -> Result, Error> { match self.name_bytes() { - Some(nb) => str::from_utf8(nb).map(|s| Some(s)).map_err(|e| e.into()), + Some(nb) => str::from_utf8(nb).map(Some).map_err(|e| e.into()), None => Ok(None), } } @@ -162,7 +161,7 @@ impl<'repo> Remote<'repo> { /// Returns `Ok(None)` if no special url for pushing is set. pub fn pushurl(&self) -> Result, Error> { match self.pushurl_bytes() { - Some(pb) => str::from_utf8(pb).map(|s| Some(s)).map_err(|e| e.into()), + Some(pb) => str::from_utf8(pb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From e9727fba4500ca2a99d36eea9a737174732c8919 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:15:05 -0700 Subject: [PATCH 48/75] [Clippy] Address `clippy::unwrap_or_default` in src/remote.rs Simplify a few methods to use `Option::unwrap_or_default()`: - `Remote::connect_auth()` - `Remote::prune()` --- src/remote.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/remote.rs b/src/remote.rs index ef490b080b..3693960579 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -1,5 +1,3 @@ -#![allow(clippy::unwrap_or_default)] - use raw::git_strarray; use std::iter::FusedIterator; use std::marker; @@ -224,8 +222,8 @@ impl<'repo> Remote<'repo> { cb: Option>, proxy_options: Option>, ) -> Result, Error> { - let cb = Box::new(cb.unwrap_or_else(RemoteCallbacks::new)); - let proxy_options = proxy_options.unwrap_or_else(ProxyOptions::new); + let cb = Box::new(cb.unwrap_or_default()); + let proxy_options = proxy_options.unwrap_or_default(); unsafe { try_call!(raw::git_remote_connect( self.raw, @@ -430,7 +428,7 @@ impl<'repo> Remote<'repo> { /// Prune tracking refs that are no longer present on remote pub fn prune(&mut self, callbacks: Option>) -> Result<(), Error> { - let cbs = Box::new(callbacks.unwrap_or_else(RemoteCallbacks::new)); + let cbs = Box::new(callbacks.unwrap_or_default()); unsafe { try_call!(raw::git_remote_prune(self.raw, &cbs.raw())); } From 4dee9b90f6ed3a82a89d6666c9d57b2ee4b3cc96 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:16:51 -0700 Subject: [PATCH 49/75] [Clippy] Address `clippy::doc_overindented_list_items` in src/remote_callbacks.rs Remove extra spaces in the documentation of the `Credentials` type --- src/remote_callbacks.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/remote_callbacks.rs b/src/remote_callbacks.rs index 1d988bb7f7..a10926a55d 100644 --- a/src/remote_callbacks.rs +++ b/src/remote_callbacks.rs @@ -1,5 +1,3 @@ -#![allow(clippy::doc_overindented_list_items)] - use libc::{c_char, c_int, c_uint, c_void, size_t}; use std::ffi::CStr; use std::mem; @@ -35,7 +33,7 @@ pub struct RemoteCallbacks<'a> { /// /// * `url` - the resource for which the credentials are required. /// * `username_from_url` - the username that was embedded in the URL, or `None` -/// if it was not included. +/// if it was not included. /// * `allowed_types` - a bitmask stating which cred types are OK to return. pub type Credentials<'a> = dyn FnMut(&str, Option<&str>, CredentialType) -> Result + 'a; From 579ebdda1ad78a1a627183fdd3e1e66a7fa679d1 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:21:43 -0700 Subject: [PATCH 50/75] [Clippy] Address `clippy::explicit_auto_deref` in src/repo.rs Remove the explicit dereferencing in `Repository::discover()` and `Repository::discover_path()`. --- src/repo.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/repo.rs b/src/repo.rs index e7af75b5c8..c92bd74d20 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1,4 +1,3 @@ -#![allow(clippy::explicit_auto_deref)] #![allow(clippy::missing_safety_doc)] #![allow(clippy::needless_borrow)] #![allow(clippy::new_without_default)] @@ -269,7 +268,7 @@ impl Repository { ptr::null() )); } - Repository::open(util::bytes2path(&*buf)) + Repository::open(util::bytes2path(&buf)) } /// Attempt to find the path to a git repo for a given path @@ -296,7 +295,7 @@ impl Repository { )); } - Ok(util::bytes2path(&*buf).to_path_buf()) + Ok(util::bytes2path(&buf).to_path_buf()) } /// Creates a new repository in the specified folder. From 01d626b06bc9d9a38cfb23c84b0aecd2a23c3d3f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:24:32 -0700 Subject: [PATCH 51/75] [Clippy] Address `clippy::missing_safety_doc` in src/repo.rs Add the missing `# Safety` heading to the existing safety documentation for `RepositoryInitOptions::raw()` and expand that documentation. --- src/repo.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/repo.rs b/src/repo.rs index c92bd74d20..8ce0982f12 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1,4 +1,3 @@ -#![allow(clippy::missing_safety_doc)] #![allow(clippy::needless_borrow)] #![allow(clippy::new_without_default)] #![allow(clippy::redundant_closure)] @@ -3634,8 +3633,15 @@ impl RepositoryInitOptions { /// Creates a set of raw init options to be used with /// `git_repository_init_ext`. /// + /// # Safety + /// /// This method is unsafe as the returned value may have pointers to the - /// interior of this structure. + /// interior of this structure. The caller must ensure that the returned + /// raw instance does not outlive the [`RepositoryInitOptions`], and also + /// that for any fields configured in the `RepositoryInitOptions` that are + /// provided in the raw structure as pointers, those pointers are not used + /// if the original references held in the `RepositoryInitOptions` are + /// dropped. pub unsafe fn raw(&self) -> raw::git_repository_init_options { let mut opts = mem::zeroed(); assert_eq!( From 51d382a29332f1a75db491d7ca877f078ecfb282 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:25:25 -0700 Subject: [PATCH 52/75] [Clippy] Address `clippy::needless_borrow` in src/repo.rs Remove a needless borrow in `fetchhead_foreach_cb()`. --- src/repo.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/repo.rs b/src/repo.rs index 8ce0982f12..ef580a15e3 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1,4 +1,3 @@ -#![allow(clippy::needless_borrow)] #![allow(clippy::new_without_default)] #![allow(clippy::redundant_closure)] #![allow(clippy::too_many_arguments)] @@ -92,7 +91,7 @@ extern "C" fn fetchhead_foreach_cb( let oid = Binding::from_raw(oid); let is_merge = is_merge == 1; - callback(&ref_name, remote_url, &oid, is_merge) + callback(ref_name, remote_url, &oid, is_merge) }; if res { @@ -3669,6 +3668,7 @@ impl RepositoryInitOptions { #[cfg(test)] #[allow(clippy::assertions_on_constants)] #[allow(clippy::bool_assert_comparison)] +#[allow(clippy::needless_borrow)] #[allow(clippy::needless_borrows_for_generic_args)] mod tests { use crate::build::CheckoutBuilder; From 872493fc7bee6967fb18e9ecd4babd70fe2966a9 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:26:56 -0700 Subject: [PATCH 53/75] [Clippy] Address `clippy::new_without_default` in src/repo.rs Add an implementation of the `Default` trait for `RepositoryInitOptions` that delegates to `RepositoryInitOptions::new()`. --- src/repo.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/repo.rs b/src/repo.rs index ef580a15e3..ae4b72ed2e 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1,4 +1,3 @@ -#![allow(clippy::new_without_default)] #![allow(clippy::redundant_closure)] #![allow(clippy::too_many_arguments)] #![allow(clippy::zero_ptr)] @@ -3665,6 +3664,15 @@ impl RepositoryInitOptions { } } +impl Default for RepositoryInitOptions { + /// Creates a default set of initialization options. + /// + /// See [`RepositoryInitOptions::new()`] for more details. + fn default() -> Self { + Self::new() + } +} + #[cfg(test)] #[allow(clippy::assertions_on_constants)] #[allow(clippy::bool_assert_comparison)] From cfcf761108720154c71438b26709cdb95931e101 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:27:43 -0700 Subject: [PATCH 54/75] [Clippy] Address `clippy::redundant_closure` in src/repo.rs Simplify `Repository::namespace()` to use the tuple variant `Some` rather than using a closure. --- src/repo.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/repo.rs b/src/repo.rs index ae4b72ed2e..8f767be74d 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1,4 +1,3 @@ -#![allow(clippy::redundant_closure)] #![allow(clippy::too_many_arguments)] #![allow(clippy::zero_ptr)] @@ -548,7 +547,7 @@ impl Repository { /// If there is no namespace, Ok(None) is returned. pub fn namespace(&self) -> Result, Error> { match self.namespace_bytes() { - Some(nb) => str::from_utf8(nb).map(|s| Some(s)).map_err(|e| e.into()), + Some(nb) => str::from_utf8(nb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From 0d00c8434491f49212825098912d5cfac285d716 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:28:52 -0700 Subject: [PATCH 55/75] [Clippy] Address `clippy::too_many_arguments` in src/repo.rs Because the method that accepts too many arguments (`Repository::diff_blobs()`) is part of the public API of the crate, simply move the lint handling to that method with an `#[expect]` attribute. Doing so avoids breaking changes while also removing the `#![allow]` from the overall module, ensuring that new functions do not have too many arguments. --- src/repo.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/repo.rs b/src/repo.rs index 8f767be74d..67b505843a 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1,4 +1,3 @@ -#![allow(clippy::too_many_arguments)] #![allow(clippy::zero_ptr)] use libc::{c_char, c_int, c_uint, c_void, size_t}; @@ -2810,6 +2809,7 @@ impl Repository { /// like binary data, the `DiffFile` binary attribute will be set to 1 and no call to /// the `hunk_cb` nor `line_cb` will be made (unless you set the `force_text` /// option). + #[expect(clippy::too_many_arguments)] pub fn diff_blobs( &self, old_blob: Option<&Blob<'_>>, From fe53f31cf20af51b5b257bff806bd5622a011c46 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:31:21 -0700 Subject: [PATCH 56/75] [Clippy] Address `clippy::zero_ptr` in src/repo.rs In `Repository::revert()` use `std::ptr::null()` for the revert options pointer passed to `git_revert()` if no options are provided by the caller. --- src/repo.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/repo.rs b/src/repo.rs index 67b505843a..18b7a952d8 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1,5 +1,3 @@ -#![allow(clippy::zero_ptr)] - use libc::{c_char, c_int, c_uint, c_void, size_t}; use std::env; use std::ffi::{CStr, CString, OsStr}; @@ -3322,7 +3320,7 @@ impl Repository { let raw_opts = options.map(|o| o.raw()); let ptr_raw_opts = match raw_opts.as_ref() { Some(v) => v, - None => 0 as *const _, + None => std::ptr::null(), }; unsafe { try_call!(raw::git_revert(self.raw(), commit.raw(), ptr_raw_opts)); From 7ed3393f43ef80fee2d3e3726fb6819f35216d36 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:32:48 -0700 Subject: [PATCH 57/75] [Clippy] Address `clippy::new_without_default` in src/revert.rs Add an implementation of the `Default` trait for `RevertOptions` that delegates to `RevertOptions::new()`. --- src/revert.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/revert.rs b/src/revert.rs index 78bfe5d7cc..c09ed9a260 100644 --- a/src/revert.rs +++ b/src/revert.rs @@ -1,5 +1,3 @@ -#![allow(clippy::new_without_default)] - use std::mem; use crate::build::CheckoutBuilder; @@ -69,3 +67,10 @@ impl<'cb> RevertOptions<'cb> { } } } + +impl<'cb> Default for RevertOptions<'cb> { + /// Creates a default set of revert options + fn default() -> Self { + Self::new() + } +} From 15815dc374ff9f6a09e58f7340378ab9810ceee1 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:33:51 -0700 Subject: [PATCH 58/75] [Clippy] Address `clippy::missing_safety_doc` in src/revert.rs Add the missing `# Safety` heading to the existing safety documentation for `StashSaveOptions::raw()`. --- src/stash.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stash.rs b/src/stash.rs index 74f375e568..09edcc88e6 100644 --- a/src/stash.rs +++ b/src/stash.rs @@ -1,5 +1,3 @@ -#![allow(clippy::missing_safety_doc)] - use crate::build::CheckoutBuilder; use crate::util::{self, Binding}; use crate::{panic, raw, IntoCString, Oid, Signature, StashApplyProgress, StashFlags}; @@ -56,6 +54,8 @@ impl<'a> StashSaveOptions<'a> { /// Acquire a pointer to the underlying raw options. /// + /// # Safety + /// /// This function is unsafe as the pointer is only valid so long as this /// structure is not moved, modified, or used elsewhere. pub unsafe fn raw(&mut self) -> *const raw::git_stash_save_options { From bf0197948f242b10d064ca87dd276676a77bc517 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:34:40 -0700 Subject: [PATCH 59/75] [Clippy] Address `clippy::missing_safety_doc` in src/status.rs Add the missing `# Safety` heading to the existing safety documentation for `StatusOptions::raw()`. --- src/status.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/status.rs b/src/status.rs index 5da7253fb2..fd0b8353b0 100644 --- a/src/status.rs +++ b/src/status.rs @@ -1,5 +1,3 @@ -#![allow(clippy::missing_safety_doc)] - use libc::{c_char, c_uint, size_t}; use std::ffi::CString; use std::iter::FusedIterator; @@ -227,6 +225,8 @@ impl StatusOptions { /// Get a pointer to the inner list of status options. /// + /// # Safety + /// /// This function is unsafe as the returned structure has interior pointers /// and may no longer be valid if these options continue to be mutated. pub unsafe fn raw(&mut self) -> *const raw::git_status_options { From e8a08348a581ed91bdafcdb2269c413b834d41b7 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:35:42 -0700 Subject: [PATCH 60/75] [Clippy] Address `clippy::redundant_closure` in src/string_array.rs Simplify `StringArray::get()` to use the tuple variant `Some` rather than using a closure. --- src/string_array.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/string_array.rs b/src/string_array.rs index 7ac04cf70d..a53024b7d1 100644 --- a/src/string_array.rs +++ b/src/string_array.rs @@ -1,7 +1,5 @@ //! Bindings to libgit2's raw `git_strarray` type -#![allow(clippy::redundant_closure)] - use std::iter::FusedIterator; use std::ops::Range; use std::str; @@ -35,7 +33,7 @@ impl StringArray { /// Returns Ok(None) if i is out of bounds. pub fn get(&self, i: usize) -> Result, Error> { match self.get_bytes(i) { - Some(gb) => str::from_utf8(gb).map(|s| Some(s)).map_err(|e| e.into()), + Some(gb) => str::from_utf8(gb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From 78570ef2855d2690ad31e7c71473752cb36ed355 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:37:49 -0700 Subject: [PATCH 61/75] [Clippy] Address `clippy::empty_line_after_doc_comments` in src/submodule.rs Add an empty comment line (`///`) between the paragraphs of the documentation for `Submodule::repo_init()`. --- src/submodule.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/submodule.rs b/src/submodule.rs index 878a74fa85..6c7e3e502f 100644 --- a/src/submodule.rs +++ b/src/submodule.rs @@ -1,4 +1,3 @@ -#![allow(clippy::empty_line_after_doc_comments)] #![allow(clippy::let_and_return)] #![allow(clippy::redundant_closure)] @@ -150,7 +149,7 @@ impl<'repo> Submodule<'repo> { /// /// This function can be called to init and set up a submodule repository /// from a submodule in preparation to clone it from its remote. - + /// /// use_gitlink: Should the workdir contain a gitlink to the repo in /// .git/modules vs. repo directly in workdir. pub fn repo_init(&mut self, use_gitlink: bool) -> Result { From c5e2093c00fcd398d9a98b7cd6fd41774d98d3a4 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:38:39 -0700 Subject: [PATCH 62/75] [Clippy] Address `clippy::let_and_return` in src/submodule.rs Remove the unneeded assignment in `Submodule::raw()`. --- src/submodule.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/submodule.rs b/src/submodule.rs index 6c7e3e502f..8bf1144791 100644 --- a/src/submodule.rs +++ b/src/submodule.rs @@ -1,4 +1,3 @@ -#![allow(clippy::let_and_return)] #![allow(clippy::redundant_closure)] use std::marker; @@ -296,13 +295,12 @@ impl<'cb> SubmoduleUpdateOptions<'cb> { raw::git_checkout_init_options(&mut checkout_opts, raw::GIT_CHECKOUT_OPTIONS_VERSION); assert_eq!(0, init_res); self.checkout_builder.configure(&mut checkout_opts); - let opts = raw::git_submodule_update_options { + raw::git_submodule_update_options { version: raw::GIT_SUBMODULE_UPDATE_OPTIONS_VERSION, checkout_opts, fetch_opts: self.fetch_opts.raw(), allow_fetch: self.allow_fetch as c_int, - }; - opts + } } /// Set checkout options. From 000ea5262220a8c7097a309e9ac80a6d3ae9e33b Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:39:30 -0700 Subject: [PATCH 63/75] [Clippy] Address `clippy::redundant_closure` in src/submodule.rs Simplify a few methods to use the tuple variant `Some` rather than using a closure: - `Submodule::branch()` - `Submodule::url()` --- src/submodule.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/submodule.rs b/src/submodule.rs index 8bf1144791..087df2755a 100644 --- a/src/submodule.rs +++ b/src/submodule.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use std::marker; use std::mem; use std::os::raw::c_int; @@ -25,7 +23,7 @@ impl<'repo> Submodule<'repo> { /// Returns `Ok(None)` if the branch is not yet available. pub fn branch(&self) -> Result, Error> { match self.branch_bytes() { - Some(bb) => str::from_utf8(bb).map(|s| Some(s)).map_err(|e| e.into()), + Some(bb) => str::from_utf8(bb).map(Some).map_err(|e| e.into()), None => Ok(None), } } @@ -61,7 +59,7 @@ impl<'repo> Submodule<'repo> { /// Returns `Ok(None)` if the URL isn't present pub fn url(&self) -> Result, Error> { match self.opt_url_bytes() { - Some(oub) => str::from_utf8(oub).map(|s| Some(s)).map_err(|e| e.into()), + Some(oub) => str::from_utf8(oub).map(Some).map_err(|e| e.into()), None => Ok(None), } } From 205f3c35f13301ef5f4db6cbee97efdf7c6d6874 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:40:57 -0700 Subject: [PATCH 64/75] [Clippy] Address `clippy::from_over_into` in src/tag.rs Remove the `#![allow]` attribute, apparently something has changed since I initially added it and clippy no longer complains. --- src/tag.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tag.rs b/src/tag.rs index 1198b47ba2..c0b321b4b9 100644 --- a/src/tag.rs +++ b/src/tag.rs @@ -1,4 +1,3 @@ -#![allow(clippy::from_over_into)] #![allow(clippy::redundant_closure)] use std::ffi::CString; From 3003bba7e86cfa075d803adc0b0e1791a1a4e402 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:41:37 -0700 Subject: [PATCH 65/75] [Clippy] Address `clippy::redundant_closure` in src/tag.rs Simplify `Tag::message()` to use the tuple variant `Some` rather than using a closure. --- src/tag.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tag.rs b/src/tag.rs index c0b321b4b9..c15bb3fb79 100644 --- a/src/tag.rs +++ b/src/tag.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use std::ffi::CString; use std::marker; use std::mem; @@ -44,7 +42,7 @@ impl<'repo> Tag<'repo> { /// Returns Ok(None) if there is no message pub fn message(&self) -> Result, Error> { match self.message_bytes() { - Some(mb) => str::from_utf8(mb).map(|s| Some(s)).map_err(|e| e.into()), + Some(mb) => str::from_utf8(mb).map(Some).map_err(|e| e.into()), None => Ok(None), } } From de0a19ac5285bb5cc38a025b4699a263077d0d77 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:42:41 -0700 Subject: [PATCH 66/75] [Clippy] Address `clippy::missing_safety_doc` in src/transport.rs Add the missing `# Safety` heading to the existing safety documentation for `register()`. --- src/transport.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/transport.rs b/src/transport.rs index a105f71bd6..4aba382545 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -1,6 +1,5 @@ //! Interfaces for adding custom transports to libgit2 -#![allow(clippy::missing_safety_doc)] #![allow(clippy::missing_transmute_annotations)] use libc::{c_char, c_int, c_uint, c_void, size_t}; @@ -106,6 +105,8 @@ struct RawSmartSubtransportStream { /// Add a custom transport definition, to be used in addition to the built-in /// set of transports that come with libgit2. /// +/// # Safety +/// /// This function is unsafe as it needs to be externally synchronized with calls /// to creation of other transports. pub unsafe fn register(prefix: &str, factory: F) -> Result<(), Error> From b84b7cb85b7b156c623b436ade115d04c8ab89f4 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:48:56 -0700 Subject: [PATCH 67/75] [Clippy] Address `clippy::missing_transmute_annotations` in src/transport.rs Add the missing annotations to: - `subtransport_action()` - `subtransport_free()` - `stream_free()` --- src/transport.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/transport.rs b/src/transport.rs index 4aba382545..031803a7b3 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -1,7 +1,5 @@ //! Interfaces for adding custom transports to libgit2 -#![allow(clippy::missing_transmute_annotations)] - use libc::{c_char, c_int, c_uint, c_void, size_t}; use std::ffi::{CStr, CString}; use std::io; @@ -265,7 +263,10 @@ extern "C" fn subtransport_action( Ok(s) => s, Err(e) => return e.raw_set_git_error(), }; - *stream = mem::transmute(Box::new(RawSmartSubtransportStream { + *stream = mem::transmute::< + Box, + *mut raw::git_smart_subtransport_stream, + >(Box::new(RawSmartSubtransportStream { raw: raw::git_smart_subtransport_stream { subtransport: raw_transport, read: Some(stream_read), @@ -304,7 +305,7 @@ extern "C" fn subtransport_close(transport: *mut raw::git_smart_subtransport) -> // object. extern "C" fn subtransport_free(transport: *mut raw::git_smart_subtransport) { let _ = panic::wrap(|| unsafe { - mem::transmute::<_, Box>(transport); + mem::transmute::<*mut raw::git_smart_subtransport, Box>(transport); }); } @@ -368,7 +369,9 @@ unsafe fn set_err_io(e: &io::Error) { // object. extern "C" fn stream_free(stream: *mut raw::git_smart_subtransport_stream) { let _ = panic::wrap(|| unsafe { - mem::transmute::<_, Box>(stream); + mem::transmute::<*mut raw::git_smart_subtransport_stream, Box>( + stream, + ); }); } From d10b756a395c876a2d785ac435e2700a65fcc43d Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:53:01 -0700 Subject: [PATCH 68/75] [Clippy] Address `clippy::from_over_into` in src/tree.rs Convert the implementations of conversions from `TreeWalkResult` to `i32` and `raw::git_treewalk_mode` from the `Into` trait to the `From` trait. --- src/tree.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/tree.rs b/src/tree.rs index 6b72390032..c166f943f8 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,4 +1,3 @@ -#![allow(clippy::from_over_into)] #![allow(clippy::manual_unwrap_or)] use libc::{c_char, c_int, c_void}; @@ -58,20 +57,18 @@ pub enum TreeWalkResult { Abort = raw::GIT_EUSER, } -impl Into for TreeWalkResult { - fn into(self) -> i32 { - self as i32 +impl From for i32 { + fn from(val: TreeWalkResult) -> i32 { + val as i32 } } -impl Into for TreeWalkMode { - #[cfg(target_env = "msvc")] - fn into(self) -> raw::git_treewalk_mode { - self as i32 - } - #[cfg(not(target_env = "msvc"))] - fn into(self) -> raw::git_treewalk_mode { - self as u32 +// On Windows raw::git_treewalk_mode is the same as i32 and the `From` above +// works for raw::git_treewalk_mode as well +#[cfg(not(target_env = "msvc"))] +impl From for raw::git_treewalk_mode { + fn from(val: TreeWalkResult) -> raw::git_treewalk_mode { + val as u32 } } From 9ff0abd3428f39ac67959d7b66003b15d5859650 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:54:16 -0700 Subject: [PATCH 69/75] [Clippy] Address `clippy::manual_unwrap_or` in src/tree.rs Simplify `treewalk_cb()` to use `Option::unwrap_or()`. --- src/tree.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/tree.rs b/src/tree.rs index c166f943f8..841d2f10a6 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,5 +1,3 @@ -#![allow(clippy::manual_unwrap_or)] - use libc::{c_char, c_int, c_void}; use std::cmp::Ordering; use std::ffi::{CStr, CString}; @@ -209,7 +207,7 @@ extern "C" fn treewalk_cb>( entry: *const raw::git_tree_entry, payload: *mut c_void, ) -> c_int { - match panic::wrap(|| unsafe { + panic::wrap(|| unsafe { let root = match CStr::from_ptr(root).to_str() { Ok(value) => value, _ => return -1, @@ -218,10 +216,8 @@ extern "C" fn treewalk_cb>( let payload = &mut *(payload as *mut TreeWalkCbData<'_, T>); let callback = &mut payload.callback; callback(root, &entry).into() - }) { - Some(value) => value, - None => -1, - } + }) + .unwrap_or(-1) } impl<'repo> Binding for Tree<'repo> { From df57c811337d1b741cba37bb1ebd662abddff37e Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 17:56:58 -0700 Subject: [PATCH 70/75] [Clippy] Address `clippy::missing_safety_doc` in src/util.rs Add safety documentation for `Binding::from_raw()` and `Binding::from_raw_opt()`. --- src/util.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/util.rs b/src/util.rs index 5460d1e727..6293668b15 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,3 @@ -#![allow(clippy::missing_safety_doc)] #![allow(clippy::needless_lifetimes)] #![allow(clippy::needless_range_loop)] #![allow(clippy::needless_return)] @@ -34,6 +33,10 @@ pub trait Binding: Sized { type Raw; /// Build a git2 struct from its [Binding::Raw] value. + /// + /// # Safety + /// + /// The raw value (which is expected to be a pointer) must be valid. unsafe fn from_raw(raw: Self::Raw) -> Self; /// Access the [Binding::Raw] value for a struct. @@ -46,6 +49,11 @@ pub trait Binding: Sized { /// /// If the input parameter is null, then the funtion returns None. Otherwise, it /// calls [Binding::from_raw]. + /// + /// # Safety + /// + /// If the input parameter is not null, it must satisfy the safety + /// requirements of the [`Binding::from_raw()`] method. unsafe fn from_raw_opt(raw: T) -> Option where T: Copy + IsNull, From c028158b1dcfac03458d206a7fef8d438eedbb1f Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 18:00:18 -0700 Subject: [PATCH 71/75] [Clippy] Address `clippy::needless_lifetimes` in src/util.rs Remove needless lifetimes from the `IntoCString` trait implementations for - references to clonable types implementing `IntoCString` (`&T`) - references to string slices - references to `std::path::Path` objects - references to `std::ffi::OsStr` objects - references to `u8` slices --- src/util.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/util.rs b/src/util.rs index 6293668b15..03670986c1 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,3 @@ -#![allow(clippy::needless_lifetimes)] #![allow(clippy::needless_range_loop)] #![allow(clippy::needless_return)] @@ -129,13 +128,13 @@ pub trait IntoCString { fn into_c_string(self) -> Result; } -impl<'a, T: IntoCString + Clone> IntoCString for &'a T { +impl IntoCString for &T { fn into_c_string(self) -> Result { self.clone().into_c_string() } } -impl<'a> IntoCString for &'a str { +impl IntoCString for &str { fn into_c_string(self) -> Result { Ok(CString::new(self)?) } @@ -153,7 +152,7 @@ impl IntoCString for CString { } } -impl<'a> IntoCString for &'a Path { +impl IntoCString for &Path { fn into_c_string(self) -> Result { let s: &OsStr = self.as_ref(); s.into_c_string() @@ -167,7 +166,7 @@ impl IntoCString for PathBuf { } } -impl<'a> IntoCString for &'a OsStr { +impl IntoCString for &OsStr { fn into_c_string(self) -> Result { self.to_os_string().into_c_string() } @@ -191,7 +190,7 @@ impl IntoCString for OsString { } } -impl<'a> IntoCString for &'a [u8] { +impl IntoCString for &[u8] { fn into_c_string(self) -> Result { Ok(CString::new(self)?) } From 5721e9992eb3ae8e1deba1dfa82f7884af8cf379 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 18:01:08 -0700 Subject: [PATCH 72/75] [Clippy] Address `clippy::needless_range_loop` in src/util.rs Simplify the `fixup_windows_path()` function to iterate by mutable reference to the path bytes rather than using a range and reading and writing bytes by index. --- src/util.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/util.rs b/src/util.rs index 03670986c1..447cd622d0 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,3 @@ -#![allow(clippy::needless_range_loop)] #![allow(clippy::needless_return)] use libc::{c_char, c_int, size_t}; @@ -267,9 +266,9 @@ pub fn cstring_to_repo_path(path: T) -> Result { #[cfg(windows)] fn fixup_windows_path>>(path: P) -> Result { let mut bytes: Vec = path.into(); - for i in 0..bytes.len() { - if bytes[i] == b'\\' { - bytes[i] = b'/'; + for byte in &mut bytes { + if *byte == b'\\' { + *byte = b'/'; } } Ok(CString::new(bytes)?) From b987823dfbe158d2e4c538f443624c54cfb96f32 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 18:01:26 -0700 Subject: [PATCH 73/75] [Clippy] Address `clippy::needless_return` in src/util.rs Remove unneeded `return`s in `path_to_repo_path()`. --- src/util.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/util.rs b/src/util.rs index 447cd622d0..8cd1d5b167 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,3 @@ -#![allow(clippy::needless_return)] - use libc::{c_char, c_int, size_t}; use std::cmp::Ordering; use std::ffi::{CString, OsStr, OsString}; @@ -245,12 +243,10 @@ pub fn path_to_repo_path(path: &Path) -> Result { #[cfg(windows)] { match path.to_str() { - None => { - return Err(Error::from_str( - "only valid unicode paths are accepted on windows", - )) - } - Some(s) => return fixup_windows_path(s), + None => Err(Error::from_str( + "only valid unicode paths are accepted on windows", + )), + Some(s) => fixup_windows_path(s), } } #[cfg(not(windows))] From 6a59e5cca5bc143c886316f1d3278715f8f9c80a Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 18:04:10 -0700 Subject: [PATCH 74/75] [Clippy] Address `clippy::new_without_default` in src/worktree.rs Add an implementation of the `Default` trait for `WorktreeAddOptions` that delegates to `WorktreeAddOptions::new()`. Add an implementation of the `Default` trait for `WorktreePruneOptions` that delegates to `WorktreePruneOptions::new()`. --- src/worktree.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/worktree.rs b/src/worktree.rs index b99731c4e1..d2065a0d45 100644 --- a/src/worktree.rs +++ b/src/worktree.rs @@ -1,4 +1,3 @@ -#![allow(clippy::new_without_default)] #![allow(clippy::redundant_closure)] use crate::buf::Buf; @@ -193,6 +192,15 @@ impl<'a> WorktreeAddOptions<'a> { } } +impl<'a> Default for WorktreeAddOptions<'a> { + /// Creates a default set of add options. + /// + /// See [`WorktreeAddOptions::new()`] for more details. + fn default() -> Self { + Self::new() + } +} + impl WorktreePruneOptions { /// Creates a default set of pruning options /// @@ -249,6 +257,15 @@ impl WorktreePruneOptions { } } +impl Default for WorktreePruneOptions { + /// Creates a default set of pruning options + /// + /// See [`WorktreePruneOptions::new()`] for more details. + fn default() -> Self { + Self::new() + } +} + impl Binding for Worktree { type Raw = *mut raw::git_worktree; unsafe fn from_raw(ptr: *mut raw::git_worktree) -> Worktree { From 3aedab1998db7a3e717c1a33002d6edd6b73f036 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 14 Jul 2026 18:04:49 -0700 Subject: [PATCH 75/75] [Clippy] Address `clippy::redundant_closure` in src/worktree.rs Simplify `Worktree::name()` to use the tuple variant `Some` rather than using a closure. --- src/worktree.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/worktree.rs b/src/worktree.rs index d2065a0d45..e568e6d182 100644 --- a/src/worktree.rs +++ b/src/worktree.rs @@ -1,5 +1,3 @@ -#![allow(clippy::redundant_closure)] - use crate::buf::Buf; use crate::reference::Reference; use crate::repo::Repository; @@ -61,7 +59,7 @@ impl Worktree { pub fn name(&self) -> Result, Error> { let opt_bytes = unsafe { crate::opt_bytes(self, raw::git_worktree_name(self.raw)) }; match opt_bytes { - Some(ob) => str::from_utf8(ob).map(|s| Some(s)).map_err(|e| e.into()), + Some(ob) => str::from_utf8(ob).map(Some).map_err(|e| e.into()), None => Ok(None), } }