From b534e13f38c65f1c70b90f6510872f28d3520023 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Fri, 1 Mar 2024 23:42:48 +0800 Subject: [PATCH 01/21] libgit2: Bump to v1.8.0 --- libgit2-sys/build.rs | 2 +- libgit2-sys/libgit2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libgit2-sys/build.rs b/libgit2-sys/build.rs index 88fce00d6e..6f85060512 100644 --- a/libgit2-sys/build.rs +++ b/libgit2-sys/build.rs @@ -7,7 +7,7 @@ use std::process::Command; /// Tries to use system libgit2 and emits necessary build script instructions. fn try_system_libgit2() -> Result { let mut cfg = pkg_config::Config::new(); - match cfg.range_version("1.7.2".."1.8.0").probe("libgit2") { + match cfg.range_version("1.8.0".."1.9.0").probe("libgit2") { Ok(lib) => { for include in &lib.include_paths { println!("cargo:root={}", include.display()); diff --git a/libgit2-sys/libgit2 b/libgit2-sys/libgit2 index a418d9d4ab..d74d491481 160000 --- a/libgit2-sys/libgit2 +++ b/libgit2-sys/libgit2 @@ -1 +1 @@ -Subproject commit a418d9d4ab87bae16b87d8f37143a4687ae0e4b2 +Subproject commit d74d491481831ddcd23575d376e56d2197e95910 From 7fa64c619f67cb6035330bd71b798b8e114f6f02 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sat, 2 Mar 2024 21:08:50 +0800 Subject: [PATCH 02/21] remote: Update struct representation for `git_push_options` See https://github.com/libgit2/libgit2/pull/6439. --- libgit2-sys/lib.rs | 1 + src/remote.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 3de6881842..5d997bc059 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -981,6 +981,7 @@ pub struct git_push_options { pub proxy_opts: git_proxy_options, pub follow_redirects: git_remote_redirect_t, pub custom_headers: git_strarray, + pub remote_push_options: git_strarray, } pub type git_tag_foreach_cb = diff --git a/src/remote.rs b/src/remote.rs index a15a095010..1909766c76 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -58,6 +58,8 @@ pub struct PushOptions<'cb> { follow_redirects: RemoteRedirect, custom_headers: Vec, custom_headers_ptrs: Vec<*const c_char>, + remote_push_options: Vec, + remote_push_options_ptrs: Vec<*const c_char>, } /// Holds callbacks for a connection to a `Remote`. Disconnects when dropped @@ -628,6 +630,8 @@ impl<'cb> PushOptions<'cb> { follow_redirects: RemoteRedirect::Initial, custom_headers: Vec::new(), custom_headers_ptrs: Vec::new(), + remote_push_options: Vec::new(), + remote_push_options_ptrs: Vec::new(), } } @@ -673,6 +677,20 @@ impl<'cb> PushOptions<'cb> { self.custom_headers_ptrs = self.custom_headers.iter().map(|s| s.as_ptr()).collect(); self } + + /// Set "push options" to deliver to the remote. + pub fn remote_push_options(&mut self, remote_push_options: &[&str]) -> &mut Self { + self.remote_push_options = remote_push_options + .iter() + .map(|&s| CString::new(s).unwrap()) + .collect(); + self.remote_push_options_ptrs = self + .remote_push_options + .iter() + .map(|s| s.as_ptr()) + .collect(); + self + } } impl<'cb> Binding for PushOptions<'cb> { @@ -700,6 +718,10 @@ impl<'cb> Binding for PushOptions<'cb> { count: self.custom_headers_ptrs.len(), strings: self.custom_headers_ptrs.as_ptr() as *mut _, }, + remote_push_options: git_strarray { + count: self.remote_push_options.len(), + strings: self.remote_push_options_ptrs.as_ptr() as *mut _, + }, } } } From cb8bbc611390764e3d7e6397759864dc2f67833d Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sat, 2 Mar 2024 22:28:11 +0800 Subject: [PATCH 03/21] lib: Add `RemoteUpdateFlags` bitflag --- libgit2-sys/lib.rs | 7 +++++++ src/lib.rs | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 5d997bc059..5f72b0c39a 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -366,6 +366,13 @@ pub struct git_indexer_options { pub type git_remote_ready_cb = Option c_int>; +git_enum! { + pub enum git_remote_update_flags { + GIT_REMOTE_UPDATE_FETCHHEAD = 1 << 0, + GIT_REMOTE_UPDATE_REPORT_UNCHANGED = 1 << 1, + } +} + #[repr(C)] pub struct git_remote_callbacks { pub version: c_uint, diff --git a/src/lib.rs b/src/lib.rs index 3dd6fe92ee..48ec7c01cf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -662,6 +662,17 @@ bitflags! { } } +bitflags! { + /// How to handle reference updates. + #[derive(Clone, Copy, Debug, Eq, PartialEq)] + pub struct RemoteUpdateFlags: u32 { + /// Write the fetch results to FETCH_HEAD. + const UPDATE_FETCHHEAD = raw::GIT_REMOTE_UPDATE_FETCHHEAD as u32; + /// Report unchanged tips in the update_tips callback. + const REPORT_UNCHANGED = raw::GIT_REMOTE_UPDATE_REPORT_UNCHANGED as u32; + } +} + #[cfg(test)] #[macro_use] mod test; From 6cb97bcba835f349ac9cc38b105e8b13115b8e0d Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sat, 2 Mar 2024 22:28:11 +0800 Subject: [PATCH 04/21] remote: Update `git_remote_update_tips` to use `RemoteUpdateFlags` --- examples/fetch.rs | 9 +++++++-- libgit2-sys/lib.rs | 2 +- src/remote.rs | 23 +++++++++++++++++------ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/examples/fetch.rs b/examples/fetch.rs index f3a11dffbd..af4aa98eb9 100644 --- a/examples/fetch.rs +++ b/examples/fetch.rs @@ -15,7 +15,7 @@ #![deny(warnings)] use clap::Parser; -use git2::{AutotagOption, FetchOptions, RemoteCallbacks, Repository}; +use git2::{AutotagOption, FetchOptions, RemoteCallbacks, RemoteUpdateFlags, Repository}; use std::io::{self, Write}; use std::str; @@ -113,7 +113,12 @@ fn run(args: &Args) -> Result<(), git2::Error> { // commits. This may be needed even if there was no packfile to download, // which can happen e.g. when the branches have been changed but all the // needed objects are available locally. - remote.update_tips(None, true, AutotagOption::Unspecified, None)?; + remote.update_tips( + None, + RemoteUpdateFlags::UPDATE_FETCHHEAD, + AutotagOption::Unspecified, + None, + )?; Ok(()) } diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 5f72b0c39a..ff1b6444e9 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -2334,7 +2334,7 @@ extern "C" { pub fn git_remote_update_tips( remote: *mut git_remote, callbacks: *const git_remote_callbacks, - update_fetchead: c_int, + update_flags: c_uint, download_tags: git_remote_autotag_option_t, reflog_message: *const c_char, ) -> c_int; diff --git a/src/remote.rs b/src/remote.rs index 1909766c76..c52db6e287 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -3,6 +3,7 @@ use std::iter::FusedIterator; use std::marker; use std::mem; use std::ops::Range; +use std::os::raw::c_uint; use std::ptr; use std::slice; use std::str; @@ -11,7 +12,7 @@ use std::{ffi::CString, os::raw::c_char}; use crate::string_array::StringArray; use crate::util::Binding; use crate::{call, raw, Buf, Direction, Error, FetchPrune, Oid, ProxyOptions, Refspec}; -use crate::{AutotagOption, Progress, RemoteCallbacks, Repository}; +use crate::{AutotagOption, Progress, RemoteCallbacks, RemoteUpdateFlags, Repository}; /// A structure representing a [remote][1] of a git repository. /// @@ -320,7 +321,7 @@ impl<'repo> Remote<'repo> { pub fn update_tips( &mut self, callbacks: Option<&mut RemoteCallbacks<'_>>, - update_fetchhead: bool, + update_flags: RemoteUpdateFlags, download_tags: AutotagOption, msg: Option<&str>, ) -> Result<(), Error> { @@ -330,7 +331,7 @@ impl<'repo> Remote<'repo> { try_call!(raw::git_remote_update_tips( self.raw, cbs.as_ref(), - update_fetchhead, + update_flags.bits() as c_uint, download_tags, msg )); @@ -778,7 +779,7 @@ impl RemoteRedirect { #[cfg(test)] mod tests { - use crate::{AutotagOption, PushOptions}; + use crate::{AutotagOption, PushOptions, RemoteUpdateFlags}; use crate::{Direction, FetchOptions, Remote, RemoteCallbacks, Repository}; use std::cell::Cell; use tempfile::TempDir; @@ -867,10 +868,20 @@ mod tests { origin.fetch(&[] as &[&str], None, None).unwrap(); origin.fetch(&[] as &[&str], None, Some("foo")).unwrap(); origin - .update_tips(None, true, AutotagOption::Unspecified, None) + .update_tips( + None, + RemoteUpdateFlags::UPDATE_FETCHHEAD, + AutotagOption::Unspecified, + None, + ) .unwrap(); origin - .update_tips(None, true, AutotagOption::All, Some("foo")) + .update_tips( + None, + RemoteUpdateFlags::UPDATE_FETCHHEAD, + AutotagOption::All, + Some("foo"), + ) .unwrap(); t!(repo.remote_add_fetch("origin", "foo")); From 3433353e659e284cb86c0fd230afeaf774244e43 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sat, 2 Mar 2024 22:28:11 +0800 Subject: [PATCH 05/21] remote: Update `git_fetch_options` to use `RemoteUpdateFlags` This includes a hacky solution since the `update_flag` field uses C bitfields, which are not natively supported in Rust. --- libgit2-sys/lib.rs | 2 +- src/remote.rs | 22 ++++++++++++++++++---- systest/build.rs | 4 +++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index ff1b6444e9..f5d4acd76d 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -398,7 +398,7 @@ pub struct git_fetch_options { pub version: c_int, pub callbacks: git_remote_callbacks, pub prune: git_fetch_prune_t, - pub update_fetchhead: c_int, + pub update_flags: c_uint, pub download_tags: git_remote_autotag_option_t, pub proxy_opts: git_proxy_options, pub depth: c_int, diff --git a/src/remote.rs b/src/remote.rs index c52db6e287..0211493507 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -44,7 +44,7 @@ pub struct FetchOptions<'cb> { depth: i32, proxy: Option>, prune: FetchPrune, - update_fetchhead: bool, + update_flags: RemoteUpdateFlags, download_tags: AutotagOption, follow_redirects: RemoteRedirect, custom_headers: Vec, @@ -507,7 +507,7 @@ impl<'cb> FetchOptions<'cb> { callbacks: None, proxy: None, prune: FetchPrune::Unspecified, - update_fetchhead: true, + update_flags: RemoteUpdateFlags::UPDATE_FETCHHEAD, download_tags: AutotagOption::Unspecified, follow_redirects: RemoteRedirect::Initial, custom_headers: Vec::new(), @@ -538,7 +538,17 @@ impl<'cb> FetchOptions<'cb> { /// /// Defaults to `true`. pub fn update_fetchhead(&mut self, update: bool) -> &mut Self { - self.update_fetchhead = update; + self.update_flags + .set(RemoteUpdateFlags::UPDATE_FETCHHEAD, update); + self + } + + /// Set whether to report unchanged tips in the update_tips callback. + /// + /// Defaults to `false`. + pub fn report_unchanged(&mut self, update: bool) -> &mut Self { + self.update_flags + .set(RemoteUpdateFlags::REPORT_UNCHANGED, update); self } @@ -603,7 +613,11 @@ impl<'cb> Binding for FetchOptions<'cb> { .map(|m| m.raw()) .unwrap_or_else(|| ProxyOptions::new().raw()), prune: crate::call::convert(&self.prune), - update_fetchhead: crate::call::convert(&self.update_fetchhead), + // HACK: `libgit2` uses C bitfields, which do not have a guaranteed memory layout. + // Reversing the bits ensures that the bitfields are set whether the bits are laid out + // from left to right or right to left, but will not work on other memory layouts. + update_flags: (self.update_flags.bits() | self.update_flags.bits().reverse_bits()) + as c_uint, download_tags: crate::call::convert(&self.download_tags), depth: self.depth, follow_redirects: self.follow_redirects.raw(), diff --git a/systest/build.rs b/systest/build.rs index bb34d9de80..5b2dac8016 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -24,7 +24,9 @@ fn main() { // this field is marked as const which ctest complains about (struct_ == "git_rebase_operation" && f == "id") || // the real name of this field is ref but that is a reserved keyword - (struct_ == "git_worktree_add_options" && f == "reference") + (struct_ == "git_worktree_add_options" && f == "reference") || + // the `update_flags` field consists of 2 bitfields + (struct_ == "git_fetch_options" && f == "update_flags") }); cfg.skip_signededness(|s| match s { s if s.ends_with("_cb") => true, From b7662914df9937e74ce1cc8e5a7cc8fa02bc36c2 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sat, 2 Mar 2024 22:29:13 +0800 Subject: [PATCH 06/21] libgit2-sys: Update struct representation for `git_config_entry` --- libgit2-sys/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index f5d4acd76d..9ae74c4718 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -862,10 +862,11 @@ pub struct git_index_time { pub struct git_config_entry { pub name: *const c_char, pub value: *const c_char, + pub backend_type: *const c_char, + pub origin_path: *const c_char, pub include_depth: c_uint, pub level: git_config_level_t, pub free: Option, - pub payload: *mut c_void, } git_enum! { From 202b38c0bfabedecc884331d81af2782022f33f9 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sat, 2 Mar 2024 22:29:13 +0800 Subject: [PATCH 07/21] libgit2-sys: Add new git error code enums --- libgit2-sys/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 9ae74c4718..a317183d5d 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -198,6 +198,10 @@ git_enum! { GIT_EINDEXDIRTY = -34, GIT_EAPPLYFAIL = -35, GIT_EOWNER = -36, + GIT_TIMEOUT = -37, + GIT_EUNCHANGED = -38, + GIT_ENOTSUPPORTED = -39, + GIT_EREADONLY = -40, } } From ee69ec57450d64695ab2412cb930fd3a66ac13a1 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sun, 3 Mar 2024 02:49:05 +0800 Subject: [PATCH 08/21] repo: Update `git_commit_create` and `git_commit_create_buffer` --- libgit2-sys/lib.rs | 4 ++-- src/repo.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index a317183d5d..be6a092ebc 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -2895,7 +2895,7 @@ extern "C" { message: *const c_char, tree: *const git_tree, parent_count: size_t, - parents: *mut *const git_commit, + parents: *const *mut git_commit, ) -> c_int; pub fn git_commit_create_buffer( out: *mut git_buf, @@ -2906,7 +2906,7 @@ extern "C" { message: *const c_char, tree: *const git_tree, parent_count: size_t, - parents: *mut *const git_commit, + parents: *const *mut git_commit, ) -> c_int; pub fn git_commit_header_field( out: *mut git_buf, diff --git a/src/repo.rs b/src/repo.rs index b41b42480c..db00545e4f 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1290,9 +1290,9 @@ impl Repository { parents: &[&Commit<'_>], ) -> Result { let update_ref = crate::opt_cstr(update_ref)?; - let mut parent_ptrs = parents + let parent_ptrs = parents .iter() - .map(|p| p.raw() as *const raw::git_commit) + .map(|p| p.raw() as *mut raw::git_commit) .collect::>(); let message = CString::new(message)?; let mut raw = raw::git_oid { @@ -1309,7 +1309,7 @@ impl Repository { message, tree.raw(), parents.len() as size_t, - parent_ptrs.as_mut_ptr() + parent_ptrs.as_ptr() )); Ok(Binding::from_raw(&raw as *const _)) } @@ -1328,9 +1328,9 @@ impl Repository { tree: &Tree<'_>, parents: &[&Commit<'_>], ) -> Result { - let mut parent_ptrs = parents + let parent_ptrs = parents .iter() - .map(|p| p.raw() as *const raw::git_commit) + .map(|p| p.raw() as *mut raw::git_commit) .collect::>(); let message = CString::new(message)?; let buf = Buf::new(); @@ -1344,7 +1344,7 @@ impl Repository { message, tree.raw(), parents.len() as size_t, - parent_ptrs.as_mut_ptr() + parent_ptrs.as_ptr() )); Ok(buf) } From 8b5fba7452c13b9bd967a71f9a649721152b76f1 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Fri, 22 Mar 2024 19:32:02 +0800 Subject: [PATCH 09/21] lib: Add `ConfigLevel::Worktree` --- libgit2-sys/lib.rs | 3 ++- src/call.rs | 1 + src/lib.rs | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index be6a092ebc..aece88991c 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -880,7 +880,8 @@ git_enum! { GIT_CONFIG_LEVEL_XDG = 3, GIT_CONFIG_LEVEL_GLOBAL = 4, GIT_CONFIG_LEVEL_LOCAL = 5, - GIT_CONFIG_LEVEL_APP = 6, + GIT_CONFIG_LEVEL_WORKTREE = 6, + GIT_CONFIG_LEVEL_APP = 7, GIT_CONFIG_HIGHEST_LEVEL = -1, } } diff --git a/src/call.rs b/src/call.rs index 95350d2690..a18f05da91 100644 --- a/src/call.rs +++ b/src/call.rs @@ -166,6 +166,7 @@ mod impls { ConfigLevel::XDG => raw::GIT_CONFIG_LEVEL_XDG, ConfigLevel::Global => raw::GIT_CONFIG_LEVEL_GLOBAL, ConfigLevel::Local => raw::GIT_CONFIG_LEVEL_LOCAL, + ConfigLevel::Worktree => raw::GIT_CONFIG_LEVEL_WORKTREE, ConfigLevel::App => raw::GIT_CONFIG_LEVEL_APP, ConfigLevel::Highest => raw::GIT_CONFIG_HIGHEST_LEVEL, } diff --git a/src/lib.rs b/src/lib.rs index 48ec7c01cf..689dcfb37e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -385,6 +385,8 @@ pub enum ConfigLevel { Global, /// Repository specific config, e.g. $PWD/.git/config Local, + /// Worktree specific configuration file, e.g. $GIT_DIR/config.worktree + Worktree, /// Application specific configuration file App, /// Highest level available @@ -974,6 +976,7 @@ impl ConfigLevel { raw::GIT_CONFIG_LEVEL_XDG => ConfigLevel::XDG, raw::GIT_CONFIG_LEVEL_GLOBAL => ConfigLevel::Global, raw::GIT_CONFIG_LEVEL_LOCAL => ConfigLevel::Local, + raw::GIT_CONFIG_LEVEL_WORKTREE => ConfigLevel::Worktree, raw::GIT_CONFIG_LEVEL_APP => ConfigLevel::App, raw::GIT_CONFIG_HIGHEST_LEVEL => ConfigLevel::Highest, n => panic!("unknown config level: {}", n), From c074cabdbf1108492e0f53acf4b9fc9bd726d948 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Fri, 22 Mar 2024 19:32:02 +0800 Subject: [PATCH 10/21] worktree: Update struct representation for `git_worktree_add_options` --- libgit2-sys/lib.rs | 1 + src/worktree.rs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index aece88991c..2ea565284f 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -1977,6 +1977,7 @@ git_enum! { pub struct git_worktree_add_options { pub version: c_uint, pub lock: c_int, + pub checkout_existing: c_int, pub reference: *mut git_reference, pub checkout_options: git_checkout_options, } diff --git a/src/worktree.rs b/src/worktree.rs index 569b639cf9..fc32902db1 100644 --- a/src/worktree.rs +++ b/src/worktree.rs @@ -165,6 +165,12 @@ impl<'a> WorktreeAddOptions<'a> { self } + /// If enabled, this will checkout the existing branch matching the worktree name. + pub fn checkout_existing(&mut self, enabled: bool) -> &mut WorktreeAddOptions<'a> { + self.raw.checkout_existing = enabled as c_int; + self + } + /// reference to use for the new worktree HEAD pub fn reference( &mut self, From 3bde019aed6780bc47e96c3509f68d7a1246dde9 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sat, 2 Mar 2024 22:37:42 +0800 Subject: [PATCH 11/21] libgit2-sys: Fix build issue with libssh2 --- libgit2-sys/build.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libgit2-sys/build.rs b/libgit2-sys/build.rs index 6f85060512..3cece57076 100644 --- a/libgit2-sys/build.rs +++ b/libgit2-sys/build.rs @@ -180,7 +180,8 @@ The build is now aborting. To disable, unset the variable or use `LIBGIT2_NO_VEN cfg.include(path); } features.push_str("#define GIT_SSH 1\n"); - features.push_str("#define GIT_SSH_MEMORY_CREDENTIALS 1\n"); + features.push_str("#define GIT_SSH_LIBSSH2 1\n"); + features.push_str("#define GIT_SSH_LIBSSH2_MEMORY_CREDENTIALS 1\n"); } if https { features.push_str("#define GIT_HTTPS 1\n"); From 26853d90ffc029cb39c8d33781a99ba24a2d2f17 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Fri, 22 Mar 2024 20:48:27 +0800 Subject: [PATCH 12/21] tests: Account for new `worktreeconfig` extension added --- tests/add_extensions.rs | 6 ++++-- tests/get_extensions.rs | 4 +++- tests/remove_extensions.rs | 9 ++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/add_extensions.rs b/tests/add_extensions.rs index 57c0eb9762..f3e2c42ae3 100644 --- a/tests/add_extensions.rs +++ b/tests/add_extensions.rs @@ -11,11 +11,13 @@ fn test_add_extensions() -> Result<(), Error> { let extensions = unsafe { get_extensions() }?; - assert_eq!(extensions.len(), 3); + assert_eq!(extensions.len(), 4); assert_eq!(extensions.get(0), Some("custom")); - // The objectformat extension was added in 1.6 assert_eq!(extensions.get(1), Some("noop")); + // The objectformat extension was added in 1.6 assert_eq!(extensions.get(2), Some("objectformat")); + // The worktreeconfig extension was added in 1.8 + assert_eq!(extensions.get(3), Some("worktreeconfig")); Ok(()) } diff --git a/tests/get_extensions.rs b/tests/get_extensions.rs index d8dd55fe0a..3a9148f20b 100644 --- a/tests/get_extensions.rs +++ b/tests/get_extensions.rs @@ -7,10 +7,12 @@ use git2::Error; fn test_get_extensions() -> Result<(), Error> { let extensions = unsafe { get_extensions() }?; - assert_eq!(extensions.len(), 2); + assert_eq!(extensions.len(), 3); assert_eq!(extensions.get(0), Some("noop")); // The objectformat extension was added in 1.6 assert_eq!(extensions.get(1), Some("objectformat")); + // The worktreeconfig extension was added in 1.8 + assert_eq!(extensions.get(2), Some("worktreeconfig")); Ok(()) } diff --git a/tests/remove_extensions.rs b/tests/remove_extensions.rs index 5f632a8809..5384daea5c 100644 --- a/tests/remove_extensions.rs +++ b/tests/remove_extensions.rs @@ -6,7 +6,14 @@ use git2::Error; #[test] fn test_remove_extensions() -> Result<(), Error> { unsafe { - set_extensions(&["custom", "!ignore", "!noop", "!objectformat", "other"])?; + set_extensions(&[ + "custom", + "!ignore", + "!noop", + "!objectformat", + "!worktreeconfig", + "other", + ])?; } let extensions = unsafe { get_extensions() }?; From eeb04b97cbdabb58c3dc23e18758cf7fefc3c6c2 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Fri, 22 Mar 2024 20:48:27 +0800 Subject: [PATCH 13/21] cred/tests: Account for changes in `git_config` --- src/cred.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cred.rs b/src/cred.rs index fc4af1e4eb..fc0b941935 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -482,7 +482,7 @@ mod test { macro_rules! test_cfg( ($($k:expr => $v:expr),*) => ({ let td = TempDir::new().unwrap(); let mut cfg = Config::new().unwrap(); - cfg.add_file(&td.path().join("cfg"), ConfigLevel::Highest, false).unwrap(); + cfg.add_file(&td.path().join("cfg"), ConfigLevel::App, false).unwrap(); $(cfg.set_str($k, $v).unwrap();)* cfg }) ); From e21a5de2bcc6bab0545674e40790b75a89e7000b Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sun, 24 Mar 2024 04:57:26 +0800 Subject: [PATCH 14/21] test: Fix `realpath` failure on Windows --- src/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test.rs b/src/test.rs index c1ff1de21f..57a590f519 100644 --- a/src/test.rs +++ b/src/test.rs @@ -66,7 +66,7 @@ pub fn worktrees_env_init(repo: &Repository) -> (TempDir, Branch<'_>) { #[cfg(windows)] pub fn realpath(original: &Path) -> io::Result { - Ok(original.to_path_buf()) + Ok(original.canonicalize()?.to_path_buf()) } #[cfg(unix)] pub fn realpath(original: &Path) -> io::Result { From 2a617b683a1acc63ce3f2952b3256ae8663e4b77 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sun, 3 Mar 2024 02:49:26 +0800 Subject: [PATCH 15/21] systest: Add `errors.h` header file --- systest/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/systest/build.rs b/systest/build.rs index 5b2dac8016..0a22a5b396 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -7,6 +7,7 @@ fn main() { cfg.include(PathBuf::from(root).join("include")); } cfg.header("git2.h") + .header("git2/sys/errors.h") .header("git2/sys/transport.h") .header("git2/sys/refs.h") .header("git2/sys/refdb_backend.h") From a65e7a45f0db8bf3dcf4c9624ec5016df3b28a8f Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Fri, 22 Mar 2024 19:32:02 +0800 Subject: [PATCH 16/21] libgit2-sys: Bump versions --- Cargo.toml | 2 +- libgit2-sys/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6359ac058c..987479b633 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ url = "2.0" bitflags = "2.1.0" libc = "0.2" log = "0.4.8" -libgit2-sys = { path = "libgit2-sys", version = "0.16.2" } +libgit2-sys = { path = "libgit2-sys", version = "0.17.0" } [target."cfg(all(unix, not(target_os = \"macos\")))".dependencies] openssl-sys = { version = "0.9.45", optional = true } diff --git a/libgit2-sys/Cargo.toml b/libgit2-sys/Cargo.toml index 67eaf8dc8e..b3adf89ddc 100644 --- a/libgit2-sys/Cargo.toml +++ b/libgit2-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libgit2-sys" -version = "0.16.2+1.7.2" +version = "0.17.0+1.8.0" authors = ["Josh Triplett ", "Alex Crichton "] links = "git2" build = "build.rs" From 449c6bec33477e57b6c84bcf57297409798dfc73 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Wed, 15 May 2024 17:00:20 +0800 Subject: [PATCH 17/21] libgit2: Bump to v1.8.1 --- libgit2-sys/Cargo.toml | 2 +- libgit2-sys/build.rs | 2 +- libgit2-sys/libgit2 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libgit2-sys/Cargo.toml b/libgit2-sys/Cargo.toml index b3adf89ddc..ff911c99f5 100644 --- a/libgit2-sys/Cargo.toml +++ b/libgit2-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libgit2-sys" -version = "0.17.0+1.8.0" +version = "0.17.0+1.8.1" authors = ["Josh Triplett ", "Alex Crichton "] links = "git2" build = "build.rs" diff --git a/libgit2-sys/build.rs b/libgit2-sys/build.rs index 3cece57076..1fd1caea41 100644 --- a/libgit2-sys/build.rs +++ b/libgit2-sys/build.rs @@ -7,7 +7,7 @@ use std::process::Command; /// Tries to use system libgit2 and emits necessary build script instructions. fn try_system_libgit2() -> Result { let mut cfg = pkg_config::Config::new(); - match cfg.range_version("1.8.0".."1.9.0").probe("libgit2") { + match cfg.range_version("1.8.1".."1.9.0").probe("libgit2") { Ok(lib) => { for include in &lib.include_paths { println!("cargo:root={}", include.display()); diff --git a/libgit2-sys/libgit2 b/libgit2-sys/libgit2 index d74d491481..36f7e21ad7 160000 --- a/libgit2-sys/libgit2 +++ b/libgit2-sys/libgit2 @@ -1 +1 @@ -Subproject commit d74d491481831ddcd23575d376e56d2197e95910 +Subproject commit 36f7e21ad757a3dacc58cf7944329da6bc1d6e96 From 8640496eab353b173b46a9403209b0ba57a4d258 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Wed, 15 May 2024 17:00:24 +0800 Subject: [PATCH 18/21] libgit2-sys: Switch to new bundled llhttp HTTP parser --- libgit2-sys/build.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libgit2-sys/build.rs b/libgit2-sys/build.rs index 1fd1caea41..1abf628c6e 100644 --- a/libgit2-sys/build.rs +++ b/libgit2-sys/build.rs @@ -89,9 +89,9 @@ The build is now aborting. To disable, unset the variable or use `LIBGIT2_NO_VEN add_c_files(&mut cfg, "libgit2/src/libgit2/transports"); add_c_files(&mut cfg, "libgit2/src/libgit2/streams"); - // Always use bundled http-parser for now - cfg.include("libgit2/deps/http-parser") - .file("libgit2/deps/http-parser/http_parser.c"); + // Always use bundled HTTP parser (llhttp) for now + cfg.include("libgit2/deps/llhttp"); + add_c_files(&mut cfg, "libgit2/deps/llhttp"); // external/system xdiff is not yet supported cfg.include("libgit2/deps/xdiff"); @@ -150,6 +150,7 @@ The build is now aborting. To disable, unset the variable or use `LIBGIT2_NO_VEN features.push_str("#define INCLUDE_features_h\n"); features.push_str("#define GIT_THREADS 1\n"); features.push_str("#define GIT_TRACE 1\n"); + features.push_str("#define GIT_HTTPPARSER_BUILTIN 1\n"); if !target.contains("android") { features.push_str("#define GIT_USE_NSEC 1\n"); From 78872dda70a3962e6269debe569265759518c8c6 Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Wed, 15 May 2024 17:16:26 +0800 Subject: [PATCH 19/21] remote: Update `git_fetch_options` to use bitflags instead of bitfields See: - https://github.com/libgit2/libgit2/issues/6800 - https://github.com/libgit2/libgit2/pull/6806 --- libgit2-sys/lib.rs | 2 +- src/remote.rs | 9 ++++----- systest/build.rs | 4 +--- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 2ea565284f..c94d0d446a 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -402,7 +402,7 @@ pub struct git_fetch_options { pub version: c_int, pub callbacks: git_remote_callbacks, pub prune: git_fetch_prune_t, - pub update_flags: c_uint, + pub update_fetchhead: c_uint, pub download_tags: git_remote_autotag_option_t, pub proxy_opts: git_proxy_options, pub depth: c_int, diff --git a/src/remote.rs b/src/remote.rs index 0211493507..13c275ae2e 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -613,11 +613,10 @@ impl<'cb> Binding for FetchOptions<'cb> { .map(|m| m.raw()) .unwrap_or_else(|| ProxyOptions::new().raw()), prune: crate::call::convert(&self.prune), - // HACK: `libgit2` uses C bitfields, which do not have a guaranteed memory layout. - // Reversing the bits ensures that the bitfields are set whether the bits are laid out - // from left to right or right to left, but will not work on other memory layouts. - update_flags: (self.update_flags.bits() | self.update_flags.bits().reverse_bits()) - as c_uint, + // `update_fetchhead` is an incorrectly named option which contains both + // the `UPDATE_FETCHHEAD` and `REPORT_UNCHANGED` flags. + // See https://github.com/libgit2/libgit2/pull/6806 + update_fetchhead: self.update_flags.bits() as c_uint, download_tags: crate::call::convert(&self.download_tags), depth: self.depth, follow_redirects: self.follow_redirects.raw(), diff --git a/systest/build.rs b/systest/build.rs index 0a22a5b396..85e8b4b437 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -25,9 +25,7 @@ fn main() { // this field is marked as const which ctest complains about (struct_ == "git_rebase_operation" && f == "id") || // the real name of this field is ref but that is a reserved keyword - (struct_ == "git_worktree_add_options" && f == "reference") || - // the `update_flags` field consists of 2 bitfields - (struct_ == "git_fetch_options" && f == "update_flags") + (struct_ == "git_worktree_add_options" && f == "reference") }); cfg.skip_signededness(|s| match s { s if s.ends_with("_cb") => true, From 938df213d29e90b1275b548403517186afdec89b Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Thu, 16 May 2024 19:20:37 +0800 Subject: [PATCH 20/21] libgit2-sys: Add updated enum values for `git_libgit2_opt_t` --- libgit2-sys/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index c94d0d446a..af1dff048b 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -1961,6 +1961,14 @@ git_enum! { GIT_OPT_SET_EXTENSIONS, GIT_OPT_GET_OWNER_VALIDATION, GIT_OPT_SET_OWNER_VALIDATION, + GIT_OPT_GET_HOMEDIR, + GIT_OPT_SET_HOMEDIR, + GIT_OPT_SET_SERVER_CONNECT_TIMEOUT, + GIT_OPT_GET_SERVER_CONNECT_TIMEOUT, + GIT_OPT_SET_SERVER_TIMEOUT, + GIT_OPT_GET_SERVER_TIMEOUT, + GIT_OPT_SET_USER_AGENT_PRODUCT, + GIT_OPT_GET_USER_AGENT_PRODUCT, } } From 76ecfe7d821d8cdb5ba13f1ce6b05736bdc922ee Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Fri, 22 Mar 2024 19:32:02 +0800 Subject: [PATCH 21/21] contributing: Add note about `git diff` --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1ab0961f1f..c842f1eec5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -31,6 +31,7 @@ The following steps can be used to update libgit2: can be helpful for seeing what has changed. The project has recently started labeling API and ABI breaking changes with labels: + Alternatively, running `git diff [PREV_VERSION]..[NEW_VERSION] --ignore-all-space -- include/` can provide an overview of changes made to the API. 4. Once you have everything functional, publish a PR with the updates. ## Release process