From 509fe5832ea35f6a670333da9e98ba5571419318 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 15 Feb 2022 07:45:51 -0800 Subject: [PATCH] Bump libgit2 to 1.4.0 (#806) * Bump libgit2 to 1.4.0 * Libgit2 1.4.0 fixes --- libgit2-sys/Cargo.toml | 2 +- libgit2-sys/lib.rs | 85 +++++++++++++++++++++++++----------------- libgit2-sys/libgit2 | 2 +- src/buf.rs | 2 +- src/index.rs | 3 -- src/lib.rs | 2 +- src/packbuilder.rs | 28 +++++++++++++- src/remote.rs | 57 ++++++++++++++++++++++++++++ src/status.rs | 8 ++++ 9 files changed, 147 insertions(+), 42 deletions(-) diff --git a/libgit2-sys/Cargo.toml b/libgit2-sys/Cargo.toml index dd91e9ff49..fab3dbf868 100644 --- a/libgit2-sys/Cargo.toml +++ b/libgit2-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libgit2-sys" -version = "0.12.26+1.3.0" +version = "0.12.26+1.4.0" authors = ["Josh Triplett ", "Alex Crichton "] links = "git2" build = "build.rs" diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index bade631b20..760e966f90 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -383,6 +383,7 @@ pub struct git_fetch_options { pub update_fetchhead: c_int, pub download_tags: git_remote_autotag_option_t, pub proxy_opts: git_proxy_options, + pub follow_redirects: git_remote_redirect_t, pub custom_headers: git_strarray, } @@ -609,6 +610,7 @@ pub struct git_status_options { pub flags: c_uint, pub pathspec: git_strarray, pub baseline: *mut git_tree, + pub rename_threshold: u16, } #[repr(C)] @@ -728,7 +730,7 @@ pub struct git_tree_update { #[derive(Copy, Clone)] pub struct git_buf { pub ptr: *mut c_char, - pub asize: size_t, + pub reserved: size_t, pub size: size_t, } @@ -951,6 +953,7 @@ pub struct git_push_options { pub pb_parallelism: c_uint, pub callbacks: git_remote_callbacks, pub proxy_opts: git_proxy_options, + pub follow_redirects: git_remote_redirect_t, pub custom_headers: git_strarray, } @@ -1356,55 +1359,66 @@ pub type git_transport_cb = Option< #[repr(C)] pub struct git_transport { pub version: c_uint, - pub set_callbacks: Option< + pub connect: Option< extern "C" fn( - *mut git_transport, - git_transport_message_cb, - git_transport_message_cb, - git_transport_certificate_check_cb, - *mut c_void, + transport: *mut git_transport, + url: *const c_char, + direction: c_int, + connect_opts: *const git_remote_connect_options, ) -> c_int, >, - pub set_custom_headers: Option c_int>, - pub connect: Option< + pub set_connect_opts: Option< extern "C" fn( - *mut git_transport, - *const c_char, - git_cred_acquire_cb, - *mut c_void, - *const git_proxy_options, - c_int, - c_int, + transport: *mut git_transport, + connect_opts: *const git_remote_connect_options, ) -> c_int, >, + pub capabilities: + Option c_int>, pub ls: Option< - extern "C" fn(*mut *mut *const git_remote_head, *mut size_t, *mut git_transport) -> c_int, - >, - pub push: Option< - extern "C" fn(*mut git_transport, *mut git_push, *const git_remote_callbacks) -> c_int, + extern "C" fn( + out: *mut *mut *const git_remote_head, + size: *mut size_t, + transport: *mut git_transport, + ) -> c_int, >, + pub push: Option c_int>, pub negotiate_fetch: Option< extern "C" fn( - *mut git_transport, - *mut git_repository, - *const *const git_remote_head, - size_t, + transport: *mut git_transport, + repo: *mut git_repository, + refs: *const *const git_remote_head, + count: size_t, ) -> c_int, >, pub download_pack: Option< extern "C" fn( - *mut git_transport, - *mut git_repository, - *mut git_indexer_progress, - git_indexer_progress_cb, - *mut c_void, + transport: *mut git_transport, + repo: *mut git_repository, + stats: *mut git_indexer_progress, ) -> c_int, >, - pub is_connected: Option c_int>, - pub read_flags: Option c_int>, - pub cancel: Option, - pub close: Option c_int>, - pub free: Option, + pub is_connected: Option c_int>, + pub cancel: Option, + pub close: Option c_int>, + pub free: Option, +} + +#[repr(C)] +pub struct git_remote_connect_options { + pub version: c_uint, + pub callbacks: git_remote_callbacks, + pub proxy_opts: git_proxy_options, + pub follow_redirects: git_remote_redirect_t, + pub custom_headers: git_strarray, +} + +git_enum! { + pub enum git_remote_redirect_t { + GIT_REMOTE_REDIRECT_NONE = 1 << 0, + GIT_REMOTE_REDIRECT_INITIAL = 1 << 1, + GIT_REMOTE_REDIRECT_ALL = 1 << 2, + } } #[repr(C)] @@ -1891,6 +1905,7 @@ pub struct git_worktree_add_options { pub version: c_uint, pub lock: c_int, pub reference: *mut git_reference, + pub checkout_options: git_checkout_options, } pub const GIT_WORKTREE_ADD_OPTIONS_VERSION: c_uint = 1; @@ -3727,7 +3742,9 @@ extern "C" { progress_cb: git_indexer_progress_cb, progress_cb_payload: *mut c_void, ) -> c_int; + #[deprecated = "use `git_packbuilder_name` to retrieve the filename"] pub fn git_packbuilder_hash(pb: *mut git_packbuilder) -> *const git_oid; + pub fn git_packbuilder_name(pb: *mut git_packbuilder) -> *const c_char; pub fn git_packbuilder_foreach( pb: *mut git_packbuilder, cb: git_packbuilder_foreach_cb, diff --git a/libgit2-sys/libgit2 b/libgit2-sys/libgit2 index b7bad55e4b..1d5b9bd86d 160000 --- a/libgit2-sys/libgit2 +++ b/libgit2-sys/libgit2 @@ -1 +1 @@ -Subproject commit b7bad55e4bb0a285b073ba5e02b01d3f522fc95d +Subproject commit 1d5b9bd86dccc7347aaadf5e3ab122eed9413404 diff --git a/src/buf.rs b/src/buf.rs index 0ab560ce80..fd2bcbf96f 100644 --- a/src/buf.rs +++ b/src/buf.rs @@ -28,7 +28,7 @@ impl Buf { Binding::from_raw(&mut raw::git_buf { ptr: ptr::null_mut(), size: 0, - asize: 0, + reserved: 0, } as *mut _) } } diff --git a/src/index.rs b/src/index.rs index 22334d0c19..b2e8dfe5c1 100644 --- a/src/index.rs +++ b/src/index.rs @@ -849,9 +849,6 @@ mod tests { #[test] fn add_then_read() { - let mut index = Index::new().unwrap(); - assert!(index.add(&entry()).is_err()); - let mut index = Index::new().unwrap(); let mut e = entry(); e.path = b"foobar".to_vec(); diff --git a/src/lib.rs b/src/lib.rs index b7f262e94c..1ba08d21de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -120,7 +120,7 @@ pub use crate::reference::{Reference, ReferenceNames, References}; pub use crate::reflog::{Reflog, ReflogEntry, ReflogIter}; pub use crate::refspec::Refspec; pub use crate::remote::{ - FetchOptions, PushOptions, Refspecs, Remote, RemoteConnection, RemoteHead, + FetchOptions, PushOptions, Refspecs, Remote, RemoteConnection, RemoteHead, RemoteRedirect, }; pub use crate::remote_callbacks::{Credentials, RemoteCallbacks}; pub use crate::remote_callbacks::{TransportMessage, UpdateTips}; diff --git a/src/packbuilder.rs b/src/packbuilder.rs index e20bf2a97c..9b93e7654b 100644 --- a/src/packbuilder.rs +++ b/src/packbuilder.rs @@ -2,6 +2,7 @@ use libc::{c_int, c_uint, c_void, size_t}; use std::marker; use std::ptr; use std::slice; +use std::str; use crate::util::Binding; use crate::{panic, raw, Buf, Error, Oid, Repository, Revwalk}; @@ -160,6 +161,8 @@ impl<'repo> PackBuilder<'repo> { /// Get the packfile's hash. A packfile's name is derived from the sorted /// hashing of all object names. This is only correct after the packfile /// has been written. + #[deprecated = "use `name()` to retrieve the filename"] + #[allow(deprecated)] pub fn hash(&self) -> Option { if self.object_count() == 0 { unsafe { Some(Binding::from_raw(raw::git_packbuilder_hash(self.raw))) } @@ -167,6 +170,25 @@ impl<'repo> PackBuilder<'repo> { None } } + + /// Get the unique name for the resulting packfile. + /// + /// The packfile's name is derived from the packfile's content. This is only + /// correct after the packfile has been written. + /// + /// Returns `None` if the packfile has not been written or if the name is + /// not valid utf-8. + pub fn name(&self) -> Option<&str> { + self.name_bytes().and_then(|s| str::from_utf8(s).ok()) + } + + /// Get the unique name for the resulting packfile, in bytes. + /// + /// The packfile's name is derived from the packfile's content. This is only + /// correct after the packfile has been written. + pub fn name_bytes(&self) -> Option<&[u8]> { + unsafe { crate::opt_bytes(self, raw::git_packbuilder_name(self.raw)) } + } } impl<'repo> Binding for PackBuilder<'repo> { @@ -284,7 +306,11 @@ mod tests { let mut builder = t!(repo.packbuilder()); let mut buf = Buf::new(); t!(builder.write_buf(&mut buf)); - assert!(builder.hash().unwrap().is_zero()); + #[allow(deprecated)] + { + assert!(builder.hash().unwrap().is_zero()); + } + assert!(builder.name().is_none()); assert_eq!(&*buf, &*empty_pack_header()); } diff --git a/src/remote.rs b/src/remote.rs index b1cc4d3693..59afa1363a 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -44,6 +44,7 @@ pub struct FetchOptions<'cb> { prune: FetchPrune, update_fetchhead: bool, download_tags: AutotagOption, + follow_redirects: RemoteRedirect, custom_headers: Vec, custom_headers_ptrs: Vec<*const c_char>, } @@ -53,6 +54,7 @@ pub struct PushOptions<'cb> { callbacks: Option>, proxy: Option>, pb_parallelism: u32, + follow_redirects: RemoteRedirect, custom_headers: Vec, custom_headers_ptrs: Vec<*const c_char>, } @@ -64,6 +66,21 @@ pub struct RemoteConnection<'repo, 'connection, 'cb> { remote: &'connection mut Remote<'repo>, } +/// Remote redirection settings; whether redirects to another host are +/// permitted. +/// +/// By default, git will follow a redirect on the initial request +/// (`/info/refs`), but not subsequent requests. +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. + Initial, + /// Allow redirects at any stage in the fetch or push. + All, +} + pub fn remote_into_raw(remote: Remote<'_>) -> *mut raw::git_remote { let ret = remote.raw; mem::forget(remote); @@ -479,6 +496,7 @@ impl<'cb> FetchOptions<'cb> { prune: FetchPrune::Unspecified, update_fetchhead: true, download_tags: AutotagOption::Unspecified, + follow_redirects: RemoteRedirect::Initial, custom_headers: Vec::new(), custom_headers_ptrs: Vec::new(), } @@ -519,6 +537,16 @@ impl<'cb> FetchOptions<'cb> { self } + /// Set remote redirection settings; whether redirects to another host are + /// permitted. + /// + /// By default, git will follow a redirect on the initial request + /// (`/info/refs`), but not subsequent requests. + pub fn follow_redirects(&mut self, redirect: RemoteRedirect) -> &mut Self { + self.follow_redirects = redirect; + self + } + /// Set extra headers for this fetch operation. pub fn custom_headers(&mut self, custom_headers: &[&str]) -> &mut Self { self.custom_headers = custom_headers @@ -552,6 +580,7 @@ impl<'cb> Binding for FetchOptions<'cb> { prune: crate::call::convert(&self.prune), update_fetchhead: crate::call::convert(&self.update_fetchhead), download_tags: crate::call::convert(&self.download_tags), + follow_redirects: self.follow_redirects.raw(), custom_headers: git_strarray { count: self.custom_headers_ptrs.len(), strings: self.custom_headers_ptrs.as_ptr() as *mut _, @@ -573,6 +602,7 @@ impl<'cb> PushOptions<'cb> { callbacks: None, proxy: None, pb_parallelism: 1, + follow_redirects: RemoteRedirect::Initial, custom_headers: Vec::new(), custom_headers_ptrs: Vec::new(), } @@ -601,6 +631,16 @@ impl<'cb> PushOptions<'cb> { self } + /// Set remote redirection settings; whether redirects to another host are + /// permitted. + /// + /// By default, git will follow a redirect on the initial request + /// (`/info/refs`), but not subsequent requests. + pub fn follow_redirects(&mut self, redirect: RemoteRedirect) -> &mut Self { + self.follow_redirects = redirect; + self + } + /// Set extra headers for this push operation. pub fn custom_headers(&mut self, custom_headers: &[&str]) -> &mut Self { self.custom_headers = custom_headers @@ -632,6 +672,7 @@ impl<'cb> Binding for PushOptions<'cb> { .map(|m| m.raw()) .unwrap_or_else(|| ProxyOptions::new().raw()), pb_parallelism: self.pb_parallelism as libc::c_uint, + follow_redirects: self.follow_redirects.raw(), custom_headers: git_strarray { count: self.custom_headers_ptrs.len(), strings: self.custom_headers_ptrs.as_ptr() as *mut _, @@ -674,6 +715,22 @@ 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 { + RemoteRedirect::None => raw::GIT_REMOTE_REDIRECT_NONE, + RemoteRedirect::Initial => raw::GIT_REMOTE_REDIRECT_INITIAL, + RemoteRedirect::All => raw::GIT_REMOTE_REDIRECT_ALL, + } + } +} + #[cfg(test)] mod tests { use crate::{AutotagOption, PushOptions}; diff --git a/src/status.rs b/src/status.rs index d843458589..d9bfc07342 100644 --- a/src/status.rs +++ b/src/status.rs @@ -216,6 +216,14 @@ impl StatusOptions { self.flag(raw::GIT_STATUS_OPT_INCLUDE_UNREADABLE_AS_UNTRACKED, include) } + /// Set threshold above which similar files will be considered renames. + /// + /// This is equivalent to the `-M` option. Defaults to 50. + pub fn rename_threshold(&mut self, threshold: u16) -> &mut StatusOptions { + self.raw.rename_threshold = threshold; + self + } + /// Get a pointer to the inner list of status options. /// /// This function is unsafe as the returned structure has interior pointers