diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 98ed1523a4..d9df2f20d5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,6 +36,7 @@ jobs: - run: cargo test --locked - run: cargo test --features https,ssh - run: cargo run -p systest + - run: cargo run -p systest --features unstable-sha256 - run: cargo test -p git2-curl rustfmt: diff --git a/libgit2-sys/Cargo.toml b/libgit2-sys/Cargo.toml index 675c2fa35c..2229760846 100644 --- a/libgit2-sys/Cargo.toml +++ b/libgit2-sys/Cargo.toml @@ -38,3 +38,15 @@ https = ["openssl-sys"] vendored = [] vendored-openssl = ["openssl-sys/vendored"] zlib-ng-compat = ["libz-sys/zlib-ng", "libssh2-sys?/zlib-ng-compat"] +# Experimental SHA256 OID support, +# reflecting upstream libgit2's GIT_EXPERIMENTAL_SHA256. +# +# This is an ABI-breaking change. +# Future releases with this feature may introduce breakages without notice +# Use at your own risk. +# +# Library authors: +# DO NOT enable this feature by default in your dependencies. +# Due to Cargo's additive features, +# downstream users cannot deactivate it once enabled. +unstable-sha256 = [] diff --git a/libgit2-sys/build.rs b/libgit2-sys/build.rs index 356ad53ea5..6365bf7851 100644 --- a/libgit2-sys/build.rs +++ b/libgit2-sys/build.rs @@ -5,20 +5,73 @@ use std::path::{Path, PathBuf}; use std::process::Command; /// Tries to use system libgit2 and emits necessary build script instructions. -fn try_system_libgit2() -> Result { +fn try_system_libgit2( + experimental_sha256: bool, +) -> Result> { let mut cfg = pkg_config::Config::new(); - match cfg.range_version("1.9.2".."1.10.0").probe("libgit2") { - Ok(lib) => { - for include in &lib.include_paths { - println!("cargo:root={}", include.display()); + let range_version = "1.9.2".."1.10.0"; + + let lib = if experimental_sha256 { + // Determine whether experimental SHA256 object support is enabled. + // + // Given the SHA256 support is ABI-incompatible, + // we take a conservative approach here: + // + // 1. Only accept if the library name has the `-experimental` suffix + // 2. The experimental library must have an `experimental.h` header file + // containing an enabled `GIT_EXPERIMENTAL_SHA256` constant. + // + // See how libgit2 handles experimental features: + // https://github.com/libgit2/libgit2/blob/3ac4c0adb1064bad16a7f980d87e7261753fd07e/cmake/ExperimentalFeatures.cmake + match cfg + .range_version(range_version.clone()) + .probe("libgit2-experimental") + { + Ok(lib) => { + let sha256_constant_in_header = lib.include_paths.iter().any(|path| { + let header = path.join("git2/experimental.h"); + let contents = match std::fs::read_to_string(header) { + Ok(s) => s, + Err(_) => return false, + }; + if contents.contains("#cmakedefine") { + // still template + return false; + } + contents + .lines() + .any(|l| l.starts_with("#define GIT_EXPERIMENTAL_SHA256 1")) + }); + if sha256_constant_in_header { + println!("cargo:rustc-cfg=libgit2_experimental_sha256"); + lib + } else { + println!("cargo:warning=no GIT_EXPERIMENTAL_SHA256 constant in headers"); + return Err( + "GIT_EXPERIMENTAL_SHA256 wasn't enabled for libgit2-experimental library" + .into(), + ); + } + } + Err(e) => { + println!("cargo:warning=failed to probe system libgit2-experimental: {e}"); + return Err(e.into()); } - Ok(lib) } - Err(e) => { - println!("cargo:warning=failed to probe system libgit2: {e}"); - Err(e) + } else { + match cfg.range_version(range_version).probe("libgit2") { + Ok(lib) => lib, + Err(e) => { + println!("cargo:warning=failed to probe system libgit2: {e}"); + return Err(e.into()); + } } + }; + + for include in &lib.include_paths { + println!("cargo:root={}", include.display()); } + Ok(lib) } fn main() { @@ -27,11 +80,13 @@ fn main() { libgit2_vendored,\ )" ); + println!("cargo:rustc-check-cfg=cfg(libgit2_experimental_sha256)"); let https = env::var("CARGO_FEATURE_HTTPS").is_ok(); let ssh = env::var("CARGO_FEATURE_SSH").is_ok(); let vendored = env::var("CARGO_FEATURE_VENDORED").is_ok(); let zlib_ng_compat = env::var("CARGO_FEATURE_ZLIB_NG_COMPAT").is_ok(); + let unstable_sha256 = env::var("CARGO_FEATURE_UNSTABLE_SHA256").is_ok(); // Specify `LIBGIT2_NO_VENDOR` to force to use system libgit2. // Due to the additive nature of Cargo features, if some crate in the @@ -41,7 +96,7 @@ fn main() { let forced_no_vendor = env::var_os("LIBGIT2_NO_VENDOR").map_or(false, |s| s != "0"); if forced_no_vendor { - if try_system_libgit2().is_err() { + if try_system_libgit2(unstable_sha256).is_err() { panic!( "\ The environment variable `LIBGIT2_NO_VENDOR` has been set but no compatible system libgit2 could be found. @@ -56,7 +111,7 @@ The build is now aborting. To disable, unset the variable or use `LIBGIT2_NO_VEN // To use zlib-ng in zlib-compat mode, we have to build libgit2 ourselves. let try_to_use_system_libgit2 = !vendored && !zlib_ng_compat; - if try_to_use_system_libgit2 && try_system_libgit2().is_ok() { + if try_to_use_system_libgit2 && try_system_libgit2(unstable_sha256).is_ok() { // using system libgit2 has worked return; } @@ -85,6 +140,11 @@ The build is now aborting. To disable, unset the variable or use `LIBGIT2_NO_VEN .out_dir(dst.join("build")) .warnings(false); + if unstable_sha256 { + println!("cargo:rustc-cfg=libgit2_experimental_sha256"); + cfg.define("GIT_EXPERIMENTAL_SHA256", "1"); + } + // Include all cross-platform C files add_c_files(&mut cfg, "libgit2/src/libgit2"); add_c_files(&mut cfg, "libgit2/src/util"); diff --git a/libgit2-sys/lib.rs b/libgit2-sys/lib.rs index 7e1ac1e998..a8e991a589 100644 --- a/libgit2-sys/lib.rs +++ b/libgit2-sys/lib.rs @@ -9,8 +9,27 @@ use libc::{c_char, c_int, c_uchar, c_uint, c_ushort, c_void, size_t}; use libssh2_sys as libssh2; use std::ffi::CStr; -pub const GIT_OID_RAWSZ: usize = 20; -pub const GIT_OID_HEXSZ: usize = GIT_OID_RAWSZ * 2; +#[cfg(not(feature = "unstable-sha256"))] +#[deprecated(note = "use `GIT_OID_SHA1_SIZE` instead")] +pub const GIT_OID_RAWSZ: usize = GIT_OID_SHA1_SIZE; +#[cfg(not(feature = "unstable-sha256"))] +#[deprecated(note = "use `GIT_OID_SHA1_HEXSIZE` instead")] +pub const GIT_OID_HEXSZ: usize = GIT_OID_SHA1_HEXSIZE; +pub const GIT_OID_SHA1_SIZE: usize = 20; +pub const GIT_OID_SHA1_HEXSIZE: usize = GIT_OID_SHA1_SIZE * 2; +#[cfg(feature = "unstable-sha256")] +pub const GIT_OID_SHA256_SIZE: usize = 32; +#[cfg(feature = "unstable-sha256")] +pub const GIT_OID_SHA256_HEXSIZE: usize = GIT_OID_SHA256_SIZE * 2; +#[cfg(not(feature = "unstable-sha256"))] +pub const GIT_OID_MAX_SIZE: usize = GIT_OID_SHA1_SIZE; +#[cfg(feature = "unstable-sha256")] +pub const GIT_OID_MAX_SIZE: usize = GIT_OID_SHA256_SIZE; +#[cfg(not(feature = "unstable-sha256"))] +pub const GIT_OID_MAX_HEXSIZE: usize = GIT_OID_SHA1_HEXSIZE; +#[cfg(feature = "unstable-sha256")] +pub const GIT_OID_MAX_HEXSIZE: usize = GIT_OID_SHA256_HEXSIZE; + pub const GIT_CLONE_OPTIONS_VERSION: c_uint = 1; pub const GIT_STASH_APPLY_OPTIONS_VERSION: c_uint = 1; pub const GIT_CHECKOUT_OPTIONS_VERSION: c_uint = 1; @@ -39,6 +58,16 @@ macro_rules! git_enum { pub type $name = $t; git_enum!(gen, $name, 0, $($variants)*); }; + (gen, $name:ident, $val:expr, #[$attr:meta] $variant:ident, $($rest:tt)*) => { + #[$attr] + pub const $variant: $name = $val; + git_enum!(gen, $name, $val+1, $($rest)*); + }; + (gen, $name:ident, $val:expr, #[$attr:meta] $variant:ident = $e:expr, $($rest:tt)*) => { + #[$attr] + pub const $variant: $name = $e; + git_enum!(gen, $name, $e+1, $($rest)*); + }; (gen, $name:ident, $val:expr, $variant:ident, $($rest:tt)*) => { pub const $variant: $name = $val; git_enum!(gen, $name, $val+1, $($rest)*); @@ -110,7 +139,9 @@ pub struct git_error { #[repr(C)] #[derive(Copy, Clone)] pub struct git_oid { - pub id: [u8; GIT_OID_RAWSZ], + #[cfg(feature = "unstable-sha256")] + pub kind: c_uchar, + pub id: [u8; GIT_OID_MAX_SIZE], } #[repr(C)] @@ -363,6 +394,12 @@ pub type git_transfer_progress = git_indexer_progress; #[repr(C)] pub struct git_indexer_options { pub version: c_uint, + #[cfg(feature = "unstable-sha256")] + pub mode: c_uint, + #[cfg(feature = "unstable-sha256")] + pub oid_type: git_oid_t, + #[cfg(feature = "unstable-sha256")] + pub odb: *mut git_odb, pub progress_cb: git_indexer_progress_cb, pub progress_cb_payload: *mut c_void, pub verify: c_uchar, @@ -1040,10 +1077,76 @@ pub struct git_repository_init_options { pub template_path: *const c_char, pub initial_head: *const c_char, pub origin_url: *const c_char, + #[cfg(feature = "unstable-sha256")] + pub oid_type: git_oid_t, } pub const GIT_REPOSITORY_INIT_OPTIONS_VERSION: c_uint = 1; +#[cfg(feature = "unstable-sha256")] +#[repr(C)] +pub struct git_repository_new_options { + pub version: c_uint, + pub oid_type: git_oid_t, +} + +#[cfg(feature = "unstable-sha256")] +pub const GIT_REPOSITORY_NEW_OPTIONS_VERSION: c_uint = 1; + +#[cfg(feature = "unstable-sha256")] +#[repr(C)] +pub struct git_index_options { + pub version: c_uint, + pub oid_type: git_oid_t, +} + +#[cfg(feature = "unstable-sha256")] +pub const GIT_INDEX_OPTIONS_VERSION: c_uint = 1; + +#[cfg(feature = "unstable-sha256")] +#[repr(C)] +pub struct git_odb_options { + pub version: c_uint, + pub oid_type: git_oid_t, +} + +#[cfg(feature = "unstable-sha256")] +pub const GIT_ODB_OPTIONS_VERSION: c_uint = 1; + +#[cfg(feature = "unstable-sha256")] +#[repr(C)] +pub struct git_odb_backend_pack_options { + pub version: c_uint, + pub oid_type: git_oid_t, +} + +#[cfg(feature = "unstable-sha256")] +pub const GIT_ODB_BACKEND_PACK_OPTIONS_VERSION: c_uint = 1; + +#[cfg(feature = "unstable-sha256")] +#[repr(C)] +pub struct git_odb_backend_loose_options { + pub version: c_uint, + pub flags: u32, + pub compression_level: c_int, + pub dir_mode: c_uint, + pub file_mode: c_uint, + pub oid_type: git_oid_t, +} + +#[cfg(feature = "unstable-sha256")] +pub const GIT_ODB_BACKEND_LOOSE_OPTIONS_VERSION: c_uint = 1; + +#[cfg(feature = "unstable-sha256")] +#[repr(C)] +pub struct git_diff_parse_options { + pub version: c_uint, + pub oid_type: git_oid_t, +} + +#[cfg(feature = "unstable-sha256")] +pub const GIT_DIFF_PARSE_OPTIONS_VERSION: c_uint = 1; + git_enum! { pub enum git_repository_init_flag_t { GIT_REPOSITORY_INIT_BARE = 1 << 0, @@ -1182,8 +1285,8 @@ pub struct git_diff_options { git_enum! { pub enum git_oid_t { GIT_OID_SHA1 = 1, - // SHA256 is still experimental so we are not going to enable it. - /* GIT_OID_SHA256 = 2, */ + #[cfg(feature = "unstable-sha256")] + GIT_OID_SHA256 = 2, } } @@ -1460,6 +1563,9 @@ pub struct git_transport { >, pub capabilities: Option c_int>, + #[cfg(feature = "unstable-sha256")] + pub oid_type: + Option c_int>, pub ls: Option< extern "C" fn( out: *mut *mut *const git_remote_head, @@ -2129,7 +2235,13 @@ extern "C" { pub fn git_libgit2_shutdown() -> c_int; // repository + #[cfg(not(feature = "unstable-sha256"))] pub fn git_repository_new(out: *mut *mut git_repository) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_repository_new( + out: *mut *mut git_repository, + opts: *mut git_repository_new_options, + ) -> c_int; pub fn git_repository_free(repo: *mut git_repository); pub fn git_repository_open(repo: *mut *mut git_repository, path: *const c_char) -> c_int; pub fn git_repository_open_bare(repo: *mut *mut git_repository, path: *const c_char) -> c_int; @@ -2254,6 +2366,21 @@ extern "C" { // object pub fn git_object_dup(dest: *mut *mut git_object, source: *mut git_object) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] + pub fn git_object_rawcontent_is_valid( + valid: *mut c_int, + buf: *const c_char, + len: size_t, + object_type: git_object_t, + ) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_object_rawcontent_is_valid( + valid: *mut c_int, + buf: *const c_char, + len: size_t, + object_type: git_object_t, + oid_type: git_oid_t, + ) -> c_int; pub fn git_object_id(obj: *const git_object) -> *const git_oid; pub fn git_object_free(object: *mut git_object); pub fn git_object_lookup( @@ -2281,8 +2408,29 @@ extern "C" { pub fn git_object_typeisloose(kind: git_object_t) -> c_int; // oid + #[cfg(not(feature = "unstable-sha256"))] pub fn git_oid_fromraw(out: *mut git_oid, raw: *const c_uchar) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_oid_fromstrn(out: *mut git_oid, str: *const c_char, len: size_t) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] + pub fn git_oid_fromstr(out: *mut git_oid, str: *const c_char) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] + pub fn git_oid_fromstrp(out: *mut git_oid, str: *const c_char) -> c_int; + + #[cfg(feature = "unstable-sha256")] + pub fn git_oid_fromraw(out: *mut git_oid, raw: *const c_uchar, oid_type: git_oid_t) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_oid_fromstrn( + out: *mut git_oid, + str: *const c_char, + len: size_t, + oid_type: git_oid_t, + ) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_oid_fromstr(out: *mut git_oid, str: *const c_char, oid_type: git_oid_t) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_oid_fromstrp(out: *mut git_oid, str: *const c_char, oid_type: git_oid_t) -> c_int; + pub fn git_oid_tostr(out: *mut c_char, n: size_t, id: *const git_oid) -> *mut c_char; pub fn git_oid_cmp(a: *const git_oid, b: *const git_oid) -> c_int; pub fn git_oid_equal(a: *const git_oid, b: *const git_oid) -> c_int; @@ -3107,8 +3255,20 @@ extern "C" { stage: c_int, ) -> *const git_index_entry; pub fn git_index_has_conflicts(index: *const git_index) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_index_new(index: *mut *mut git_index) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_index_new(index: *mut *mut git_index, opts: *const git_index_options) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_index_open(index: *mut *mut git_index, index_path: *const c_char) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_index_open( + index: *mut *mut git_index, + index_path: *const c_char, + opts: *const git_index_options, + ) -> c_int; + // #[cfg(feature = "unstable-sha256")] + // pub fn git_index_options_init(opts: *mut git_index_options, version: c_uint) -> c_int; pub fn git_index_path(index: *const git_index) -> *const c_char; pub fn git_index_read(index: *mut git_index, force: c_int) -> c_int; pub fn git_index_read_tree(index: *mut git_index, tree: *const git_tree) -> c_int; @@ -3666,10 +3826,18 @@ extern "C" { line_cb: git_diff_line_cb, payload: *mut c_void, ) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] + pub fn git_diff_from_buffer( + diff: *mut *mut git_diff, + content: *const c_char, + content_len: size_t, + ) -> c_int; + #[cfg(feature = "unstable-sha256")] pub fn git_diff_from_buffer( diff: *mut *mut git_diff, content: *const c_char, content_len: size_t, + opts: *mut git_diff_parse_options, ) -> c_int; pub fn git_diff_find_similar( diff: *mut git_diff, @@ -3971,6 +4139,7 @@ extern "C" { pub fn git_packbuilder_free(pb: *mut git_packbuilder); // indexer + #[cfg(not(feature = "unstable-sha256"))] pub fn git_indexer_new( out: *mut *mut git_indexer, path: *const c_char, @@ -3978,6 +4147,12 @@ extern "C" { odb: *mut git_odb, opts: *mut git_indexer_options, ) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_indexer_new( + out: *mut *mut git_indexer, + path: *const c_char, + opts: *mut git_indexer_options, + ) -> c_int; pub fn git_indexer_append( idx: *mut git_indexer, data: *const c_void, @@ -3994,7 +4169,18 @@ extern "C" { // odb pub fn git_repository_odb(out: *mut *mut git_odb, repo: *mut git_repository) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_odb_new(db: *mut *mut git_odb) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_odb_new(db: *mut *mut git_odb, opts: *const git_odb_options) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] + pub fn git_odb_open(out: *mut *mut git_odb, objects_dir: *const c_char) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_odb_open( + out: *mut *mut git_odb, + objects_dir: *const c_char, + opts: *const git_odb_options, + ) -> c_int; pub fn git_odb_free(db: *mut git_odb); pub fn git_odb_open_rstream( out: *mut *mut git_odb_stream, @@ -4052,14 +4238,31 @@ extern "C" { progress_payload: *mut c_void, ) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_odb_hash( out: *mut git_oid, data: *const c_void, len: size_t, otype: git_object_t, ) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_odb_hash( + out: *mut git_oid, + data: *const c_void, + len: size_t, + otype: git_object_t, + oid_type: git_oid_t, + ) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_odb_hashfile(out: *mut git_oid, path: *const c_char, otype: git_object_t) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_odb_hashfile( + out: *mut git_oid, + path: *const c_char, + otype: git_object_t, + oid_type: git_oid_t, + ) -> c_int; pub fn git_odb_exists_prefix( out: *mut git_oid, @@ -4088,18 +4291,33 @@ extern "C" { priority: c_int, ) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_odb_backend_pack( out: *mut *mut git_odb_backend, objects_dir: *const c_char, ) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_odb_backend_pack( + out: *mut *mut git_odb_backend, + objects_dir: *const c_char, + opts: *const git_odb_backend_pack_options, + ) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_odb_backend_one_pack( out: *mut *mut git_odb_backend, - objects_dir: *const c_char, + index_file: *const c_char, + ) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_odb_backend_one_pack( + out: *mut *mut git_odb_backend, + index_file: *const c_char, + opts: *const git_odb_backend_pack_options, ) -> c_int; pub fn git_odb_add_disk_alternate(odb: *mut git_odb, path: *const c_char) -> c_int; + #[cfg(not(feature = "unstable-sha256"))] pub fn git_odb_backend_loose( out: *mut *mut git_odb_backend, objects_dir: *const c_char, @@ -4108,6 +4326,12 @@ extern "C" { dir_mode: c_uint, file_mode: c_uint, ) -> c_int; + #[cfg(feature = "unstable-sha256")] + pub fn git_odb_backend_loose( + out: *mut *mut git_odb_backend, + objects_dir: *const c_char, + opts: *mut git_odb_backend_loose_options, + ) -> c_int; pub fn git_odb_add_alternate( odb: *mut git_odb, @@ -4409,3 +4633,14 @@ fn ssh_init() {} pub fn vendored() -> bool { cfg!(libgit2_vendored) } + +#[doc(hidden)] +pub fn experimental_features() -> Vec<&'static str> { + let mut features = vec![]; + + if cfg!(libgit2_experimental_sha256) { + features.push("sha256"); + } + + features +} diff --git a/src/blob.rs b/src/blob.rs index 5c4a6ce6b8..e72abbe262 100644 --- a/src/blob.rs +++ b/src/blob.rs @@ -96,7 +96,7 @@ impl<'repo> BlobWriter<'repo> { // After commit we already doesn't need cleanup on drop self.need_cleanup = false; let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_blob_create_fromstream_commit(&mut raw, self.raw)); diff --git a/src/build.rs b/src/build.rs index 4ac62439b7..eebbdd5ebe 100644 --- a/src/build.rs +++ b/src/build.rs @@ -724,7 +724,7 @@ impl TreeUpdateBuilder { self.updates.push(raw::git_tree_update { action: raw::GIT_TREE_UPDATE_REMOVE, id: raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }, filemode: raw::GIT_FILEMODE_UNREADABLE, path: path_ptr, @@ -755,7 +755,7 @@ impl TreeUpdateBuilder { /// The baseline tree must exist in the specified repository. pub fn create_updated(&mut self, repo: &Repository, baseline: &Tree<'_>) -> Result { let mut ret = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_tree_create_updated( diff --git a/src/commit.rs b/src/commit.rs index 7fef508096..7095bccf94 100644 --- a/src/commit.rs +++ b/src/commit.rs @@ -261,7 +261,7 @@ impl<'repo> Commit<'repo> { tree: Option<&Tree<'repo>>, ) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; let update_ref = crate::opt_cstr(update_ref)?; let encoding = crate::opt_cstr(message_encoding)?; diff --git a/src/diff.rs b/src/diff.rs index 3070550390..5ba3535a9b 100644 --- a/src/diff.rs +++ b/src/diff.rs @@ -290,7 +290,7 @@ impl<'repo> Diff<'repo> { /// Create a patch ID from a diff. pub fn patchid(&self, opts: Option<&mut DiffPatchidOptions>) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_diff_patchid( diff --git a/src/index.rs b/src/index.rs index c0d9294520..d02b45e169 100644 --- a/src/index.rs +++ b/src/index.rs @@ -617,7 +617,7 @@ impl Index { /// The index must not contain any file in conflict. pub fn write_tree(&mut self) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_index_write_tree(&mut raw, self.raw)); @@ -631,7 +631,7 @@ impl Index { /// can be chosen. pub fn write_tree_to(&mut self, repo: &Repository) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_index_write_tree_to(&mut raw, self.raw, repo.raw())); diff --git a/src/note.rs b/src/note.rs index 50e5800fe7..b0049226a9 100644 --- a/src/note.rs +++ b/src/note.rs @@ -93,7 +93,7 @@ impl<'repo> Iterator for Notes<'repo> { type Item = Result<(Oid, Oid), Error>; fn next(&mut self) -> Option> { let mut note_id = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; let mut annotated_id = note_id; unsafe { diff --git a/src/odb.rs b/src/odb.rs index 2019908c48..2e531dc58c 100644 --- a/src/odb.rs +++ b/src/odb.rs @@ -145,7 +145,7 @@ impl<'repo> Odb<'repo> { pub fn write(&self, kind: ObjectType, data: &[u8]) -> Result { unsafe { let mut out = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; try_call!(raw::git_odb_write( &mut out, @@ -195,7 +195,7 @@ impl<'repo> Odb<'repo> { pub fn exists_prefix(&self, short_oid: Oid, len: usize) -> Result { unsafe { let mut out = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; try_call!(raw::git_odb_exists_prefix( &mut out, @@ -389,7 +389,7 @@ impl<'repo> OdbWriter<'repo> { /// Attempting write after finishing will be ignored. pub fn finalize(&mut self) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_odb_stream_finalize_write(&mut raw, self.raw)); diff --git a/src/oid.rs b/src/oid.rs index 35516cb181..67798baa41 100644 --- a/src/oid.rs +++ b/src/oid.rs @@ -25,7 +25,7 @@ impl Oid { pub fn from_str(s: &str) -> Result { crate::init(); let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_oid_fromstrn( @@ -43,9 +43,9 @@ impl Oid { pub fn from_bytes(bytes: &[u8]) -> Result { crate::init(); let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; - if bytes.len() != raw::GIT_OID_RAWSZ { + if bytes.len() != raw::GIT_OID_MAX_SIZE { Err(Error::from_str("raw byte array must be 20 bytes")) } else { unsafe { @@ -58,7 +58,7 @@ impl Oid { /// Creates an all zero Oid structure. pub fn zero() -> Oid { let out = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; Oid { raw: out } } @@ -70,7 +70,7 @@ impl Oid { crate::init(); let mut out = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_odb_hash( @@ -94,7 +94,7 @@ impl Oid { let rpath = path.as_ref().into_c_string()?; let mut out = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_odb_hashfile(&mut out, rpath, kind.raw())); @@ -134,7 +134,7 @@ impl fmt::Debug for Oid { impl fmt::Display for Oid { /// Hex-encode this Oid into a formatter. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut dst = [0u8; raw::GIT_OID_HEXSZ + 1]; + let mut dst = [0u8; raw::GIT_OID_MAX_HEXSIZE + 1]; unsafe { raw::git_oid_tostr( dst.as_mut_ptr() as *mut libc::c_char, diff --git a/src/repo.rs b/src/repo.rs index 07d3a7c55f..5b7594227e 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -1133,7 +1133,7 @@ impl Repository { /// the blob. pub fn blob(&self, data: &[u8]) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { let ptr = data.as_ptr() as *const c_void; @@ -1157,7 +1157,7 @@ impl Repository { // Normal file path OK (does not need Windows conversion). let path = path.into_c_string()?; let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_blob_create_fromdisk(&mut raw, self.raw(), path)); @@ -1310,7 +1310,7 @@ impl Repository { .collect::>(); let message = CString::new(message)?; let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_commit_create( @@ -1384,7 +1384,7 @@ impl Repository { let signature = CString::new(signature)?; let signature_field = crate::opt_cstr(signature_field)?; let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_commit_create_with_signature( @@ -1683,7 +1683,7 @@ impl Repository { pub fn refname_to_id(&self, name: &str) -> Result { let name = CString::new(name)?; let mut ret = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_reference_name_to_id(&mut ret, self.raw(), name)); @@ -1911,7 +1911,7 @@ impl Repository { let name = CString::new(name)?; let message = CString::new(message)?; let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_tag_create( @@ -1944,7 +1944,7 @@ impl Repository { let name = CString::new(name)?; let message = CString::new(message)?; let mut raw_oid = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_tag_annotation_create( @@ -1972,7 +1972,7 @@ impl Repository { ) -> Result { let name = CString::new(name)?; let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_tag_create_lightweight( @@ -2348,7 +2348,7 @@ impl Repository { let notes_ref = crate::opt_cstr(notes_ref)?; let note = CString::new(note)?; let mut ret = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_note_create( @@ -2464,7 +2464,7 @@ impl Repository { /// Find a merge base between two commits pub fn merge_base(&self, one: Oid, two: Oid) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_merge_base( @@ -2512,7 +2512,7 @@ impl Repository { /// given commits, use [`Self::merge_base_octopus`]. pub fn merge_base_many(&self, oids: &[Oid]) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { @@ -2529,7 +2529,7 @@ impl Repository { /// Find a common merge base between all given a list of commits pub fn merge_base_octopus(&self, oids: &[Oid]) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { @@ -2974,7 +2974,7 @@ impl Repository { ) -> Result { unsafe { let mut raw_oid = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; let message = crate::opt_cstr(message)?; let flags = flags.unwrap_or_else(StashFlags::empty); @@ -2996,7 +2996,7 @@ impl Repository { ) -> Result { unsafe { let mut raw_oid = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; let opts = opts.map(|opts| opts.raw()); try_call!(raw::git_stash_save_with_opts( diff --git a/src/revwalk.rs b/src/revwalk.rs index 7837f00d63..3bb1e82b33 100644 --- a/src/revwalk.rs +++ b/src/revwalk.rs @@ -239,7 +239,7 @@ impl<'repo> Iterator for Revwalk<'repo> { type Item = Result; fn next(&mut self) -> Option> { let mut out: raw::git_oid = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call_iter!(raw::git_revwalk_next(&mut out, self.raw())); diff --git a/src/treebuilder.rs b/src/treebuilder.rs index 1548a048cf..29ad54bb3b 100644 --- a/src/treebuilder.rs +++ b/src/treebuilder.rs @@ -115,7 +115,7 @@ impl<'repo> TreeBuilder<'repo> { /// return its Oid pub fn write(&self) -> Result { let mut raw = raw::git_oid { - id: [0; raw::GIT_OID_RAWSZ], + id: [0; raw::GIT_OID_MAX_SIZE], }; unsafe { try_call!(raw::git_treebuilder_write(&mut raw, self.raw())); diff --git a/systest/Cargo.toml b/systest/Cargo.toml index 708cda4303..bdb41de2ae 100644 --- a/systest/Cargo.toml +++ b/systest/Cargo.toml @@ -11,3 +11,6 @@ libc = "0.2" [build-dependencies] ctest2 = "0.4" + +[features] +unstable-sha256 = ["libgit2-sys/unstable-sha256"] diff --git a/systest/build.rs b/systest/build.rs index 9503af7e10..3983c964b5 100644 --- a/systest/build.rs +++ b/systest/build.rs @@ -6,6 +6,14 @@ fn main() { if let Some(root) = env::var_os("DEP_GIT2_ROOT") { cfg.include(PathBuf::from(root).join("include")); } + + // Enable the unstable-sha256 rust cfg + // so ctest2 sees the correct function signatures + if env::var("CARGO_FEATURE_UNSTABLE_SHA256").is_ok() { + cfg.cfg("feature", Some("unstable-sha256")); + cfg.define("GIT_EXPERIMENTAL_SHA256", Some("1")); + } + cfg.header("git2.h") .header("git2/sys/errors.h") .header("git2/sys/transport.h")