[packages/rust] - update git2 and libgit2 crates to latest versions, rel 3

baggins baggins at pld-linux.org
Sat Oct 23 21:47:56 CEST 2021


commit dfa5a2fd1435b64589b9fde46ab8f840982b71be
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Sat Oct 23 21:43:26 2021 +0200

    - update git2 and libgit2 crates to latest versions, rel 3
    
    The bundled crates expect libgit2 1.1.0 and break with anything newer:
    
      invalid version 0 on git_proxy_options; class=Invalid (3)

 libgit2.patch | 4018 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 rust.spec     |    4 +-
 2 files changed, 4021 insertions(+), 1 deletion(-)
---
diff --git a/rust.spec b/rust.spec
index d9b270d..afada11 100644
--- a/rust.spec
+++ b/rust.spec
@@ -38,7 +38,7 @@ Summary:	The Rust Programming Language
 Summary(pl.UTF-8):	Język programowania Rust
 Name:		rust
 Version:	1.56.0
-Release:	2
+Release:	3
 # Licenses: (rust itself) and (bundled libraries)
 License:	(Apache v2.0 or MIT) and (BSD and ISC and MIT)
 Group:		Development/Languages
@@ -54,6 +54,7 @@ Source4:	https://static.rust-lang.org/dist/%{bootstrap_date}/rust-%{bootstrap_ru
 # Source4-md5:	56a568e97e7a5c3cb80569ab84f4657b
 Source5:	https://static.rust-lang.org/dist/%{bootstrap_date}/rust-%{bootstrap_rust}-armv7-unknown-linux-gnueabihf.tar.xz
 # Source5-md5:	991a439bcdcbcf1b2bbe55ce9e90404f
+Patch0:		libgit2.patch
 URL:		https://www.rust-lang.org/
 # for src/compiler-rt
 BuildRequires:	cmake >= 3.4.3
@@ -329,6 +330,7 @@ Dopełnianie parametrów polecenia cargo w powłoce Zsh.
 
 %prep
 %setup -q -n %{rustc_package}
+%patch0 -p1
 
 %if %{with bootstrap}
 %ifarch %{x8664} x32
diff --git a/libgit2.patch b/libgit2.patch
new file mode 100644
index 0000000..397b5be
--- /dev/null
+++ b/libgit2.patch
@@ -0,0 +1,4018 @@
+diff -urN rustc-1.56.0-src/Cargo.lock rustc-1.56.0-src-git2/Cargo.lock
+--- rustc-1.56.0-src/Cargo.lock	2021-10-18 11:52:36.000000000 +0200
++++ rustc-1.56.0-src-git2/Cargo.lock	2021-10-23 20:59:08.434911180 +0200
+@@ -1429,7 +1429,7 @@
+ 
+ [[package]]
+ name = "git2"
+-version = "0.13.17"
++version = "0.13.23"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "1d250f5f82326884bd39c2853577e70a121775db76818ffa452ed1e80de12986"
+ dependencies = [
+@@ -1889,7 +1889,7 @@
+ 
+ [[package]]
+ name = "libgit2-sys"
+-version = "0.12.18+1.1.0"
++version = "0.12.24+1.3.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "3da6a42da88fc37ee1ecda212ffa254c25713532980005d5f7c0b0fbe7e6e885"
+ dependencies = [
+diff -urN rustc-1.56.0-src/src/tools/cargo/Cargo.toml rustc-1.56.0-src-git2/src/tools/cargo/Cargo.toml
+--- rustc-1.56.0-src/src/tools/cargo/Cargo.toml	2021-10-18 11:52:56.000000000 +0200
++++ rustc-1.56.0-src-git2/src/tools/cargo/Cargo.toml	2021-10-23 21:00:31.124770799 +0200
+@@ -44,7 +44,7 @@
+ lazycell = "1.2.0"
+ libc = "0.2"
+ log = "0.4.6"
+-libgit2-sys = "0.12.18"
++libgit2-sys = "0.12.24"
+ memchr = "2.1.3"
+ num_cpus = "1.0"
+ opener = "0.5"
+diff -urN rustc-1.56.0-src/src/tools/miri/cargo-miri/Cargo.lock rustc-1.56.0-src-git2/src/tools/miri/cargo-miri/Cargo.lock
+--- rustc-1.56.0-src/src/tools/miri/cargo-miri/Cargo.lock	2021-10-18 11:52:56.000000000 +0200
++++ rustc-1.56.0-src-git2/src/tools/miri/cargo-miri/Cargo.lock	2021-10-23 21:01:01.564718045 +0200
+@@ -181,7 +181,7 @@
+ 
+ [[package]]
+ name = "git2"
+-version = "0.13.17"
++version = "0.13.23"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "1d250f5f82326884bd39c2853577e70a121775db76818ffa452ed1e80de12986"
+ dependencies = [
+@@ -232,7 +232,7 @@
+ 
+ [[package]]
+ name = "libgit2-sys"
+-version = "0.12.18+1.1.0"
++version = "0.12.24+1.3.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "3da6a42da88fc37ee1ecda212ffa254c25713532980005d5f7c0b0fbe7e6e885"
+ dependencies = [
+diff -urN rustc-1.56.0-src/src/tools/rls/Cargo.lock rustc-1.56.0-src-git2/src/tools/rls/Cargo.lock
+--- rustc-1.56.0-src/src/tools/rls/Cargo.lock	2021-10-18 11:52:56.000000000 +0200
++++ rustc-1.56.0-src-git2/src/tools/rls/Cargo.lock	2021-10-23 20:55:59.835212449 +0200
+@@ -854,7 +854,7 @@
+ 
+ [[package]]
+ name = "git2"
+-version = "0.13.17"
++version = "0.13.23"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "1d250f5f82326884bd39c2853577e70a121775db76818ffa452ed1e80de12986"
+ dependencies = [
+@@ -1216,7 +1216,7 @@
+ 
+ [[package]]
+ name = "libgit2-sys"
+-version = "0.12.18+1.1.0"
++version = "0.12.24+1.3.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "3da6a42da88fc37ee1ecda212ffa254c25713532980005d5f7c0b0fbe7e6e885"
+ dependencies = [
+diff -urN rustc-1.56.0-src/vendor/git2/Cargo.lock rustc-1.56.0-src-git2/vendor/git2/Cargo.lock
+--- rustc-1.56.0-src/vendor/git2/Cargo.lock	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/Cargo.lock	2021-10-23 20:59:46.411513930 +0200
+@@ -94,7 +94,7 @@
+ 
+ [[package]]
+ name = "git2"
+-version = "0.13.17"
++version = "0.13.23"
+ dependencies = [
+  "bitflags",
+  "libc",
+@@ -162,7 +162,7 @@
+ 
+ [[package]]
+ name = "libgit2-sys"
+-version = "0.12.18+1.1.0"
++version = "0.12.24+1.3.0"
+ source = "registry+https://github.com/rust-lang/crates.io-index"
+ checksum = "3da6a42da88fc37ee1ecda212ffa254c25713532980005d5f7c0b0fbe7e6e885"
+ dependencies = [
+diff -urN rustc-1.56.0-src/vendor/git2/Cargo.toml rustc-1.56.0-src-git2/vendor/git2/Cargo.toml
+--- rustc-1.56.0-src/vendor/git2/Cargo.toml	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/Cargo.toml	2021-10-23 20:47:39.252455615 +0200
+@@ -13,7 +13,7 @@
+ [package]
+ edition = "2018"
+ name = "git2"
+-version = "0.13.17"
++version = "0.13.23"
+ authors = ["Josh Triplett <josh at joshtriplett.org>", "Alex Crichton <alex at alexcrichton.com>"]
+ description = "Bindings to libgit2 for interoperating with git repositories. This library is\nboth threadsafe and memory safe and allows both reading and writing git\nrepositories.\n"
+ documentation = "https://docs.rs/git2"
+@@ -29,7 +29,7 @@
+ version = "0.2"
+ 
+ [dependencies.libgit2-sys]
+-version = "0.12.18"
++version = "0.12.24"
+ 
+ [dependencies.log]
+ version = "0.4.8"
+diff -urN rustc-1.56.0-src/vendor/git2/README.md rustc-1.56.0-src-git2/vendor/git2/README.md
+--- rustc-1.56.0-src/vendor/git2/README.md	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/README.md	2021-10-23 20:47:39.252455615 +0200
+@@ -12,8 +12,7 @@
+ ## Rust version requirements
+ 
+ git2-rs works with stable Rust, and typically works with the most recent prior
+-stable release as well. Check the MSRV job of [the CI script](.github/workflows/main.yml) to see the oldest
+-version of Rust known to pass tests.
++stable release as well.
+ 
+ ## Version of libgit2
+ 
+diff -urN rustc-1.56.0-src/vendor/git2/src/attr.rs rustc-1.56.0-src-git2/vendor/git2/src/attr.rs
+--- rustc-1.56.0-src/vendor/git2/src/attr.rs	1970-01-01 01:00:00.000000000 +0100
++++ rustc-1.56.0-src-git2/vendor/git2/src/attr.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -0,0 +1,175 @@
++use crate::raw;
++use std::ptr;
++use std::str;
++
++/// All possible states of an attribute.
++///
++/// This enum is used to interpret the value returned by
++/// [`Repository::get_attr`](crate::Repository::get_attr) and
++/// [`Repository::get_attr_bytes`](crate::Repository::get_attr_bytes).
++#[derive(Debug, Clone, Copy, Eq)]
++pub enum AttrValue<'string> {
++    /// The attribute is set to true.
++    True,
++    /// The attribute is unset (set to false).
++    False,
++    /// The attribute is set to a [valid UTF-8 string](prim at str).
++    String(&'string str),
++    /// The attribute is set to a string that might not be [valid UTF-8](prim at str).
++    Bytes(&'string [u8]),
++    /// The attribute is not specified.
++    Unspecified,
++}
++
++macro_rules! from_value {
++    ($value:expr => $string:expr) => {
++        match unsafe { raw::git_attr_value($value.map_or(ptr::null(), |v| v.as_ptr().cast())) } {
++            raw::GIT_ATTR_VALUE_TRUE => Self::True,
++            raw::GIT_ATTR_VALUE_FALSE => Self::False,
++            raw::GIT_ATTR_VALUE_STRING => $string,
++            raw::GIT_ATTR_VALUE_UNSPECIFIED => Self::Unspecified,
++            _ => unreachable!(),
++        }
++    };
++}
++
++impl<'string> AttrValue<'string> {
++    /// Returns the state of an attribute by inspecting its [value](crate::Repository::get_attr)
++    /// by a [string](prim at str).
++    ///
++    /// This function always returns [`AttrValue::String`] and never returns [`AttrValue::Bytes`]
++    /// when the attribute is set to a string.
++    pub fn from_string(value: Option<&'string str>) -> Self {
++        from_value!(value => Self::String(value.unwrap()))
++    }
++
++    /// Returns the state of an attribute by inspecting its [value](crate::Repository::get_attr_bytes)
++    /// by a [byte](u8) [slice].
++    ///
++    /// This function will perform UTF-8 validation when the attribute is set to a string, returns
++    /// [`AttrValue::String`] if it's valid UTF-8 and [`AttrValue::Bytes`] otherwise.
++    pub fn from_bytes(value: Option<&'string [u8]>) -> Self {
++        let mut value = Self::always_bytes(value);
++        if let Self::Bytes(bytes) = value {
++            if let Ok(string) = str::from_utf8(bytes) {
++                value = Self::String(string);
++            }
++        }
++        value
++    }
++
++    /// Returns the state of an attribute just like [`AttrValue::from_bytes`], but skips UTF-8
++    /// validation and always returns [`AttrValue::Bytes`] when it's set to a string.
++    pub fn always_bytes(value: Option<&'string [u8]>) -> Self {
++        from_value!(value => Self::Bytes(value.unwrap()))
++    }
++}
++
++/// Compare two [`AttrValue`]s.
++///
++/// Note that this implementation does not differentiate between [`AttrValue::String`] and
++/// [`AttrValue::Bytes`].
++impl PartialEq for AttrValue<'_> {
++    fn eq(&self, other: &AttrValue<'_>) -> bool {
++        match (self, other) {
++            (Self::True, AttrValue::True)
++            | (Self::False, AttrValue::False)
++            | (Self::Unspecified, AttrValue::Unspecified) => true,
++            (AttrValue::String(string), AttrValue::Bytes(bytes))
++            | (AttrValue::Bytes(bytes), AttrValue::String(string)) => string.as_bytes() == *bytes,
++            (AttrValue::String(left), AttrValue::String(right)) => left == right,
++            (AttrValue::Bytes(left), AttrValue::Bytes(right)) => left == right,
++            _ => false,
++        }
++    }
++}
++
++#[cfg(test)]
++mod tests {
++    use super::AttrValue;
++
++    macro_rules! test_attr_value {
++        ($function:ident, $variant:ident) => {
++            const ATTR_TRUE: &str = "[internal]__TRUE__";
++            const ATTR_FALSE: &str = "[internal]__FALSE__";
++            const ATTR_UNSET: &str = "[internal]__UNSET__";
++            let as_bytes = AsRef::<[u8]>::as_ref;
++            // Use `matches!` here since the `PartialEq` implementation does not differentiate
++            // between `String` and `Bytes`.
++            assert!(matches!(
++                AttrValue::$function(Some(ATTR_TRUE.as_ref())),
++                AttrValue::$variant(s) if as_bytes(s) == ATTR_TRUE.as_bytes()
++            ));
++            assert!(matches!(
++                AttrValue::$function(Some(ATTR_FALSE.as_ref())),
++                AttrValue::$variant(s) if as_bytes(s) == ATTR_FALSE.as_bytes()
++            ));
++            assert!(matches!(
++                AttrValue::$function(Some(ATTR_UNSET.as_ref())),
++                AttrValue::$variant(s) if as_bytes(s) == ATTR_UNSET.as_bytes()
++            ));
++            assert!(matches!(
++                AttrValue::$function(Some("foo".as_ref())),
++                AttrValue::$variant(s) if as_bytes(s) == b"foo"
++            ));
++            assert!(matches!(
++                AttrValue::$function(Some("bar".as_ref())),
++                AttrValue::$variant(s) if as_bytes(s) == b"bar"
++            ));
++            assert_eq!(AttrValue::$function(None), AttrValue::Unspecified);
++        };
++    }
++
++    #[test]
++    fn attr_value_from_string() {
++        test_attr_value!(from_string, String);
++    }
++
++    #[test]
++    fn attr_value_from_bytes() {
++        test_attr_value!(from_bytes, String);
++        assert!(matches!(
++            AttrValue::from_bytes(Some(&[0xff])),
++            AttrValue::Bytes(&[0xff])
++        ));
++        assert!(matches!(
++            AttrValue::from_bytes(Some(b"\xffoobar")),
++            AttrValue::Bytes(b"\xffoobar")
++        ));
++    }
++
++    #[test]
++    fn attr_value_always_bytes() {
++        test_attr_value!(always_bytes, Bytes);
++        assert!(matches!(
++            AttrValue::always_bytes(Some(&[0xff; 2])),
++            AttrValue::Bytes(&[0xff, 0xff])
++        ));
++        assert!(matches!(
++            AttrValue::always_bytes(Some(b"\xffoo")),
++            AttrValue::Bytes(b"\xffoo")
++        ));
++    }
++
++    #[test]
++    fn attr_value_partial_eq() {
++        assert_eq!(AttrValue::True, AttrValue::True);
++        assert_eq!(AttrValue::False, AttrValue::False);
++        assert_eq!(AttrValue::String("foo"), AttrValue::String("foo"));
++        assert_eq!(AttrValue::Bytes(b"foo"), AttrValue::Bytes(b"foo"));
++        assert_eq!(AttrValue::String("bar"), AttrValue::Bytes(b"bar"));
++        assert_eq!(AttrValue::Bytes(b"bar"), AttrValue::String("bar"));
++        assert_eq!(AttrValue::Unspecified, AttrValue::Unspecified);
++        assert_ne!(AttrValue::True, AttrValue::False);
++        assert_ne!(AttrValue::False, AttrValue::Unspecified);
++        assert_ne!(AttrValue::Unspecified, AttrValue::True);
++        assert_ne!(AttrValue::True, AttrValue::String("true"));
++        assert_ne!(AttrValue::Unspecified, AttrValue::Bytes(b"unspecified"));
++        assert_ne!(AttrValue::Bytes(b"false"), AttrValue::False);
++        assert_ne!(AttrValue::String("unspecified"), AttrValue::Unspecified);
++        assert_ne!(AttrValue::String("foo"), AttrValue::String("bar"));
++        assert_ne!(AttrValue::Bytes(b"foo"), AttrValue::Bytes(b"bar"));
++        assert_ne!(AttrValue::String("foo"), AttrValue::Bytes(b"bar"));
++        assert_ne!(AttrValue::Bytes(b"foo"), AttrValue::String("bar"));
++    }
++}
+diff -urN rustc-1.56.0-src/vendor/git2/src/blame.rs rustc-1.56.0-src-git2/vendor/git2/src/blame.rs
+--- rustc-1.56.0-src/vendor/git2/src/blame.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/blame.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -228,6 +228,18 @@
+         }
+         self
+     }
++
++    /// The first line in the file to blame.
++    pub fn min_line(&mut self, lineno: usize) -> &mut BlameOptions {
++        self.raw.min_line = lineno;
++        self
++    }
++
++    /// The last line in the file to blame.
++    pub fn max_line(&mut self, lineno: usize) -> &mut BlameOptions {
++        self.raw.max_line = lineno;
++        self
++    }
+ }
+ 
+ impl<'repo> Binding for Blame<'repo> {
+@@ -235,7 +247,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_blame) -> Blame<'repo> {
+         Blame {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -256,7 +268,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_blame_hunk) -> BlameHunk<'blame> {
+         BlameHunk {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/blob.rs rustc-1.56.0-src-git2/vendor/git2/src/blob.rs
+--- rustc-1.56.0-src/vendor/git2/src/blob.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/blob.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -56,7 +56,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_blob) -> Blob<'repo> {
+         Blob {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -110,7 +110,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_writestream) -> BlobWriter<'repo> {
+         BlobWriter {
+-            raw: raw,
++            raw,
+             need_cleanup: true,
+             _marker: marker::PhantomData,
+         }
+diff -urN rustc-1.56.0-src/vendor/git2/src/branch.rs rustc-1.56.0-src-git2/vendor/git2/src/branch.rs
+--- rustc-1.56.0-src/vendor/git2/src/branch.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/branch.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -28,6 +28,17 @@
+         Branch { inner: reference }
+     }
+ 
++    /// Ensure the branch name is well-formed.
++    pub fn name_is_valid(name: &str) -> Result<bool, Error> {
++        crate::init();
++        let name = CString::new(name)?;
++        let mut valid: libc::c_int = 0;
++        unsafe {
++            try_call!(raw::git_branch_name_is_valid(&mut valid, name.as_ptr()));
++        }
++        Ok(valid == 1)
++    }
++
+     /// Gain access to the reference that is this branch
+     pub fn get(&self) -> &Reference<'repo> {
+         &self.inner
+@@ -120,7 +131,7 @@
+     /// pointer.
+     pub unsafe fn from_raw(raw: *mut raw::git_branch_iterator) -> Branches<'repo> {
+         Branches {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -151,7 +162,7 @@
+ 
+ #[cfg(test)]
+ mod tests {
+-    use crate::BranchType;
++    use crate::{Branch, BranchType};
+ 
+     #[test]
+     fn smoke() {
+@@ -175,4 +186,12 @@
+ 
+         b1.delete().unwrap();
+     }
++
++    #[test]
++    fn name_is_valid() {
++        assert!(Branch::name_is_valid("foo").unwrap());
++        assert!(!Branch::name_is_valid("").unwrap());
++        assert!(!Branch::name_is_valid("with spaces").unwrap());
++        assert!(!Branch::name_is_valid("~tilde").unwrap());
++    }
+ }
+diff -urN rustc-1.56.0-src/vendor/git2/src/call.rs rustc-1.56.0-src-git2/vendor/git2/src/call.rs
+--- rustc-1.56.0-src/vendor/git2/src/call.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/call.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -58,7 +58,9 @@
+ 
+     use crate::call::Convert;
+     use crate::{raw, BranchType, ConfigLevel, Direction, ObjectType, ResetType};
+-    use crate::{AutotagOption, DiffFormat, FetchPrune, FileFavor, SubmoduleIgnore};
++    use crate::{
++        AutotagOption, DiffFormat, FetchPrune, FileFavor, SubmoduleIgnore, SubmoduleUpdate,
++    };
+ 
+     impl<T: Copy> Convert<T> for T {
+         fn convert(&self) -> T {
+@@ -208,6 +210,18 @@
+             }
+         }
+     }
++
++    impl Convert<raw::git_submodule_update_t> for SubmoduleUpdate {
++        fn convert(&self) -> raw::git_submodule_update_t {
++            match *self {
++                SubmoduleUpdate::Checkout => raw::GIT_SUBMODULE_UPDATE_CHECKOUT,
++                SubmoduleUpdate::Rebase => raw::GIT_SUBMODULE_UPDATE_REBASE,
++                SubmoduleUpdate::Merge => raw::GIT_SUBMODULE_UPDATE_MERGE,
++                SubmoduleUpdate::None => raw::GIT_SUBMODULE_UPDATE_NONE,
++                SubmoduleUpdate::Default => raw::GIT_SUBMODULE_UPDATE_DEFAULT,
++            }
++        }
++    }
+ 
+     impl Convert<raw::git_remote_autotag_option_t> for AutotagOption {
+         fn convert(&self) -> raw::git_remote_autotag_option_t {
+diff -urN rustc-1.56.0-src/vendor/git2/src/cert.rs rustc-1.56.0-src-git2/vendor/git2/src/cert.rs
+--- rustc-1.56.0-src/vendor/git2/src/cert.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/cert.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -100,7 +100,7 @@
+     type Raw = *mut raw::git_cert;
+     unsafe fn from_raw(raw: *mut raw::git_cert) -> Cert<'a> {
+         Cert {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/commit.rs rustc-1.56.0-src-git2/vendor/git2/src/commit.rs
+--- rustc-1.56.0-src/vendor/git2/src/commit.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/commit.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -6,7 +6,7 @@
+ use std::str;
+ 
+ use crate::util::Binding;
+-use crate::{raw, signature, Error, Object, Oid, Signature, Time, Tree};
++use crate::{raw, signature, Buf, Error, IntoCString, Mailmap, Object, Oid, Signature, Time, Tree};
+ 
+ /// A structure to represent a git [commit][1]
+ ///
+@@ -105,6 +105,20 @@
+         str::from_utf8(self.raw_header_bytes()).ok()
+     }
+ 
++    /// Get an arbitrary header field.
++    pub fn header_field_bytes<T: IntoCString>(&self, field: T) -> Result<Buf, Error> {
++        let buf = Buf::new();
++        let raw_field = field.into_c_string()?;
++        unsafe {
++            try_call!(raw::git_commit_header_field(
++                buf.raw(),
++                &*self.raw,
++                raw_field
++            ));
++        }
++        Ok(buf)
++    }
++
+     /// Get the full raw text of the commit header.
+     pub fn raw_header_bytes(&self) -> &[u8] {
+         unsafe { crate::opt_bytes(self, raw::git_commit_raw_header(&*self.raw)).unwrap() }
+@@ -169,6 +183,20 @@
+         }
+     }
+ 
++    /// Get the author of this commit, using the mailmap to map names and email
++    /// addresses to canonical real names and email addresses.
++    pub fn author_with_mailmap(&self, mailmap: &Mailmap) -> Result<Signature<'static>, Error> {
++        let mut ret = ptr::null_mut();
++        unsafe {
++            try_call!(raw::git_commit_author_with_mailmap(
++                &mut ret,
++                &*self.raw,
++                &*mailmap.raw()
++            ));
++            Ok(Binding::from_raw(ret))
++        }
++    }
++
+     /// Get the committer of this commit.
+     pub fn committer(&self) -> Signature<'_> {
+         unsafe {
+@@ -177,6 +205,20 @@
+         }
+     }
+ 
++    /// Get the committer of this commit, using the mailmap to map names and email
++    /// addresses to canonical real names and email addresses.
++    pub fn committer_with_mailmap(&self, mailmap: &Mailmap) -> Result<Signature<'static>, Error> {
++        let mut ret = ptr::null_mut();
++        unsafe {
++            try_call!(raw::git_commit_committer_with_mailmap(
++                &mut ret,
++                &*self.raw,
++                &*mailmap.raw()
++            ));
++            Ok(Binding::from_raw(ret))
++        }
++    }
++
+     /// Amend this existing commit with all non-`None` values
+     ///
+     /// This creates a new commit that is exactly the same as the old commit,
+@@ -271,7 +313,7 @@
+     type Raw = *mut raw::git_commit;
+     unsafe fn from_raw(raw: *mut raw::git_commit) -> Commit<'repo> {
+         Commit {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -367,6 +409,11 @@
+         commit.tree().unwrap();
+         assert_eq!(commit.parents().count(), 0);
+ 
++        let tree_header_bytes = commit.header_field_bytes("tree").unwrap();
++        assert_eq!(
++            crate::Oid::from_str(tree_header_bytes.as_str().unwrap()).unwrap(),
++            commit.tree_id()
++        );
+         assert_eq!(commit.author().name(), Some("name"));
+         assert_eq!(commit.author().email(), Some("email"));
+         assert_eq!(commit.committer().name(), Some("name"));
+diff -urN rustc-1.56.0-src/vendor/git2/src/config.rs rustc-1.56.0-src-git2/vendor/git2/src/config.rs
+--- rustc-1.56.0-src/vendor/git2/src/config.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/config.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -465,7 +465,7 @@
+ impl Binding for Config {
+     type Raw = *mut raw::git_config;
+     unsafe fn from_raw(raw: *mut raw::git_config) -> Config {
+-        Config { raw: raw }
++        Config { raw }
+     }
+     fn raw(&self) -> *mut raw::git_config {
+         self.raw
+@@ -534,7 +534,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_config_entry) -> ConfigEntry<'cfg> {
+         ConfigEntry {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+             owned: true,
+         }
+@@ -549,7 +549,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_config_iterator) -> ConfigEntries<'cfg> {
+         ConfigEntries {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -571,7 +571,7 @@
+             try_call_iter!(raw::git_config_next(&mut raw, self.raw));
+             Some(Ok(ConfigEntry {
+                 owned: false,
+-                raw: raw,
++                raw,
+                 _marker: marker::PhantomData,
+             }))
+         }
+diff -urN rustc-1.56.0-src/vendor/git2/src/cred.rs rustc-1.56.0-src-git2/vendor/git2/src/cred.rs
+--- rustc-1.56.0-src/vendor/git2/src/cred.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/cred.rs	2021-10-23 20:47:39.252455615 +0200
+@@ -22,6 +22,7 @@
+     pub username: Option<String>,
+     protocol: Option<String>,
+     host: Option<String>,
++    port: Option<u16>,
+     path: Option<String>,
+     url: String,
+     commands: Vec<String>,
+@@ -170,7 +171,7 @@
+     type Raw = *mut raw::git_cred;
+ 
+     unsafe fn from_raw(raw: *mut raw::git_cred) -> Cred {
+-        Cred { raw: raw }
++        Cred { raw }
+     }
+     fn raw(&self) -> *mut raw::git_cred {
+         self.raw
+@@ -199,6 +200,7 @@
+         let mut ret = CredentialHelper {
+             protocol: None,
+             host: None,
++            port: None,
+             path: None,
+             username: None,
+             url: url.to_string(),
+@@ -210,6 +212,7 @@
+             if let Some(url::Host::Domain(s)) = url.host() {
+                 ret.host = Some(s.to_string());
+             }
++            ret.port = url.port();
+             ret.protocol = Some(url.scheme().to_string());
+         }
+         ret
+@@ -408,7 +411,11 @@
+                 let _ = writeln!(stdin, "protocol={}", p);
+             }
+             if let Some(ref p) = self.host {
+-                let _ = writeln!(stdin, "host={}", p);
++                if let Some(ref p2) = self.port {
++                    let _ = writeln!(stdin, "host={}:{}", p, p2);
++                } else {
++                    let _ = writeln!(stdin, "host={}", p);
++                }
+             }
+             if let Some(ref p) = self.path {
+                 let _ = writeln!(stdin, "path={}", p);
+@@ -640,6 +647,19 @@
+     }
+ 
+     #[test]
++    fn credential_helper9() {
++        let cfg = test_cfg! {
++            "credential.helper" => "!f() { while read line; do eval $line; done; if [ \"$host\" = example.com:3000 ]; then echo username=a; echo password=b; fi; }; f"
++        };
++        let (u, p) = CredentialHelper::new("https://example.com:3000/foo/bar")
++            .config(&cfg)
++            .execute()
++            .unwrap();
++        assert_eq!(u, "a");
++        assert_eq!(p, "b");
++    }
++
++    #[test]
+     #[cfg(feature = "ssh")]
+     fn ssh_key_from_memory() {
+         let cred = Cred::ssh_key_from_memory(
+diff -urN rustc-1.56.0-src/vendor/git2/src/describe.rs rustc-1.56.0-src-git2/vendor/git2/src/describe.rs
+--- rustc-1.56.0-src/vendor/git2/src/describe.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/describe.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -44,7 +44,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_describe_result) -> Describe<'repo> {
+         Describe {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/diff.rs rustc-1.56.0-src-git2/vendor/git2/src/diff.rs
+--- rustc-1.56.0-src/vendor/git2/src/diff.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/diff.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -58,6 +58,11 @@
+     raw: raw::git_diff_format_email_options,
+ }
+ 
++/// Control behavior of formatting emails
++pub struct DiffPatchidOptions {
++    raw: raw::git_diff_patchid_options,
++}
++
+ /// An iterator over the diffs in a delta
+ pub struct Deltas<'diff> {
+     range: Range<usize>,
+@@ -278,6 +283,21 @@
+         Ok(buf)
+     }
+ 
++    /// Create an patchid from a diff.
++    pub fn patchid(&self, opts: Option<&mut DiffPatchidOptions>) -> Result<Oid, Error> {
++        let mut raw = raw::git_oid {
++            id: [0; raw::GIT_OID_RAWSZ],
++        };
++        unsafe {
++            try_call!(raw::git_diff_patchid(
++                &mut raw,
++                self.raw,
++                opts.map(|o| &mut o.raw)
++            ));
++            Ok(Binding::from_raw(&raw as *const _))
++        }
++    }
++
+     // TODO: num_deltas_of_type, find_similar
+ }
+ impl Diff<'static> {
+@@ -289,6 +309,7 @@
+     /// a patch file likely contains abbreviated object IDs, so the
+     /// object IDs parsed by this function will also be abreviated.
+     pub fn from_buffer(buffer: &[u8]) -> Result<Diff<'static>, Error> {
++        crate::init();
+         let mut diff: *mut raw::git_diff = std::ptr::null_mut();
+         unsafe {
+             // NOTE: Doesn't depend on repo, so lifetime can be 'static
+@@ -318,9 +339,9 @@
+             (*data)(delta, hunk, line)
+         });
+         if r == Some(true) {
+-            0
++            raw::GIT_OK
+         } else {
+-            -1
++            raw::GIT_EUSER
+         }
+     }
+ }
+@@ -341,9 +362,9 @@
+             }
+         });
+         if r == Some(true) {
+-            0
++            raw::GIT_OK
+         } else {
+-            -1
++            raw::GIT_EUSER
+         }
+     }
+ }
+@@ -365,9 +386,9 @@
+             }
+         });
+         if r == Some(true) {
+-            0
++            raw::GIT_OK
+         } else {
+-            -1
++            raw::GIT_EUSER
+         }
+     }
+ }
+@@ -389,9 +410,9 @@
+             }
+         });
+         if r == Some(true) {
+-            0
++            raw::GIT_OK
+         } else {
+-            -1
++            raw::GIT_EUSER
+         }
+     }
+ }
+@@ -415,9 +436,9 @@
+             }
+         });
+         if r == Some(true) {
+-            0
++            raw::GIT_OK
+         } else {
+-            -1
++            raw::GIT_EUSER
+         }
+     }
+ }
+@@ -426,7 +447,7 @@
+     type Raw = *mut raw::git_diff;
+     unsafe fn from_raw(raw: *mut raw::git_diff) -> Diff<'repo> {
+         Diff {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -524,7 +545,7 @@
+     type Raw = *mut raw::git_diff_delta;
+     unsafe fn from_raw(raw: *mut raw::git_diff_delta) -> DiffDelta<'a> {
+         DiffDelta {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -609,7 +630,7 @@
+     type Raw = *const raw::git_diff_file;
+     unsafe fn from_raw(raw: *const raw::git_diff_file) -> DiffFile<'a> {
+         DiffFile {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -793,6 +814,11 @@
+         self.flag(raw::GIT_DIFF_IGNORE_WHITESPACE_EOL, ignore)
+     }
+ 
++    /// Ignore blank lines
++    pub fn ignore_blank_lines(&mut self, ignore: bool) -> &mut DiffOptions {
++        self.flag(raw::GIT_DIFF_IGNORE_BLANK_LINES, ignore)
++    }
++
+     /// When generating patch text, include the content of untracked files.
+     ///
+     /// This automatically turns on `include_untracked` but it does not turn on
+@@ -931,6 +957,61 @@
+ }
+ impl<'diff> ExactSizeIterator for Deltas<'diff> {}
+ 
++/// Line origin constants.
++#[derive(Copy, Clone, Debug, PartialEq)]
++pub enum DiffLineType {
++    /// These values will be sent to `git_diff_line_cb` along with the line
++    Context,
++    ///
++    Addition,
++    ///
++    Deletion,
++    /// Both files have no LF at end
++    ContextEOFNL,
++    /// Old has no LF at end, new does
++    AddEOFNL,
++    /// Old has LF at end, new does not
++    DeleteEOFNL,
++    /// 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,
++    ///
++    HunkHeader,
++    /// For "Binary files x and y differ"
++    Binary,
++}
++
++impl Binding for DiffLineType {
++    type Raw = raw::git_diff_line_t;
++    unsafe fn from_raw(raw: raw::git_diff_line_t) -> Self {
++        match raw {
++            raw::GIT_DIFF_LINE_CONTEXT => DiffLineType::Context,
++            raw::GIT_DIFF_LINE_ADDITION => DiffLineType::Addition,
++            raw::GIT_DIFF_LINE_DELETION => DiffLineType::Deletion,
++            raw::GIT_DIFF_LINE_CONTEXT_EOFNL => DiffLineType::ContextEOFNL,
++            raw::GIT_DIFF_LINE_ADD_EOFNL => DiffLineType::AddEOFNL,
++            raw::GIT_DIFF_LINE_DEL_EOFNL => DiffLineType::DeleteEOFNL,
++            raw::GIT_DIFF_LINE_FILE_HDR => DiffLineType::FileHeader,
++            raw::GIT_DIFF_LINE_HUNK_HDR => DiffLineType::HunkHeader,
++            raw::GIT_DIFF_LINE_BINARY => DiffLineType::Binary,
++            _ => panic!("Unknown git diff line type"),
++        }
++    }
++    fn raw(&self) -> raw::git_diff_line_t {
++        match *self {
++            DiffLineType::Context => raw::GIT_DIFF_LINE_CONTEXT,
++            DiffLineType::Addition => raw::GIT_DIFF_LINE_ADDITION,
++            DiffLineType::Deletion => raw::GIT_DIFF_LINE_DELETION,
++            DiffLineType::ContextEOFNL => raw::GIT_DIFF_LINE_CONTEXT_EOFNL,
++            DiffLineType::AddEOFNL => raw::GIT_DIFF_LINE_ADD_EOFNL,
++            DiffLineType::DeleteEOFNL => raw::GIT_DIFF_LINE_DEL_EOFNL,
++            DiffLineType::FileHeader => raw::GIT_DIFF_LINE_FILE_HDR,
++            DiffLineType::HunkHeader => raw::GIT_DIFF_LINE_HUNK_HDR,
++            DiffLineType::Binary => raw::GIT_DIFF_LINE_BINARY,
++        }
++    }
++}
++
+ impl<'a> DiffLine<'a> {
+     /// Line number in old file or `None` for added line
+     pub fn old_lineno(&self) -> Option<u32> {
+@@ -968,6 +1049,12 @@
+         }
+     }
+ 
++    /// origin of this `DiffLine`.
++    ///
++    pub fn origin_value(&self) -> DiffLineType {
++        unsafe { Binding::from_raw((*self.raw).origin as raw::git_diff_line_t) }
++    }
++
+     /// Sigil showing the origin of this `DiffLine`.
+     ///
+     ///  * ` ` - Line context
+@@ -999,7 +1086,7 @@
+     type Raw = *const raw::git_diff_line;
+     unsafe fn from_raw(raw: *const raw::git_diff_line) -> DiffLine<'a> {
+         DiffLine {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -1061,7 +1148,7 @@
+     type Raw = *const raw::git_diff_hunk;
+     unsafe fn from_raw(raw: *const raw::git_diff_hunk) -> DiffHunk<'a> {
+         DiffHunk {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -1083,7 +1170,7 @@
+ }
+ 
+ impl DiffStats {
+-    /// Get the total number of files chaned in a diff.
++    /// Get the total number of files changed in a diff.
+     pub fn files_changed(&self) -> usize {
+         unsafe { raw::git_diff_stats_files_changed(&*self.raw) as usize }
+     }
+@@ -1117,7 +1204,7 @@
+     type Raw = *mut raw::git_diff_stats;
+ 
+     unsafe fn from_raw(raw: *mut raw::git_diff_stats) -> DiffStats {
+-        DiffStats { raw: raw }
++        DiffStats { raw }
+     }
+     fn raw(&self) -> *mut raw::git_diff_stats {
+         self.raw
+@@ -1166,7 +1253,7 @@
+     type Raw = *const raw::git_diff_binary;
+     unsafe fn from_raw(raw: *const raw::git_diff_binary) -> DiffBinary<'a> {
+         DiffBinary {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -1198,7 +1285,7 @@
+     type Raw = *const raw::git_diff_binary_file;
+     unsafe fn from_raw(raw: *const raw::git_diff_binary_file) -> DiffBinaryFile<'a> {
+         DiffBinaryFile {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -1433,9 +1520,29 @@
+     }
+ }
+ 
++impl DiffPatchidOptions {
++    /// Creates a new set of patchid options,
++    /// initialized to the default values
++    pub fn new() -> Self {
++        let mut opts = DiffPatchidOptions {
++            raw: unsafe { mem::zeroed() },
++        };
++        assert_eq!(
++            unsafe {
++                raw::git_diff_patchid_options_init(
++                    &mut opts.raw,
++                    raw::GIT_DIFF_PATCHID_OPTIONS_VERSION,
++                )
++            },
++            0
++        );
++        opts
++    }
++}
++
+ #[cfg(test)]
+ mod tests {
+-    use crate::{DiffOptions, Signature, Time};
++    use crate::{DiffLineType, DiffOptions, Oid, Signature, Time};
+     use std::borrow::Borrow;
+     use std::fs::File;
+     use std::io::Write;
+@@ -1450,6 +1557,8 @@
+         assert_eq!(stats.insertions(), 0);
+         assert_eq!(stats.deletions(), 0);
+         assert_eq!(stats.files_changed(), 0);
++        let patchid = diff.patchid(None).unwrap();
++        assert_ne!(patchid, Oid::zero());
+     }
+ 
+     #[test]
+@@ -1684,4 +1793,58 @@
+             assert_eq!(line.trim(), "")
+         }
+     }
++
++    #[test]
++    fn foreach_diff_line_origin_value() {
++        let foo_path = Path::new("foo");
++        let (td, repo) = crate::test::repo_init();
++        t!(t!(File::create(&td.path().join(foo_path))).write_all(b"bar\n"));
++        let mut index = t!(repo.index());
++        t!(index.add_path(foo_path));
++        let mut opts = DiffOptions::new();
++        opts.include_untracked(true);
++        let diff = t!(repo.diff_tree_to_index(None, Some(&index), Some(&mut opts)));
++        let mut origin_values: Vec<DiffLineType> = Vec::new();
++        t!(diff.foreach(
++            &mut |_file, _progress| { true },
++            None,
++            None,
++            Some(&mut |_file, _hunk, line| {
++                origin_values.push(line.origin_value());
++                true
++            })
++        ));
++        assert_eq!(origin_values.len(), 1);
++        assert_eq!(origin_values[0], DiffLineType::Addition);
++    }
++
++    #[test]
++    fn foreach_exits_with_euser() {
++        let foo_path = Path::new("foo");
++        let bar_path = Path::new("foo");
++
++        let (td, repo) = crate::test::repo_init();
++        t!(t!(File::create(&td.path().join(foo_path))).write_all(b"bar\n"));
++
++        let mut index = t!(repo.index());
++        t!(index.add_path(foo_path));
++        t!(index.add_path(bar_path));
++
++        let mut opts = DiffOptions::new();
++        opts.include_untracked(true);
++        let diff = t!(repo.diff_tree_to_index(None, Some(&index), Some(&mut opts)));
++
++        let mut calls = 0;
++        let result = diff.foreach(
++            &mut |_file, _progress| {
++                calls += 1;
++                false
++            },
++            None,
++            None,
++            None,
++        );
++
++        assert_eq!(result.unwrap_err().code(), crate::ErrorCode::User);
++    }
+ }
+diff -urN rustc-1.56.0-src/vendor/git2/src/error.rs rustc-1.56.0-src-git2/vendor/git2/src/error.rs
+--- rustc-1.56.0-src/vendor/git2/src/error.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/error.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -69,12 +69,12 @@
+     }
+ 
+     unsafe fn from_raw(code: c_int, ptr: *const raw::git_error) -> Error {
+-        let msg = CStr::from_ptr((*ptr).message as *const _).to_bytes();
+-        let msg = String::from_utf8_lossy(msg).into_owned();
++        let message = CStr::from_ptr((*ptr).message as *const _).to_bytes();
++        let message = String::from_utf8_lossy(message).into_owned();
+         Error {
+-            code: code,
++            code,
+             klass: (*ptr).klass,
+-            message: msg,
++            message,
+         }
+     }
+ 
+diff -urN rustc-1.56.0-src/vendor/git2/src/index.rs rustc-1.56.0-src-git2/vendor/git2/src/index.rs
+--- rustc-1.56.0-src/vendor/git2/src/index.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/index.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -166,7 +166,7 @@
+                 gid: entry.gid,
+                 file_size: entry.file_size,
+                 id: *entry.id.raw(),
+-                flags: flags,
++                flags,
+                 flags_extended: entry.flags_extended,
+                 path: path.as_ptr(),
+                 mtime: raw::git_index_time {
+@@ -223,7 +223,7 @@
+                 gid: entry.gid,
+                 file_size: entry.file_size,
+                 id: *entry.id.raw(),
+-                flags: flags,
++                flags,
+                 flags_extended: entry.flags_extended,
+                 path: path.as_ptr(),
+                 mtime: raw::git_index_time {
+@@ -600,7 +600,7 @@
+ impl Binding for Index {
+     type Raw = *mut raw::git_index;
+     unsafe fn from_raw(raw: *mut raw::git_index) -> Index {
+-        Index { raw: raw }
++        Index { raw }
+     }
+     fn raw(&self) -> *mut raw::git_index {
+         self.raw
+@@ -718,15 +718,15 @@
+         let path = slice::from_raw_parts(path as *const u8, pathlen);
+ 
+         IndexEntry {
+-            dev: dev,
+-            ino: ino,
+-            mode: mode,
+-            uid: uid,
+-            gid: gid,
+-            file_size: file_size,
++            dev,
++            ino,
++            mode,
++            uid,
++            gid,
++            file_size,
+             id: Binding::from_raw(&id as *const _),
+-            flags: flags,
+-            flags_extended: flags_extended,
++            flags,
++            flags_extended,
+             path: path.to_vec(),
+             mtime: Binding::from_raw(mtime),
+             ctime: Binding::from_raw(ctime),
+diff -urN rustc-1.56.0-src/vendor/git2/src/lib.rs rustc-1.56.0-src-git2/vendor/git2/src/lib.rs
+--- rustc-1.56.0-src/vendor/git2/src/lib.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/lib.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -80,6 +80,7 @@
+ use std::sync::Once;
+ 
+ pub use crate::apply::{ApplyLocation, ApplyOptions};
++pub use crate::attr::AttrValue;
+ pub use crate::blame::{Blame, BlameHunk, BlameIter, BlameOptions};
+ pub use crate::blob::{Blob, BlobWriter};
+ pub use crate::branch::{Branch, Branches};
+@@ -91,15 +92,20 @@
+ pub use crate::describe::{Describe, DescribeFormatOptions, DescribeOptions};
+ pub use crate::diff::{Deltas, Diff, DiffDelta, DiffFile, DiffOptions};
+ pub use crate::diff::{DiffBinary, DiffBinaryFile, DiffBinaryKind};
+-pub use crate::diff::{DiffFindOptions, DiffHunk, DiffLine, DiffStats};
++pub use crate::diff::{DiffFindOptions, DiffHunk, DiffLine, DiffLineType, DiffStats};
+ pub use crate::error::Error;
+ pub use crate::index::{
+     Index, IndexConflict, IndexConflicts, IndexEntries, IndexEntry, IndexMatchedPath,
+ };
+ pub use crate::indexer::{IndexerProgress, Progress};
++pub use crate::mailmap::Mailmap;
+ pub use crate::mempack::Mempack;
+ pub use crate::merge::{AnnotatedCommit, MergeOptions};
+-pub use crate::message::{message_prettify, DEFAULT_COMMENT_CHAR};
++pub use crate::message::{
++    message_prettify, message_trailers_bytes, message_trailers_strs, MessageTrailersBytes,
++    MessageTrailersBytesIterator, MessageTrailersStrs, MessageTrailersStrsIterator,
++    DEFAULT_COMMENT_CHAR,
++};
+ pub use crate::note::{Note, Notes};
+ pub use crate::object::Object;
+ pub use crate::odb::{Odb, OdbObject, OdbPackwriter, OdbReader, OdbWriter};
+@@ -128,9 +134,12 @@
+ pub use crate::submodule::{Submodule, SubmoduleUpdateOptions};
+ pub use crate::tag::Tag;
+ pub use crate::time::{IndexTime, Time};
++pub use crate::tracing::{trace_set, TraceLevel};
++pub use crate::transaction::Transaction;
+ pub use crate::tree::{Tree, TreeEntry, TreeIter, TreeWalkMode, TreeWalkResult};
+ pub use crate::treebuilder::TreeBuilder;
+ pub use crate::util::IntoCString;
++pub use crate::version::Version;
+ pub use crate::worktree::{Worktree, WorktreeAddOptions, WorktreeLockStatus, WorktreePruneOptions};
+ 
+ // Create a convinience method on bitflag struct which checks the given flag
+@@ -633,6 +642,7 @@
+ mod test;
+ #[macro_use]
+ mod panic;
++mod attr;
+ mod call;
+ mod util;
+ 
+@@ -657,6 +667,7 @@
+ mod error;
+ mod index;
+ mod indexer;
++mod mailmap;
+ mod mempack;
+ mod merge;
+ mod message;
+@@ -685,8 +696,11 @@
+ mod tag;
+ mod tagforeach;
+ mod time;
++mod tracing;
++mod transaction;
+ mod tree;
+ mod treebuilder;
++mod version;
+ mod worktree;
+ 
+ fn init() {
+@@ -929,6 +943,34 @@
+     }
+ }
+ 
++impl SubmoduleIgnore {
++    /// Converts a [`raw::git_submodule_ignore_t`] to a [`SubmoduleIgnore`]
++    pub fn from_raw(raw: raw::git_submodule_ignore_t) -> Self {
++        match raw {
++            raw::GIT_SUBMODULE_IGNORE_UNSPECIFIED => SubmoduleIgnore::Unspecified,
++            raw::GIT_SUBMODULE_IGNORE_NONE => SubmoduleIgnore::None,
++            raw::GIT_SUBMODULE_IGNORE_UNTRACKED => SubmoduleIgnore::Untracked,
++            raw::GIT_SUBMODULE_IGNORE_DIRTY => SubmoduleIgnore::Dirty,
++            raw::GIT_SUBMODULE_IGNORE_ALL => SubmoduleIgnore::All,
++            n => panic!("unknown submodule ignore rule: {}", n),
++        }
++    }
++}
++
++impl SubmoduleUpdate {
++    /// Converts a [`raw::git_submodule_update_t`] to a [`SubmoduleUpdate`]
++    pub fn from_raw(raw: raw::git_submodule_update_t) -> Self {
++        match raw {
++            raw::GIT_SUBMODULE_UPDATE_CHECKOUT => SubmoduleUpdate::Checkout,
++            raw::GIT_SUBMODULE_UPDATE_REBASE => SubmoduleUpdate::Rebase,
++            raw::GIT_SUBMODULE_UPDATE_MERGE => SubmoduleUpdate::Merge,
++            raw::GIT_SUBMODULE_UPDATE_NONE => SubmoduleUpdate::None,
++            raw::GIT_SUBMODULE_UPDATE_DEFAULT => SubmoduleUpdate::Default,
++            n => panic!("unknown submodule update strategy: {}", n),
++        }
++    }
++}
++
+ bitflags! {
+     /// Status flags for a single file
+     ///
+@@ -1171,6 +1213,7 @@
+ /// These values represent settings for the `submodule.$name.ignore`
+ /// configuration value which says how deeply to look at the working
+ /// directory when getting the submodule status.
++#[derive(Debug)]
+ pub enum SubmoduleIgnore {
+     /// Use the submodule's configuration
+     Unspecified,
+@@ -1184,6 +1227,31 @@
+     All,
+ }
+ 
++/// Submodule update values
++///
++/// These values represent settings for the `submodule.$name.update`
++/// configuration value which says how to handle `git submodule update`
++/// for this submodule. The value is usually set in the ".gitmodules"
++/// file and copied to ".git/config" when the submodule is initialized.
++#[derive(Debug)]
++pub enum SubmoduleUpdate {
++    /// The default; when a submodule is updated, checkout the new detached
++    /// HEAD to the submodule directory.
++    Checkout,
++    /// Update by rebasing the current checked out branch onto the commit from
++    /// the superproject.
++    Rebase,
++    /// Update by merging the commit in the superproject into the current
++    /// checkout out branch of the submodule.
++    Merge,
++    /// Do not update this submodule even when the commit in the superproject
++    /// is updated.
++    None,
++    /// Not used except as static initializer when we don't want any particular
++    /// update rule to be specified.
++    Default,
++}
++
+ bitflags! {
+     /// ...
+     pub struct PathspecFlags: u32 {
+diff -urN rustc-1.56.0-src/vendor/git2/src/mailmap.rs rustc-1.56.0-src-git2/vendor/git2/src/mailmap.rs
+--- rustc-1.56.0-src/vendor/git2/src/mailmap.rs	1970-01-01 01:00:00.000000000 +0100
++++ rustc-1.56.0-src-git2/vendor/git2/src/mailmap.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -0,0 +1,134 @@
++use std::ffi::CString;
++use std::ptr;
++
++use crate::util::Binding;
++use crate::{raw, Error, Signature};
++
++/// A structure to represent a repository's .mailmap file.
++///
++/// The representation cannot be written to disk.
++pub struct Mailmap {
++    raw: *mut raw::git_mailmap,
++}
++
++impl Binding for Mailmap {
++    type Raw = *mut raw::git_mailmap;
++
++    unsafe fn from_raw(ptr: *mut raw::git_mailmap) -> Mailmap {
++        Mailmap { raw: ptr }
++    }
++
++    fn raw(&self) -> *mut raw::git_mailmap {
++        self.raw
++    }
++}
++
++impl Drop for Mailmap {
++    fn drop(&mut self) {
++        unsafe {
++            raw::git_mailmap_free(self.raw);
++        }
++    }
++}
++
++impl Mailmap {
++    /// Creates an empty, in-memory mailmap object.
++    pub fn new() -> Result<Mailmap, Error> {
++        crate::init();
++        let mut ret = ptr::null_mut();
++        unsafe {
++            try_call!(raw::git_mailmap_new(&mut ret));
++            Ok(Binding::from_raw(ret))
++        }
++    }
++
++    /// Creates an in-memory mailmap object representing the given buffer.
++    pub fn from_buffer(buf: &str) -> Result<Mailmap, Error> {
++        crate::init();
++        let mut ret = ptr::null_mut();
++        let len = buf.len();
++        let buf = CString::new(buf)?;
++        unsafe {
++            try_call!(raw::git_mailmap_from_buffer(&mut ret, buf, len));
++            Ok(Binding::from_raw(ret))
++        }
++    }
++
++    /// Adds a new entry to this in-memory mailmap object.
++    pub fn add_entry(
++        &mut self,
++        real_name: Option<&str>,
++        real_email: Option<&str>,
++        replace_name: Option<&str>,
++        replace_email: &str,
++    ) -> Result<(), Error> {
++        let real_name = crate::opt_cstr(real_name)?;
++        let real_email = crate::opt_cstr(real_email)?;
++        let replace_name = crate::opt_cstr(replace_name)?;
++        let replace_email = CString::new(replace_email)?;
++        unsafe {
++            try_call!(raw::git_mailmap_add_entry(
++                self.raw,
++                real_name,
++                real_email,
++                replace_name,
++                replace_email
++            ));
++            Ok(())
++        }
++    }
++
++    /// Resolves a signature to its real name and email address.
++    pub fn resolve_signature(&self, sig: &Signature<'_>) -> Result<Signature<'static>, Error> {
++        let mut ret = ptr::null_mut();
++        unsafe {
++            try_call!(raw::git_mailmap_resolve_signature(
++                &mut ret,
++                &*self.raw,
++                sig.raw()
++            ));
++            Ok(Binding::from_raw(ret))
++        }
++    }
++}
++
++#[cfg(test)]
++mod tests {
++    use super::*;
++
++    #[test]
++    fn smoke() {
++        let sig_name = "name";
++        let sig_email = "email";
++        let sig = t!(Signature::now(sig_name, sig_email));
++
++        let mut mm = t!(Mailmap::new());
++
++        let mailmapped_sig = t!(mm.resolve_signature(&sig));
++        assert_eq!(mailmapped_sig.name(), Some(sig_name));
++        assert_eq!(mailmapped_sig.email(), Some(sig_email));
++
++        t!(mm.add_entry(None, None, None, sig_email));
++        t!(mm.add_entry(
++            Some("real name"),
++            Some("real at email"),
++            Some(sig_name),
++            sig_email,
++        ));
++
++        let mailmapped_sig = t!(mm.resolve_signature(&sig));
++        assert_eq!(mailmapped_sig.name(), Some("real name"));
++        assert_eq!(mailmapped_sig.email(), Some("real at email"));
++    }
++
++    #[test]
++    fn from_buffer() {
++        let buf = "<prøper at emæil> <email>";
++        let mm = t!(Mailmap::from_buffer(&buf));
++
++        let sig = t!(Signature::now("name", "email"));
++        let mailmapped_sig = t!(mm.resolve_signature(&sig));
++        assert_eq!(mailmapped_sig.name(), Some("name"));
++        assert_eq!(mailmapped_sig.email(), Some("prøper at emæil"));
++    }
++}
+diff -urN rustc-1.56.0-src/vendor/git2/src/mempack.rs rustc-1.56.0-src-git2/vendor/git2/src/mempack.rs
+--- rustc-1.56.0-src/vendor/git2/src/mempack.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/mempack.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -16,7 +16,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_odb_backend) -> Mempack<'odb> {
+         Mempack {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/merge.rs rustc-1.56.0-src-git2/vendor/git2/src/merge.rs
+--- rustc-1.56.0-src/vendor/git2/src/merge.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/merge.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -178,7 +178,7 @@
+     type Raw = *mut raw::git_annotated_commit;
+     unsafe fn from_raw(raw: *mut raw::git_annotated_commit) -> AnnotatedCommit<'repo> {
+         AnnotatedCommit {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/message.rs rustc-1.56.0-src-git2/vendor/git2/src/message.rs
+--- rustc-1.56.0-src/vendor/git2/src/message.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/message.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -1,4 +1,7 @@
++use core::ops::Range;
++use std::ffi::CStr;
+ use std::ffi::CString;
++use std::ptr;
+ 
+ use libc::{c_char, c_int};
+ 
+@@ -31,12 +34,216 @@
+ /// The default comment character for `message_prettify` ('#')
+ pub const DEFAULT_COMMENT_CHAR: Option<u8> = Some(b'#');
+ 
++/// Get the trailers for the given message.
++///
++/// Use this function when you are dealing with a UTF-8-encoded message.
++pub fn message_trailers_strs(message: &str) -> Result<MessageTrailersStrs, Error> {
++    _message_trailers(message.into_c_string()?).map(|res| MessageTrailersStrs(res))
++}
++
++/// Get the trailers for the given message.
++///
++/// Use this function when the message might not be UTF-8-encoded,
++/// or if you want to handle the returned trailer key–value pairs
++/// as bytes.
++pub fn message_trailers_bytes<S: IntoCString>(message: S) -> Result<MessageTrailersBytes, Error> {
++    _message_trailers(message.into_c_string()?).map(|res| MessageTrailersBytes(res))
++}
++
++fn _message_trailers(message: CString) -> Result<MessageTrailers, Error> {
++    let ret = MessageTrailers::new();
++    unsafe {
++        try_call!(raw::git_message_trailers(ret.raw(), message));
++    }
++    Ok(ret)
++}
++
++/// Collection of UTF-8-encoded trailers.
++///
++/// Use `iter()` to get access to the values.
++pub struct MessageTrailersStrs(MessageTrailers);
++
++impl MessageTrailersStrs {
++    /// Create a borrowed iterator.
++    pub fn iter(&self) -> MessageTrailersStrsIterator<'_> {
++        MessageTrailersStrsIterator(self.0.iter())
++    }
++    /// The number of trailer key–value pairs.
++    pub fn len(&self) -> usize {
++        self.0.len()
++    }
++    /// Convert to the “bytes” variant.
++    pub fn to_bytes(self) -> MessageTrailersBytes {
++        MessageTrailersBytes(self.0)
++    }
++}
++
++/// Collection of unencoded (bytes) trailers.
++///
++/// Use `iter()` to get access to the values.
++pub struct MessageTrailersBytes(MessageTrailers);
++
++impl MessageTrailersBytes {
++    /// Create a borrowed iterator.
++    pub fn iter(&self) -> MessageTrailersBytesIterator<'_> {
++        MessageTrailersBytesIterator(self.0.iter())
++    }
++    /// The number of trailer key–value pairs.
++    pub fn len(&self) -> usize {
++        self.0.len()
++    }
++}
++
++struct MessageTrailers {
++    raw: raw::git_message_trailer_array,
++}
++
++impl MessageTrailers {
++    fn new() -> MessageTrailers {
++        crate::init();
++        unsafe {
++            Binding::from_raw(&mut raw::git_message_trailer_array {
++                trailers: ptr::null_mut(),
++                count: 0,
++                _trailer_block: ptr::null_mut(),
++            } as *mut _)
++        }
++    }
++    fn iter(&self) -> MessageTrailersIterator<'_> {
++        MessageTrailersIterator {
++            trailers: self,
++            range: Range {
++                start: 0,
++                end: self.raw.count,
++            },
++        }
++    }
++    fn len(&self) -> usize {
++        self.raw.count
++    }
++}
++
++impl Drop for MessageTrailers {
++    fn drop(&mut self) {
++        unsafe {
++            raw::git_message_trailer_array_free(&mut self.raw);
++        }
++    }
++}
++
++impl Binding for MessageTrailers {
++    type Raw = *mut raw::git_message_trailer_array;
++    unsafe fn from_raw(raw: *mut raw::git_message_trailer_array) -> MessageTrailers {
++        MessageTrailers { raw: *raw }
++    }
++    fn raw(&self) -> *mut raw::git_message_trailer_array {
++        &self.raw as *const _ as *mut _
++    }
++}
++
++struct MessageTrailersIterator<'a> {
++    trailers: &'a MessageTrailers,
++    range: Range<usize>,
++}
++
++fn to_raw_tuple(trailers: &MessageTrailers, index: usize) -> (*const c_char, *const c_char) {
++    unsafe {
++        let addr = trailers.raw.trailers.wrapping_add(index);
++        ((*addr).key, (*addr).value)
++    }
++}
++
++/// Borrowed iterator over the UTF-8-encoded trailers.
++pub struct MessageTrailersStrsIterator<'a>(MessageTrailersIterator<'a>);
++
++impl<'pair> Iterator for MessageTrailersStrsIterator<'pair> {
++    type Item = (&'pair str, &'pair str);
++
++    fn next(&mut self) -> Option<Self::Item> {
++        self.0
++            .range
++            .next()
++            .map(|index| to_str_tuple(&self.0.trailers, index))
++    }
++
++    fn size_hint(&self) -> (usize, Option<usize>) {
++        self.0.range.size_hint()
++    }
++}
++
++impl ExactSizeIterator for MessageTrailersStrsIterator<'_> {
++    fn len(&self) -> usize {
++        self.0.range.len()
++    }
++}
++
++impl DoubleEndedIterator for MessageTrailersStrsIterator<'_> {
++    fn next_back(&mut self) -> Option<Self::Item> {
++        self.0
++            .range
++            .next_back()
++            .map(|index| to_str_tuple(&self.0.trailers, index))
++    }
++}
++
++fn to_str_tuple(trailers: &MessageTrailers, index: usize) -> (&str, &str) {
++    unsafe {
++        let (rkey, rvalue) = to_raw_tuple(&trailers, index);
++        let key = CStr::from_ptr(rkey).to_str().unwrap();
++        let value = CStr::from_ptr(rvalue).to_str().unwrap();
++        (key, value)
++    }
++}
++
++/// Borrowed iterator over the raw (bytes) trailers.
++pub struct MessageTrailersBytesIterator<'a>(MessageTrailersIterator<'a>);
++
++impl<'pair> Iterator for MessageTrailersBytesIterator<'pair> {
++    type Item = (&'pair [u8], &'pair [u8]);
++
++    fn next(&mut self) -> Option<Self::Item> {
++        self.0
++            .range
++            .next()
++            .map(|index| to_bytes_tuple(&self.0.trailers, index))
++    }
++
++    fn size_hint(&self) -> (usize, Option<usize>) {
++        self.0.range.size_hint()
++    }
++}
++
++impl ExactSizeIterator for MessageTrailersBytesIterator<'_> {
++    fn len(&self) -> usize {
++        self.0.range.len()
++    }
++}
++
++impl DoubleEndedIterator for MessageTrailersBytesIterator<'_> {
++    fn next_back(&mut self) -> Option<Self::Item> {
++        self.0
++            .range
++            .next_back()
++            .map(|index| to_bytes_tuple(&self.0.trailers, index))
++    }
++}
++
++fn to_bytes_tuple(trailers: &MessageTrailers, index: usize) -> (&[u8], &[u8]) {
++    unsafe {
++        let (rkey, rvalue) = to_raw_tuple(&trailers, index);
++        let key = CStr::from_ptr(rkey).to_bytes();
++        let value = CStr::from_ptr(rvalue).to_bytes();
++        (key, value)
++    }
++}
++
+ #[cfg(test)]
+ mod tests {
+-    use crate::{message_prettify, DEFAULT_COMMENT_CHAR};
+ 
+     #[test]
+     fn prettify() {
++        use crate::{message_prettify, DEFAULT_COMMENT_CHAR};
++
+         // This does not attempt to duplicate the extensive tests for
+         // git_message_prettify in libgit2, just a few representative values to
+         // make sure the interface works as expected.
+@@ -58,4 +265,80 @@
+             "1\n"
+         );
+     }
++
++    #[test]
++    fn trailers() {
++        use crate::{message_trailers_bytes, message_trailers_strs, MessageTrailersStrs};
++        use std::collections::HashMap;
++
++        // no trailers
++        let message1 = "
++WHAT ARE WE HERE FOR
++
++What are we here for?
++
++Just to be eaten?
++";
++        let expected: HashMap<&str, &str> = HashMap::new();
++        assert_eq!(expected, to_map(&message_trailers_strs(message1).unwrap()));
++
++        // standard PSA
++        let message2 = "
++Attention all
++
++We are out of tomatoes.
++
++Spoken-by: Major Turnips
++Transcribed-by: Seargant Persimmons
++Signed-off-by: Colonel Kale
++";
++        let expected: HashMap<&str, &str> = vec![
++            ("Spoken-by", "Major Turnips"),
++            ("Transcribed-by", "Seargant Persimmons"),
++            ("Signed-off-by", "Colonel Kale"),
++        ]
++        .into_iter()
++        .collect();
++        assert_eq!(expected, to_map(&message_trailers_strs(message2).unwrap()));
++
++        // ignore everything after `---`
++        let message3 = "
++The fate of Seargant Green-Peppers
++
++Seargant Green-Peppers was killed by Caterpillar Battalion 44.
++
++Signed-off-by: Colonel Kale
++---
++I never liked that guy, anyway.
++
++Opined-by: Corporal Garlic
++";
++        let expected: HashMap<&str, &str> = vec![("Signed-off-by", "Colonel Kale")]
++            .into_iter()
++            .collect();
++        assert_eq!(expected, to_map(&message_trailers_strs(message3).unwrap()));
++
++        // Raw bytes message; not valid UTF-8
++        // Source: https://stackoverflow.com/a/3886015/1725151
++        let message4 = b"
++Be honest guys
++
++Am I a malformed brussels sprout?
++
++Signed-off-by: Lieutenant \xe2\x28\xa1prout
++";
++
++        let trailer = message_trailers_bytes(&message4[..]).unwrap();
++        let expected = (&b"Signed-off-by"[..], &b"Lieutenant \xe2\x28\xa1prout"[..]);
++        let actual = trailer.iter().next().unwrap();
++        assert_eq!(expected, actual);
++
++        fn to_map(trailers: &MessageTrailersStrs) -> HashMap<&str, &str> {
++            let mut map = HashMap::with_capacity(trailers.len());
++            for (key, value) in trailers.iter() {
++                map.insert(key, value);
++            }
++            map
++        }
++    }
+ }
+diff -urN rustc-1.56.0-src/vendor/git2/src/note.rs rustc-1.56.0-src-git2/vendor/git2/src/note.rs
+--- rustc-1.56.0-src/vendor/git2/src/note.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/note.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -53,7 +53,7 @@
+     type Raw = *mut raw::git_note;
+     unsafe fn from_raw(raw: *mut raw::git_note) -> Note<'repo> {
+         Note {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -80,7 +80,7 @@
+     type Raw = *mut raw::git_note_iterator;
+     unsafe fn from_raw(raw: *mut raw::git_note_iterator) -> Notes<'repo> {
+         Notes {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/object.rs rustc-1.56.0-src-git2/vendor/git2/src/object.rs
+--- rustc-1.56.0-src/vendor/git2/src/object.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/object.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -232,7 +232,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_object) -> Object<'repo> {
+         Object {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/odb.rs rustc-1.56.0-src-git2/vendor/git2/src/odb.rs
+--- rustc-1.56.0-src/vendor/git2/src/odb.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/odb.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -23,7 +23,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_odb) -> Odb<'repo> {
+         Odb {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -273,7 +273,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_odb_object) -> OdbObject<'a> {
+         OdbObject {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -327,7 +327,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_odb_stream) -> OdbReader<'repo> {
+         OdbReader {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -386,7 +386,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_odb_stream) -> OdbWriter<'repo> {
+         OdbWriter {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/oid_array.rs rustc-1.56.0-src-git2/vendor/git2/src/oid_array.rs
+--- rustc-1.56.0-src/vendor/git2/src/oid_array.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/oid_array.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -32,7 +32,7 @@
+ impl Binding for OidArray {
+     type Raw = raw::git_oidarray;
+     unsafe fn from_raw(raw: raw::git_oidarray) -> OidArray {
+-        OidArray { raw: raw }
++        OidArray { raw }
+     }
+     fn raw(&self) -> raw::git_oidarray {
+         self.raw
+diff -urN rustc-1.56.0-src/vendor/git2/src/oid.rs rustc-1.56.0-src-git2/vendor/git2/src/oid.rs
+--- rustc-1.56.0-src/vendor/git2/src/oid.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/oid.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -35,7 +35,7 @@
+                 s.len() as libc::size_t
+             ));
+         }
+-        Ok(Oid { raw: raw })
++        Ok(Oid { raw })
+     }
+ 
+     /// Parse a raw object id into an Oid structure.
+@@ -52,7 +52,7 @@
+             unsafe {
+                 try_call!(raw::git_oid_fromraw(&mut raw, bytes.as_ptr()));
+             }
+-            Ok(Oid { raw: raw })
++            Ok(Oid { raw })
+         }
+     }
+ 
+diff -urN rustc-1.56.0-src/vendor/git2/src/opts.rs rustc-1.56.0-src-git2/vendor/git2/src/opts.rs
+--- rustc-1.56.0-src/vendor/git2/src/opts.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/opts.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -3,7 +3,7 @@
+ use std::ffi::CString;
+ 
+ use crate::util::Binding;
+-use crate::{call, raw, Buf, ConfigLevel, Error, IntoCString};
++use crate::{raw, Buf, ConfigLevel, Error, IntoCString};
+ 
+ /// Set the search path for a level of config data. The search path applied to
+ /// shared attributes and ignore files, too.
+@@ -23,11 +23,11 @@
+     P: IntoCString,
+ {
+     crate::init();
+-    call::c_try(raw::git_libgit2_opts(
++    try_call!(raw::git_libgit2_opts(
+         raw::GIT_OPT_SET_SEARCH_PATH as libc::c_int,
+         level as libc::c_int,
+-        path.into_c_string()?.as_ptr(),
+-    ))?;
++        path.into_c_string()?.as_ptr()
++    ));
+     Ok(())
+ }
+ 
+@@ -42,11 +42,11 @@
+ /// the global state.
+ pub unsafe fn reset_search_path(level: ConfigLevel) -> Result<(), Error> {
+     crate::init();
+-    call::c_try(raw::git_libgit2_opts(
++    try_call!(raw::git_libgit2_opts(
+         raw::GIT_OPT_SET_SEARCH_PATH as libc::c_int,
+         level as libc::c_int,
+-        core::ptr::null::<u8>(),
+-    ))?;
++        core::ptr::null::<u8>()
++    ));
+     Ok(())
+ }
+ 
+@@ -61,11 +61,11 @@
+ pub unsafe fn get_search_path(level: ConfigLevel) -> Result<CString, Error> {
+     crate::init();
+     let buf = Buf::new();
+-    call::c_try(raw::git_libgit2_opts(
++    try_call!(raw::git_libgit2_opts(
+         raw::GIT_OPT_GET_SEARCH_PATH as libc::c_int,
+         level as libc::c_int,
+-        buf.raw(),
+-    ))?;
++        buf.raw() as *const _
++    ));
+     buf.into_c_string()
+ }
+ 
+diff -urN rustc-1.56.0-src/vendor/git2/src/packbuilder.rs rustc-1.56.0-src-git2/vendor/git2/src/packbuilder.rs
+--- rustc-1.56.0-src/vendor/git2/src/packbuilder.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/packbuilder.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -21,7 +21,7 @@
+ /// A builder for creating a packfile
+ pub struct PackBuilder<'repo> {
+     raw: *mut raw::git_packbuilder,
+-    progress: Option<Box<Box<ProgressCb<'repo>>>>,
++    _progress: Option<Box<Box<ProgressCb<'repo>>>>,
+     _marker: marker::PhantomData<&'repo Repository>,
+ }
+ 
+@@ -122,7 +122,7 @@
+                 ptr as *mut _
+             ));
+         }
+-        self.progress = Some(progress);
++        self._progress = Some(progress);
+         Ok(())
+     }
+ 
+@@ -135,7 +135,7 @@
+                 None,
+                 ptr::null_mut()
+             ));
+-            self.progress = None;
++            self._progress = None;
+         }
+         Ok(())
+     }
+@@ -174,7 +174,7 @@
+     unsafe fn from_raw(ptr: *mut raw::git_packbuilder) -> PackBuilder<'repo> {
+         PackBuilder {
+             raw: ptr,
+-            progress: None,
++            _progress: None,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/panic.rs rustc-1.56.0-src-git2/vendor/git2/src/panic.rs
+--- rustc-1.56.0-src/vendor/git2/src/panic.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/panic.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -24,7 +24,7 @@
+ pub fn check() {
+     let err = LAST_ERROR.with(|slot| slot.borrow_mut().take());
+     if let Some(err) = err {
+-        panic!(err)
++        std::panic::resume_unwind(err);
+     }
+ }
+ 
+diff -urN rustc-1.56.0-src/vendor/git2/src/patch.rs rustc-1.56.0-src-git2/vendor/git2/src/patch.rs
+--- rustc-1.56.0-src/vendor/git2/src/patch.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/patch.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -21,7 +21,7 @@
+     type Raw = *mut raw::git_patch;
+     unsafe fn from_raw(raw: Self::Raw) -> Self {
+         Patch {
+-            raw: raw,
++            raw,
+             buffers: PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/pathspec.rs rustc-1.56.0-src-git2/vendor/git2/src/pathspec.rs
+--- rustc-1.56.0-src/vendor/git2/src/pathspec.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/pathspec.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -168,7 +168,7 @@
+     type Raw = *mut raw::git_pathspec;
+ 
+     unsafe fn from_raw(raw: *mut raw::git_pathspec) -> Pathspec {
+-        Pathspec { raw: raw }
++        Pathspec { raw }
+     }
+     fn raw(&self) -> *mut raw::git_pathspec {
+         self.raw
+@@ -268,7 +268,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_pathspec_match_list) -> PathspecMatchList<'ps> {
+         PathspecMatchList {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/rebase.rs rustc-1.56.0-src-git2/vendor/git2/src/rebase.rs
+--- rustc-1.56.0-src/vendor/git2/src/rebase.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/rebase.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -230,7 +230,7 @@
+     type Raw = *mut raw::git_rebase;
+     unsafe fn from_raw(raw: *mut raw::git_rebase) -> Rebase<'repo> {
+         Rebase {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -324,7 +324,7 @@
+     type Raw = *const raw::git_rebase_operation;
+     unsafe fn from_raw(raw: *const raw::git_rebase_operation) -> RebaseOperation<'rebase> {
+         RebaseOperation {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/reference.rs rustc-1.56.0-src-git2/vendor/git2/src/reference.rs
+--- rustc-1.56.0-src/vendor/git2/src/reference.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/reference.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -387,7 +387,7 @@
+     type Raw = *mut raw::git_reference;
+     unsafe fn from_raw(raw: *mut raw::git_reference) -> Reference<'repo> {
+         Reference {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -419,7 +419,7 @@
+     type Raw = *mut raw::git_reference_iterator;
+     unsafe fn from_raw(raw: *mut raw::git_reference_iterator) -> References<'repo> {
+         References {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/reflog.rs rustc-1.56.0-src-git2/vendor/git2/src/reflog.rs
+--- rustc-1.56.0-src/vendor/git2/src/reflog.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/reflog.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -103,7 +103,7 @@
+     type Raw = *mut raw::git_reflog;
+ 
+     unsafe fn from_raw(raw: *mut raw::git_reflog) -> Reflog {
+-        Reflog { raw: raw }
++        Reflog { raw }
+     }
+     fn raw(&self) -> *mut raw::git_reflog {
+         self.raw
+@@ -151,7 +151,7 @@
+ 
+     unsafe fn from_raw(raw: *const raw::git_reflog_entry) -> ReflogEntry<'reflog> {
+         ReflogEntry {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/refspec.rs rustc-1.56.0-src-git2/vendor/git2/src/refspec.rs
+--- rustc-1.56.0-src/vendor/git2/src/refspec.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/refspec.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -112,7 +112,7 @@
+ 
+     unsafe fn from_raw(raw: *const raw::git_refspec) -> Refspec<'remote> {
+         Refspec {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/remote.rs rustc-1.56.0-src-git2/vendor/git2/src/remote.rs
+--- rustc-1.56.0-src/vendor/git2/src/remote.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/remote.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -1,11 +1,12 @@
+ use libc;
+-use std::ffi::CString;
++use raw::git_strarray;
+ use std::marker;
+ use std::mem;
+ use std::ops::Range;
+ use std::ptr;
+ use std::slice;
+ use std::str;
++use std::{ffi::CString, os::raw::c_char};
+ 
+ use crate::string_array::StringArray;
+ use crate::util::Binding;
+@@ -43,6 +44,8 @@
+     prune: FetchPrune,
+     update_fetchhead: bool,
+     download_tags: AutotagOption,
++    custom_headers: Vec<CString>,
++    custom_headers_ptrs: Vec<*const c_char>,
+ }
+ 
+ /// Options to control the behavior of a git push.
+@@ -50,6 +53,8 @@
+     callbacks: Option<RemoteCallbacks<'cb>>,
+     proxy: Option<ProxyOptions<'cb>>,
+     pb_parallelism: u32,
++    custom_headers: Vec<CString>,
++    custom_headers_ptrs: Vec<*const c_char>,
+ }
+ 
+ /// Holds callbacks for a connection to a `Remote`. Disconnects when dropped
+@@ -62,7 +67,7 @@
+ pub fn remote_into_raw(remote: Remote<'_>) -> *mut raw::git_remote {
+     let ret = remote.raw;
+     mem::forget(remote);
+-    return ret;
++    ret
+ }
+ 
+ impl<'repo> Remote<'repo> {
+@@ -221,6 +226,17 @@
+         Ok(())
+     }
+ 
++    /// Cancel the operation
++    ///
++    /// At certain points in its operation, the network code checks whether the
++    /// operation has been cancelled and if so stops the operation.
++    pub fn stop(&mut self) -> Result<(), Error> {
++        unsafe {
++            try_call!(raw::git_remote_stop(self.raw));
++        }
++        Ok(())
++    }
++
+     /// Get the number of refspecs for a remote
+     pub fn refspecs(&self) -> Refspecs<'_> {
+         let cnt = unsafe { raw::git_remote_refspec_count(&*self.raw) as usize };
+@@ -345,6 +361,15 @@
+         }
+     }
+ 
++    /// Prune tracking refs that are no longer present on remote
++    pub fn prune(&mut self, callbacks: Option<RemoteCallbacks<'_>>) -> Result<(), Error> {
++        let cbs = Box::new(callbacks.unwrap_or_else(RemoteCallbacks::new));
++        unsafe {
++            try_call!(raw::git_remote_prune(self.raw, &cbs.raw()));
++        }
++        Ok(())
++    }
++
+     /// Get the remote's list of fetch refspecs
+     pub fn fetch_refspecs(&self) -> Result<StringArray, Error> {
+         unsafe {
+@@ -381,7 +406,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_remote) -> Remote<'repo> {
+         Remote {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -454,6 +479,8 @@
+             prune: FetchPrune::Unspecified,
+             update_fetchhead: true,
+             download_tags: AutotagOption::Unspecified,
++            custom_headers: Vec::new(),
++            custom_headers_ptrs: Vec::new(),
+         }
+     }
+ 
+@@ -491,6 +518,16 @@
+         self.download_tags = opt;
+         self
+     }
++
++    /// Set extra headers for this fetch operation.
++    pub fn custom_headers(&mut self, custom_headers: &[&str]) -> &mut Self {
++        self.custom_headers = custom_headers
++            .iter()
++            .map(|&s| CString::new(s).unwrap())
++            .collect();
++        self.custom_headers_ptrs = self.custom_headers.iter().map(|s| s.as_ptr()).collect();
++        self
++    }
+ }
+ 
+ impl<'cb> Binding for FetchOptions<'cb> {
+@@ -515,10 +552,9 @@
+             prune: crate::call::convert(&self.prune),
+             update_fetchhead: crate::call::convert(&self.update_fetchhead),
+             download_tags: crate::call::convert(&self.download_tags),
+-            // TODO: expose this as a builder option
+-            custom_headers: raw::git_strarray {
+-                count: 0,
+-                strings: ptr::null_mut(),
++            custom_headers: git_strarray {
++                count: self.custom_headers_ptrs.len(),
++                strings: self.custom_headers_ptrs.as_ptr() as *mut _,
+             },
+         }
+     }
+@@ -537,6 +573,8 @@
+             callbacks: None,
+             proxy: None,
+             pb_parallelism: 1,
++            custom_headers: Vec::new(),
++            custom_headers_ptrs: Vec::new(),
+         }
+     }
+ 
+@@ -562,6 +600,16 @@
+         self.pb_parallelism = parallel;
+         self
+     }
++
++    /// Set extra headers for this push operation.
++    pub fn custom_headers(&mut self, custom_headers: &[&str]) -> &mut Self {
++        self.custom_headers = custom_headers
++            .iter()
++            .map(|&s| CString::new(s).unwrap())
++            .collect();
++        self.custom_headers_ptrs = self.custom_headers.iter().map(|s| s.as_ptr()).collect();
++        self
++    }
+ }
+ 
+ impl<'cb> Binding for PushOptions<'cb> {
+@@ -584,10 +632,9 @@
+                 .map(|m| m.raw())
+                 .unwrap_or_else(|| ProxyOptions::new().raw()),
+             pb_parallelism: self.pb_parallelism as libc::c_uint,
+-            // TODO: expose this as a builder option
+-            custom_headers: raw::git_strarray {
+-                count: 0,
+-                strings: ptr::null_mut(),
++            custom_headers: git_strarray {
++                count: self.custom_headers_ptrs.len(),
++                strings: self.custom_headers_ptrs.as_ptr() as *mut _,
+             },
+         }
+     }
+@@ -614,6 +661,11 @@
+     pub fn default_branch(&self) -> Result<Buf, Error> {
+         self.remote.default_branch()
+     }
++
++    /// access remote bound to this connection
++    pub fn remote(&mut self) -> &mut Remote<'repo> {
++        self.remote
++    }
+ }
+ 
+ impl<'repo, 'connection, 'cb> Drop for RemoteConnection<'repo, 'connection, 'cb> {
+@@ -636,7 +688,7 @@
+         drop(repo);
+ 
+         let repo = t!(Repository::init(td.path()));
+-        let origin = t!(repo.find_remote("origin"));
++        let mut origin = t!(repo.find_remote("origin"));
+         assert_eq!(origin.name(), Some("origin"));
+         assert_eq!(origin.url(), Some("/path/to/nowhere"));
+         assert_eq!(origin.pushurl(), None);
+@@ -646,6 +698,8 @@
+ 
+         let stats = origin.stats();
+         assert_eq!(stats.total_objects(), 0);
++
++        t!(origin.stop());
+     }
+ 
+     #[test]
+@@ -847,4 +901,46 @@
+         let commit = repo.find_commit(commit).unwrap();
+         assert_eq!(commit.message(), Some("initial"));
+     }
++
++    #[test]
++    fn prune() {
++        let (td, remote_repo) = crate::test::repo_init();
++        let oid = remote_repo.head().unwrap().target().unwrap();
++        let commit = remote_repo.find_commit(oid).unwrap();
++        remote_repo.branch("stale", &commit, true).unwrap();
++
++        let td2 = TempDir::new().unwrap();
++        let url = crate::test::path2url(&td.path());
++        let repo = Repository::clone(&url, &td2).unwrap();
++
++        fn assert_branch_count(repo: &Repository, count: usize) {
++            assert_eq!(
++                repo.branches(Some(crate::BranchType::Remote))
++                    .unwrap()
++                    .filter(|b| b.as_ref().unwrap().0.name().unwrap() == Some("origin/stale"))
++                    .count(),
++                count,
++            );
++        }
++
++        assert_branch_count(&repo, 1);
++
++        // delete `stale` branch on remote repo
++        let mut stale_branch = remote_repo
++            .find_branch("stale", crate::BranchType::Local)
++            .unwrap();
++        stale_branch.delete().unwrap();
++
++        // prune
++        let mut remote = repo.find_remote("origin").unwrap();
++        remote.connect(Direction::Push).unwrap();
++        let mut callbacks = RemoteCallbacks::new();
++        callbacks.update_tips(|refname, _a, b| {
++            assert_eq!(refname, "refs/remotes/origin/stale");
++            assert!(b.is_zero());
++            true
++        });
++        remote.prune(Some(callbacks)).unwrap();
++        assert_branch_count(&repo, 0);
++    }
+ }
+diff -urN rustc-1.56.0-src/vendor/git2/src/repo.rs rustc-1.56.0-src-git2/vendor/git2/src/repo.rs
+--- rustc-1.56.0-src/vendor/git2/src/repo.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/repo.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -19,19 +19,82 @@
+ use crate::worktree::{Worktree, WorktreeAddOptions};
+ use crate::CherrypickOptions;
+ use crate::RevertOptions;
++use crate::{mailmap::Mailmap, panic};
+ use crate::{
+     raw, AttrCheckFlags, Buf, Error, Object, Remote, RepositoryOpenFlags, RepositoryState, Revspec,
+     StashFlags,
+ };
+ use crate::{
+-    AnnotatedCommit, MergeAnalysis, MergeOptions, MergePreference, SubmoduleIgnore, SubmoduleStatus,
++    AnnotatedCommit, MergeAnalysis, MergeOptions, MergePreference, SubmoduleIgnore,
++    SubmoduleStatus, SubmoduleUpdate,
+ };
+ use crate::{ApplyLocation, ApplyOptions, Rebase, RebaseOptions};
+ use crate::{Blame, BlameOptions, Reference, References, ResetType, Signature, Submodule};
+ use crate::{Blob, BlobWriter, Branch, BranchType, Branches, Commit, Config, Index, Oid, Tree};
+ use crate::{Describe, IntoCString, Reflog, RepositoryInitMode, RevparseMode};
+ use crate::{DescribeOptions, Diff, DiffOptions, Odb, PackBuilder, TreeBuilder};
+-use crate::{Note, Notes, ObjectType, Revwalk, Status, StatusOptions, Statuses, Tag};
++use crate::{Note, Notes, ObjectType, Revwalk, Status, StatusOptions, Statuses, Tag, Transaction};
++
++type MergeheadForeachCb<'a> = dyn FnMut(&Oid) -> bool + 'a;
++type FetchheadForeachCb<'a> = dyn FnMut(&str, &[u8], &Oid, bool) -> bool + 'a;
++
++struct FetchheadForeachCbData<'a> {
++    callback: &'a mut FetchheadForeachCb<'a>,
++}
++
++struct MergeheadForeachCbData<'a> {
++    callback: &'a mut MergeheadForeachCb<'a>,
++}
++
++extern "C" fn mergehead_foreach_cb(oid: *const raw::git_oid, payload: *mut c_void) -> c_int {
++    panic::wrap(|| unsafe {
++        let data = &mut *(payload as *mut MergeheadForeachCbData<'_>);
++        let res = {
++            let callback = &mut data.callback;
++            callback(&Binding::from_raw(oid))
++        };
++
++        if res {
++            0
++        } else {
++            1
++        }
++    })
++    .unwrap_or(1)
++}
++
++extern "C" fn fetchhead_foreach_cb(
++    ref_name: *const c_char,
++    remote_url: *const c_char,
++    oid: *const raw::git_oid,
++    is_merge: c_uint,
++    payload: *mut c_void,
++) -> c_int {
++    panic::wrap(|| unsafe {
++        let data = &mut *(payload as *mut FetchheadForeachCbData<'_>);
++        let res = {
++            let callback = &mut data.callback;
++
++            assert!(!ref_name.is_null());
++            assert!(!remote_url.is_null());
++            assert!(!oid.is_null());
++
++            let ref_name = str::from_utf8(CStr::from_ptr(ref_name).to_bytes()).unwrap();
++            let remote_url = CStr::from_ptr(remote_url).to_bytes();
++            let oid = Binding::from_raw(oid);
++            let is_merge = is_merge == 1;
++
++            callback(&ref_name, remote_url, &oid, is_merge)
++        };
++
++        if res {
++            0
++        } else {
++            1
++        }
++    })
++    .unwrap_or(1)
++}
+ 
+ /// An owned git repository, representing all state associated with the
+ /// underlying filesystem.
+@@ -952,6 +1015,14 @@
+     }
+ 
+     /// Get the value of a git attribute for a path as a string.
++    ///
++    /// This function will return a special string if the attribute is set to a special value.
++    /// Interpreting the special string is discouraged. You should always use
++    /// [`AttrValue::from_string`](crate::AttrValue::from_string) to interpret the return value
++    /// and avoid the special string.
++    ///
++    /// As such, the return type of this function will probably be changed in the next major version
++    /// to prevent interpreting the returned string without checking whether it's special.
+     pub fn get_attr(
+         &self,
+         path: &Path,
+@@ -964,6 +1035,14 @@
+     }
+ 
+     /// Get the value of a git attribute for a path as a byte slice.
++    ///
++    /// This function will return a special byte slice if the attribute is set to a special value.
++    /// Interpreting the special byte slice is discouraged. You should always use
++    /// [`AttrValue::from_bytes`](crate::AttrValue::from_bytes) to interpret the return value and
++    /// avoid the special string.
++    ///
++    /// As such, the return type of this function will probably be changed in the next major version
++    /// to prevent interpreting the returned byte slice without checking whether it's special.
+     pub fn get_attr_bytes(
+         &self,
+         path: &Path,
+@@ -1619,6 +1698,62 @@
+         Ok(SubmoduleStatus::from_bits_truncate(ret as u32))
+     }
+ 
++    /// Set the ignore rule for the submodule in the configuration
++    ///
++    /// This does not affect any currently-loaded instances.
++    pub fn submodule_set_ignore(
++        &mut self,
++        name: &str,
++        ignore: SubmoduleIgnore,
++    ) -> Result<(), Error> {
++        let name = CString::new(name)?;
++        unsafe {
++            try_call!(raw::git_submodule_set_ignore(self.raw(), name, ignore));
++        }
++        Ok(())
++    }
++
++    /// Set the update rule for the submodule in the configuration
++    ///
++    /// This setting won't affect any existing instances.
++    pub fn submodule_set_update(
++        &mut self,
++        name: &str,
++        update: SubmoduleUpdate,
++    ) -> Result<(), Error> {
++        let name = CString::new(name)?;
++        unsafe {
++            try_call!(raw::git_submodule_set_update(self.raw(), name, update));
++        }
++        Ok(())
++    }
++
++    /// Set the URL for the submodule in the configuration
++    ///
++    /// After calling this, you may wish to call [`Submodule::sync`] to write
++    /// the changes to the checked out submodule repository.
++    pub fn submodule_set_url(&mut self, name: &str, url: &str) -> Result<(), Error> {
++        let name = CString::new(name)?;
++        let url = CString::new(url)?;
++        unsafe {
++            try_call!(raw::git_submodule_set_url(self.raw(), name, url));
++        }
++        Ok(())
++    }
++
++    /// Set the branch for the submodule in the configuration
++    ///
++    /// After calling this, you may wish to call [`Submodule::sync`] to write
++    /// the changes to the checked out submodule repository.
++    pub fn submodule_set_branch(&mut self, name: &str, branch_name: &str) -> Result<(), Error> {
++        let name = CString::new(name)?;
++        let branch_name = CString::new(branch_name)?;
++        unsafe {
++            try_call!(raw::git_submodule_set_branch(self.raw(), name, branch_name));
++        }
++        Ok(())
++    }
++
+     /// Lookup a reference to one of the objects in a repository.
+     pub fn find_tree(&self, oid: Oid) -> Result<Tree<'_>, Error> {
+         let mut raw = ptr::null_mut();
+@@ -2708,7 +2843,7 @@
+         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_cherrypick(self.raw(), commit.raw(), ptr_raw_opts));
+@@ -2794,6 +2929,26 @@
+         }
+     }
+ 
++    /// Apply a Diff to the provided tree, and return the resulting Index.
++    pub fn apply_to_tree(
++        &self,
++        tree: &Tree<'_>,
++        diff: &Diff<'_>,
++        options: Option<&mut ApplyOptions<'_>>,
++    ) -> Result<Index, Error> {
++        let mut ret = ptr::null_mut();
++        unsafe {
++            try_call!(raw::git_apply_to_tree(
++                &mut ret,
++                self.raw,
++                tree.raw(),
++                diff.raw(),
++                options.map(|s| s.raw()).unwrap_or(ptr::null())
++            ));
++            Ok(Binding::from_raw(ret))
++        }
++    }
++
+     /// Reverts the given commit, producing changes in the index and working directory.
+     pub fn revert(
+         &self,
+@@ -2880,6 +3035,70 @@
+             Ok(Binding::from_raw(raw))
+         }
+     }
++
++    /// Create a new transaction
++    pub fn transaction<'a>(&'a self) -> Result<Transaction<'a>, Error> {
++        let mut raw = ptr::null_mut();
++        unsafe {
++            try_call!(raw::git_transaction_new(&mut raw, self.raw));
++            Ok(Binding::from_raw(raw))
++        }
++    }
++
++    /// Gets this repository's mailmap.
++    pub fn mailmap(&self) -> Result<Mailmap, Error> {
++        let mut ret = ptr::null_mut();
++        unsafe {
++            try_call!(raw::git_mailmap_from_repository(&mut ret, self.raw));
++            Ok(Binding::from_raw(ret))
++        }
++    }
++
++    ///  If a merge is in progress, invoke 'callback' for each commit ID in the
++    ///  MERGE_HEAD file.
++    pub fn mergehead_foreach<C>(&mut self, mut callback: C) -> Result<(), Error>
++    where
++        C: FnMut(&Oid) -> bool,
++    {
++        unsafe {
++            let mut data = MergeheadForeachCbData {
++                callback: &mut callback,
++            };
++            let cb: raw::git_repository_mergehead_foreach_cb = Some(mergehead_foreach_cb);
++            try_call!(raw::git_repository_mergehead_foreach(
++                self.raw(),
++                cb,
++                &mut data as *mut _ as *mut _
++            ));
++            Ok(())
++        }
++    }
++
++    /// Invoke 'callback' for each entry in the given FETCH_HEAD file.
++    ///
++    /// `callback` will be called with with following arguments:
++    ///
++    /// - `&str`: the reference name
++    /// - `&[u8]`: the remote url
++    /// - `&Oid`: the reference target OID
++    /// - `bool`: was the reference the result of a merge
++    pub fn fetchhead_foreach<C>(&self, mut callback: C) -> Result<(), Error>
++    where
++        C: FnMut(&str, &[u8], &Oid, bool) -> bool,
++    {
++        unsafe {
++            let mut data = FetchheadForeachCbData {
++                callback: &mut callback,
++            };
++            let cb: raw::git_repository_fetchhead_foreach_cb = Some(fetchhead_foreach_cb);
++            try_call!(raw::git_repository_fetchhead_foreach(
++                self.raw(),
++                cb,
++                &mut data as *mut _ as *mut _
++            ));
++            Ok(())
++        }
++    }
+ }
+ 
+ impl Binding for Repository {
+@@ -3062,7 +3281,9 @@
+ mod tests {
+     use crate::build::CheckoutBuilder;
+     use crate::CherrypickOptions;
+-    use crate::{ObjectType, Oid, Repository, ResetType};
++    use crate::{
++        ObjectType, Oid, Repository, ResetType, Signature, SubmoduleIgnore, SubmoduleUpdate,
++    };
+     use std::ffi::OsStr;
+     use std::fs;
+     use std::path::Path;
+@@ -3705,4 +3926,143 @@
+ 
+         Ok(())
+     }
++
++    #[test]
++    fn smoke_submodule_set() -> Result<(), crate::Error> {
++        let (td1, _repo) = crate::test::repo_init();
++        let (td2, mut repo2) = crate::test::repo_init();
++        let url = crate::test::path2url(td1.path());
++        let name = "bar";
++        {
++            let mut s = repo2.submodule(&url, Path::new(name), true)?;
++            fs::remove_dir_all(td2.path().join("bar")).unwrap();
++            Repository::clone(&url, td2.path().join("bar"))?;
++            s.add_to_index(false)?;
++            s.add_finalize()?;
++        }
++
++        // update strategy
++        repo2.submodule_set_update(name, SubmoduleUpdate::None)?;
++        assert!(matches!(
++            repo2.find_submodule(name)?.update_strategy(),
++            SubmoduleUpdate::None
++        ));
++        repo2.submodule_set_update(name, SubmoduleUpdate::Rebase)?;
++        assert!(matches!(
++            repo2.find_submodule(name)?.update_strategy(),
++            SubmoduleUpdate::Rebase
++        ));
++
++        // ignore rule
++        repo2.submodule_set_ignore(name, SubmoduleIgnore::Untracked)?;
++        assert!(matches!(
++            repo2.find_submodule(name)?.ignore_rule(),
++            SubmoduleIgnore::Untracked
++        ));
++        repo2.submodule_set_ignore(name, SubmoduleIgnore::Dirty)?;
++        assert!(matches!(
++            repo2.find_submodule(name)?.ignore_rule(),
++            SubmoduleIgnore::Dirty
++        ));
++
++        // url
++        repo2.submodule_set_url(name, "fake-url")?;
++        assert_eq!(repo2.find_submodule(name)?.url(), Some("fake-url"));
++
++        // branch
++        repo2.submodule_set_branch(name, "fake-branch")?;
++        assert_eq!(repo2.find_submodule(name)?.branch(), Some("fake-branch"));
++
++        Ok(())
++    }
++
++    #[test]
++    fn smoke_mailmap_from_repository() {
++        let (_td, repo) = crate::test::repo_init();
++
++        let commit = {
++            let head = t!(repo.head()).target().unwrap();
++            t!(repo.find_commit(head))
++        };
++
++        // This is our baseline for HEAD.
++        let author = commit.author();
++        let committer = commit.committer();
++        assert_eq!(author.name(), Some("name"));
++        assert_eq!(author.email(), Some("email"));
++        assert_eq!(committer.name(), Some("name"));
++        assert_eq!(committer.email(), Some("email"));
++
++        // There is no .mailmap file in the test repo so all signature identities are equal.
++        let mailmap = t!(repo.mailmap());
++        let mailmapped_author = t!(commit.author_with_mailmap(&mailmap));
++        let mailmapped_committer = t!(commit.committer_with_mailmap(&mailmap));
++        assert_eq!(mailmapped_author.name(), author.name());
++        assert_eq!(mailmapped_author.email(), author.email());
++        assert_eq!(mailmapped_committer.name(), committer.name());
++        assert_eq!(mailmapped_committer.email(), committer.email());
++
++        let commit = {
++            // - Add a .mailmap file to the repository.
++            // - Commit with a signature identity different from the author's.
++            // - Include entries for both author and committer to prove we call
++            //   the right raw functions.
++            let mailmap_file = Path::new(".mailmap");
++            let p = Path::new(repo.workdir().unwrap()).join(&mailmap_file);
++            t!(fs::write(
++                p,
++                r#"
++Author Name <author.proper at email> name <email>
++Committer Name <committer.proper at email> <committer at email>"#,
++            ));
++            let mut index = t!(repo.index());
++            t!(index.add_path(&mailmap_file));
++            let id_mailmap = t!(index.write_tree());
++            let tree_mailmap = t!(repo.find_tree(id_mailmap));
++
++            let head = t!(repo.commit(
++                Some("HEAD"),
++                &author,
++                t!(&Signature::now("committer", "committer at email")),
++                "Add mailmap",
++                &tree_mailmap,
++                &[&commit],
++            ));
++            t!(repo.find_commit(head))
++        };
++
++        // Sanity check that we're working with the right commit and that its
++        // author and committer identities differ.
++        let author = commit.author();
++        let committer = commit.committer();
++        assert_ne!(author.name(), committer.name());
++        assert_ne!(author.email(), committer.email());
++        assert_eq!(author.name(), Some("name"));
++        assert_eq!(author.email(), Some("email"));
++        assert_eq!(committer.name(), Some("committer"));
++        assert_eq!(committer.email(), Some("committer at email"));
++
++        // Fetch the newly added .mailmap from the repository.
++        let mailmap = t!(repo.mailmap());
++        let mailmapped_author = t!(commit.author_with_mailmap(&mailmap));
++        let mailmapped_committer = t!(commit.committer_with_mailmap(&mailmap));
++
++        let mm_resolve_author = t!(mailmap.resolve_signature(&author));
++        let mm_resolve_committer = t!(mailmap.resolve_signature(&committer));
++
++        // Mailmap Signature lifetime is independent of Commit lifetime.
++        drop(author);
++        drop(committer);
++        drop(commit);
++
++        // author_with_mailmap() + committer_with_mailmap() work
++        assert_eq!(mailmapped_author.name(), Some("Author Name"));
++        assert_eq!(mailmapped_author.email(), Some("author.proper at email"));
++        assert_eq!(mailmapped_committer.name(), Some("Committer Name"));
++        assert_eq!(mailmapped_committer.email(), Some("committer.proper at email"));
++
++        // resolve_signature() works
++        assert_eq!(mm_resolve_author.email(), mailmapped_author.email());
++        assert_eq!(mm_resolve_committer.email(), mailmapped_committer.email());
++    }
+ }
+diff -urN rustc-1.56.0-src/vendor/git2/src/revspec.rs rustc-1.56.0-src-git2/vendor/git2/src/revspec.rs
+--- rustc-1.56.0-src/vendor/git2/src/revspec.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/revspec.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -14,11 +14,7 @@
+         to: Option<Object<'repo>>,
+         mode: RevparseMode,
+     ) -> Revspec<'repo> {
+-        Revspec {
+-            from: from,
+-            to: to,
+-            mode: mode,
+-        }
++        Revspec { from, to, mode }
+     }
+ 
+     /// Access the `from` range of this revspec.
+diff -urN rustc-1.56.0-src/vendor/git2/src/revwalk.rs rustc-1.56.0-src-git2/vendor/git2/src/revwalk.rs
+--- rustc-1.56.0-src/vendor/git2/src/revwalk.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/revwalk.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -1,9 +1,9 @@
+-use libc::c_uint;
++use libc::{c_int, c_uint, c_void};
+ use std::ffi::CString;
+ use std::marker;
+ 
+ use crate::util::Binding;
+-use crate::{raw, Error, Oid, Repository, Sort};
++use crate::{panic, raw, Error, Oid, Repository, Sort};
+ 
+ /// A revwalk allows traversal of the commit graph defined by including one or
+ /// more leaves and excluding one or more roots.
+@@ -12,6 +12,40 @@
+     _marker: marker::PhantomData<&'repo Repository>,
+ }
+ 
++/// A `Revwalk` with an assiciated "hide callback", see `with_hide_callback`
++pub struct RevwalkWithHideCb<'repo, 'cb, C>
++where
++    C: FnMut(Oid) -> bool,
++{
++    revwalk: Revwalk<'repo>,
++    _marker: marker::PhantomData<&'cb C>,
++}
++
++extern "C" fn revwalk_hide_cb<C>(commit_id: *const raw::git_oid, payload: *mut c_void) -> c_int
++where
++    C: FnMut(Oid) -> bool,
++{
++    panic::wrap(|| unsafe {
++        let hide_cb = payload as *mut C;
++        if (*hide_cb)(Oid::from_raw(commit_id)) {
++            1
++        } else {
++            0
++        }
++    })
++    .unwrap_or(-1)
++}
++
++impl<'repo, 'cb, C: FnMut(Oid) -> bool> RevwalkWithHideCb<'repo, 'cb, C> {
++    /// Consumes the `RevwalkWithHideCb` and returns the contained `Revwalk`.
++    ///
++    /// Note that this will reset the `Revwalk`.
++    pub fn into_inner(mut self) -> Result<Revwalk<'repo>, Error> {
++        self.revwalk.reset()?;
++        Ok(self.revwalk)
++    }
++}
++
+ impl<'repo> Revwalk<'repo> {
+     /// Reset a revwalk to allow re-configuring it.
+     ///
+@@ -119,6 +153,29 @@
+         Ok(())
+     }
+ 
++    /// Hide all commits for which the callback returns true from
++    /// the walk.
++    pub fn with_hide_callback<'cb, C>(
++        self,
++        callback: &'cb C,
++    ) -> Result<RevwalkWithHideCb<'repo, 'cb, C>, Error>
++    where
++        C: FnMut(Oid) -> bool,
++    {
++        let r = RevwalkWithHideCb {
++            revwalk: self,
++            _marker: marker::PhantomData,
++        };
++        unsafe {
++            raw::git_revwalk_add_hide_cb(
++                r.revwalk.raw(),
++                Some(revwalk_hide_cb::<C>),
++                callback as *const _ as *mut c_void,
++            );
++        };
++        Ok(r)
++    }
++
+     /// Hide the repository's HEAD
+     ///
+     /// For more information, see `hide`.
+@@ -163,7 +220,7 @@
+     type Raw = *mut raw::git_revwalk;
+     unsafe fn from_raw(raw: *mut raw::git_revwalk) -> Revwalk<'repo> {
+         Revwalk {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -191,6 +248,15 @@
+     }
+ }
+ 
++impl<'repo, 'cb, C: FnMut(Oid) -> bool> Iterator for RevwalkWithHideCb<'repo, 'cb, C> {
++    type Item = Result<Oid, Error>;
++    fn next(&mut self) -> Option<Result<Oid, Error>> {
++        let out = self.revwalk.next();
++        crate::panic::check();
++        out
++    }
++}
++
+ #[cfg(test)]
+ mod tests {
+     #[test]
+@@ -216,4 +282,35 @@
+         walk.hide_head().unwrap();
+         assert_eq!(walk.by_ref().count(), 0);
+     }
++
++    #[test]
++    fn smoke_hide_cb() {
++        let (_td, repo) = crate::test::repo_init();
++        let head = repo.head().unwrap();
++        let target = head.target().unwrap();
++
++        let mut walk = repo.revwalk().unwrap();
++        walk.push(target).unwrap();
++
++        let oids: Vec<crate::Oid> = walk.by_ref().collect::<Result<Vec<_>, _>>().unwrap();
++
++        assert_eq!(oids.len(), 1);
++        assert_eq!(oids[0], target);
++
++        walk.reset().unwrap();
++        walk.push_head().unwrap();
++        assert_eq!(walk.by_ref().count(), 1);
++
++        walk.reset().unwrap();
++        walk.push_head().unwrap();
++
++        let hide_cb = |oid| oid == target;
++        let mut walk = walk.with_hide_callback(&hide_cb).unwrap();
++
++        assert_eq!(walk.by_ref().count(), 0);
++
++        let mut walk = walk.into_inner().unwrap();
++        walk.push_head().unwrap();
++        assert_eq!(walk.by_ref().count(), 1);
++    }
+ }
+diff -urN rustc-1.56.0-src/vendor/git2/src/signature.rs rustc-1.56.0-src-git2/vendor/git2/src/signature.rs
+--- rustc-1.56.0-src/vendor/git2/src/signature.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/signature.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -105,7 +105,7 @@
+     type Raw = *mut raw::git_signature;
+     unsafe fn from_raw(raw: *mut raw::git_signature) -> Signature<'a> {
+         Signature {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+             owned: true,
+         }
+diff -urN rustc-1.56.0-src/vendor/git2/src/status.rs rustc-1.56.0-src-git2/vendor/git2/src/status.rs
+--- rustc-1.56.0-src/vendor/git2/src/status.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/status.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -72,7 +72,7 @@
+             let r = raw::git_status_init_options(&mut raw, raw::GIT_STATUS_OPTIONS_VERSION);
+             assert_eq!(r, 0);
+             StatusOptions {
+-                raw: raw,
++                raw,
+                 pathspec: Vec::new(),
+                 ptrs: Vec::new(),
+             }
+@@ -264,7 +264,7 @@
+     type Raw = *mut raw::git_status_list;
+     unsafe fn from_raw(raw: *mut raw::git_status_list) -> Statuses<'repo> {
+         Statuses {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -340,7 +340,7 @@
+ 
+     unsafe fn from_raw(raw: *const raw::git_status_entry) -> StatusEntry<'statuses> {
+         StatusEntry {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/string_array.rs rustc-1.56.0-src-git2/vendor/git2/src/string_array.rs
+--- rustc-1.56.0-src/vendor/git2/src/string_array.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/string_array.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -79,7 +79,7 @@
+ impl Binding for StringArray {
+     type Raw = raw::git_strarray;
+     unsafe fn from_raw(raw: raw::git_strarray) -> StringArray {
+-        StringArray { raw: raw }
++        StringArray { raw }
+     }
+     fn raw(&self) -> raw::git_strarray {
+         self.raw
+diff -urN rustc-1.56.0-src/vendor/git2/src/submodule.rs rustc-1.56.0-src-git2/vendor/git2/src/submodule.rs
+--- rustc-1.56.0-src/vendor/git2/src/submodule.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/submodule.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -5,8 +5,8 @@
+ use std::ptr;
+ use std::str;
+ 
+-use crate::build::CheckoutBuilder;
+ use crate::util::{self, Binding};
++use crate::{build::CheckoutBuilder, SubmoduleIgnore, SubmoduleUpdate};
+ use crate::{raw, Error, FetchOptions, Oid, Repository};
+ 
+ /// A structure to represent a git [submodule][1]
+@@ -113,6 +113,16 @@
+         unsafe { Binding::from_raw_opt(raw::git_submodule_wd_id(self.raw)) }
+     }
+ 
++    /// Get the ignore rule that will be used for the submodule.
++    pub fn ignore_rule(&self) -> SubmoduleIgnore {
++        SubmoduleIgnore::from_raw(unsafe { raw::git_submodule_ignore(self.raw) })
++    }
++
++    /// Get the update rule that will be used for the submodule.
++    pub fn update_strategy(&self) -> SubmoduleUpdate {
++        SubmoduleUpdate::from_raw(unsafe { raw::git_submodule_update_strategy(self.raw) })
++    }
++
+     /// Copy submodule info into ".git/config" file.
+     ///
+     /// Just like "git submodule init", this copies information about the
+@@ -223,7 +233,7 @@
+     type Raw = *mut raw::git_submodule;
+     unsafe fn from_raw(raw: *mut raw::git_submodule) -> Submodule<'repo> {
+         Submodule {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/tag.rs rustc-1.56.0-src-git2/vendor/git2/src/tag.rs
+--- rustc-1.56.0-src/vendor/git2/src/tag.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/tag.rs	2021-10-23 20:47:39.255788944 +0200
+@@ -86,7 +86,7 @@
+         unsafe { Binding::from_raw(raw::git_tag_target_id(&*self.raw)) }
+     }
+ 
+-    /// Get the OID of the tagged object of a tag
++    /// Get the ObjectType of the tagged object of a tag
+     pub fn target_type(&self) -> Option<ObjectType> {
+         unsafe { ObjectType::from_raw(raw::git_tag_target_type(&*self.raw)) }
+     }
+@@ -118,7 +118,7 @@
+     type Raw = *mut raw::git_tag;
+     unsafe fn from_raw(raw: *mut raw::git_tag) -> Tag<'repo> {
+         Tag {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/time.rs rustc-1.56.0-src-git2/vendor/git2/src/time.rs
+--- rustc-1.56.0-src/vendor/git2/src/time.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/time.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -61,7 +61,7 @@
+ impl Binding for Time {
+     type Raw = raw::git_time;
+     unsafe fn from_raw(raw: raw::git_time) -> Time {
+-        Time { raw: raw }
++        Time { raw }
+     }
+     fn raw(&self) -> raw::git_time {
+         self.raw
+@@ -73,8 +73,8 @@
+     pub fn new(seconds: i32, nanoseconds: u32) -> IndexTime {
+         unsafe {
+             Binding::from_raw(raw::git_index_time {
+-                seconds: seconds,
+-                nanoseconds: nanoseconds,
++                seconds,
++                nanoseconds,
+             })
+         }
+     }
+@@ -92,7 +92,7 @@
+ impl Binding for IndexTime {
+     type Raw = raw::git_index_time;
+     unsafe fn from_raw(raw: raw::git_index_time) -> IndexTime {
+-        IndexTime { raw: raw }
++        IndexTime { raw }
+     }
+     fn raw(&self) -> raw::git_index_time {
+         self.raw
+diff -urN rustc-1.56.0-src/vendor/git2/src/tracing.rs rustc-1.56.0-src-git2/vendor/git2/src/tracing.rs
+--- rustc-1.56.0-src/vendor/git2/src/tracing.rs	1970-01-01 01:00:00.000000000 +0100
++++ rustc-1.56.0-src-git2/vendor/git2/src/tracing.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -0,0 +1,82 @@
++use std::sync::atomic::{AtomicUsize, Ordering};
++
++use libc::c_char;
++
++use crate::{panic, raw, util::Binding};
++
++/// Available tracing levels.  When tracing is set to a particular level,
++/// callers will be provided tracing at the given level and all lower levels.
++#[derive(Copy, Clone, Debug)]
++pub enum TraceLevel {
++    /// No tracing will be performed.
++    None,
++
++    /// Severe errors that may impact the program's execution
++    Fatal,
++
++    /// Errors that do not impact the program's execution
++    Error,
++
++    /// Warnings that suggest abnormal data
++    Warn,
++
++    /// Informational messages about program execution
++    Info,
++
++    /// Detailed data that allows for debugging
++    Debug,
++
++    /// Exceptionally detailed debugging data
++    Trace,
++}
++
++impl Binding for TraceLevel {
++    type Raw = raw::git_trace_level_t;
++    unsafe fn from_raw(raw: raw::git_trace_level_t) -> Self {
++        match raw {
++            raw::GIT_TRACE_NONE => Self::None,
++            raw::GIT_TRACE_FATAL => Self::Fatal,
++            raw::GIT_TRACE_ERROR => Self::Error,
++            raw::GIT_TRACE_WARN => Self::Warn,
++            raw::GIT_TRACE_INFO => Self::Info,
++            raw::GIT_TRACE_DEBUG => Self::Debug,
++            raw::GIT_TRACE_TRACE => Self::Trace,
++            _ => panic!("Unknown git trace level"),
++        }
++    }
++    fn raw(&self) -> raw::git_trace_level_t {
++        match *self {
++            Self::None => raw::GIT_TRACE_NONE,
++            Self::Fatal => raw::GIT_TRACE_FATAL,
++            Self::Error => raw::GIT_TRACE_ERROR,
++            Self::Warn => raw::GIT_TRACE_WARN,
++            Self::Info => raw::GIT_TRACE_INFO,
++            Self::Debug => raw::GIT_TRACE_DEBUG,
++            Self::Trace => raw::GIT_TRACE_TRACE,
++        }
++    }
++}
++
++pub type TracingCb = fn(TraceLevel, &str);
++
++static CALLBACK: AtomicUsize = AtomicUsize::new(0);
++
++///
++pub fn trace_set(level: TraceLevel, cb: TracingCb) -> bool {
++    CALLBACK.store(cb as usize, Ordering::SeqCst);
++
++    unsafe {
++        raw::git_trace_set(level.raw(), Some(tracing_cb_c));
++    }
++
++    return true;
++}
++
++extern "C" fn tracing_cb_c(level: raw::git_trace_level_t, msg: *const c_char) {
++    let cb = CALLBACK.load(Ordering::SeqCst);
++    panic::wrap(|| unsafe {
++        let cb: TracingCb = std::mem::transmute(cb);
++        let msg = std::ffi::CStr::from_ptr(msg).to_str().unwrap();
++        cb(Binding::from_raw(level), msg);
++    });
++}
+diff -urN rustc-1.56.0-src/vendor/git2/src/transaction.rs rustc-1.56.0-src-git2/vendor/git2/src/transaction.rs
+--- rustc-1.56.0-src/vendor/git2/src/transaction.rs	1970-01-01 01:00:00.000000000 +0100
++++ rustc-1.56.0-src-git2/vendor/git2/src/transaction.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -0,0 +1,285 @@
++use std::ffi::CString;
++use std::marker;
++
++use crate::{raw, util::Binding, Error, Oid, Reflog, Repository, Signature};
++
++/// A structure representing a transactional update of a repository's references.
++///
++/// Transactions work by locking loose refs for as long as the [`Transaction`]
++/// is held, and committing all changes to disk when [`Transaction::commit`] is
++/// called. Note that comitting is not atomic: if an operation fails, the
++/// transaction aborts, but previous successful operations are not rolled back.
++pub struct Transaction<'repo> {
++    raw: *mut raw::git_transaction,
++    _marker: marker::PhantomData<&'repo Repository>,
++}
++
++impl Drop for Transaction<'_> {
++    fn drop(&mut self) {
++        unsafe { raw::git_transaction_free(self.raw) }
++    }
++}
++
++impl<'repo> Binding for Transaction<'repo> {
++    type Raw = *mut raw::git_transaction;
++
++    unsafe fn from_raw(ptr: *mut raw::git_transaction) -> Transaction<'repo> {
++        Transaction {
++            raw: ptr,
++            _marker: marker::PhantomData,
++        }
++    }
++
++    fn raw(&self) -> *mut raw::git_transaction {
++        self.raw
++    }
++}
++
++impl<'repo> Transaction<'repo> {
++    /// Lock the specified reference by name.
++    pub fn lock_ref(&mut self, refname: &str) -> Result<(), Error> {
++        let refname = CString::new(refname).unwrap();
++        unsafe {
++            try_call!(raw::git_transaction_lock_ref(self.raw, refname));
++        }
++
++        Ok(())
++    }
++
++    /// Set the target of the specified reference.
++    ///
++    /// The reference must have been locked via `lock_ref`.
++    ///
++    /// If `reflog_signature` is `None`, the [`Signature`] is read from the
++    /// repository config.
++    pub fn set_target(
++        &mut self,
++        refname: &str,
++        target: Oid,
++        reflog_signature: Option<&Signature<'_>>,
++        reflog_message: &str,
++    ) -> Result<(), Error> {
++        let refname = CString::new(refname).unwrap();
++        let reflog_message = CString::new(reflog_message).unwrap();
++        unsafe {
++            try_call!(raw::git_transaction_set_target(
++                self.raw,
++                refname,
++                target.raw(),
++                reflog_signature.map(|s| s.raw()),
++                reflog_message
++            ));
++        }
++
++        Ok(())
++    }
++
++    /// Set the target of the specified symbolic reference.
++    ///
++    /// The reference must have been locked via `lock_ref`.
++    ///
++    /// If `reflog_signature` is `None`, the [`Signature`] is read from the
++    /// repository config.
++    pub fn set_symbolic_target(
++        &mut self,
++        refname: &str,
++        target: &str,
++        reflog_signature: Option<&Signature<'_>>,
++        reflog_message: &str,
++    ) -> Result<(), Error> {
++        let refname = CString::new(refname).unwrap();
++        let target = CString::new(target).unwrap();
++        let reflog_message = CString::new(reflog_message).unwrap();
++        unsafe {
++            try_call!(raw::git_transaction_set_symbolic_target(
++                self.raw,
++                refname,
++                target,
++                reflog_signature.map(|s| s.raw()),
++                reflog_message
++            ));
++        }
++
++        Ok(())
++    }
++
++    /// Add a [`Reflog`] to the transaction.
++    ///
++    /// This commit the in-memory [`Reflog`] to disk when the transaction commits.
++    /// Note that atomicty is **not* guaranteed: if the transaction fails to
++    /// modify `refname`, the reflog may still have been comitted to disk.
++    ///
++    /// If this is combined with setting the target, that update won't be
++    /// written to the log (ie. the `reflog_signature` and `reflog_message`
++    /// parameters will be ignored).
++    pub fn set_reflog(&mut self, refname: &str, reflog: Reflog) -> Result<(), Error> {
++        let refname = CString::new(refname).unwrap();
++        unsafe {
++            try_call!(raw::git_transaction_set_reflog(
++                self.raw,
++                refname,
++                reflog.raw()
++            ));
++        }
++
++        Ok(())
++    }
++
++    /// Remove a reference.
++    ///
++    /// The reference must have been locked via `lock_ref`.
++    pub fn remove(&mut self, refname: &str) -> Result<(), Error> {
++        let refname = CString::new(refname).unwrap();
++        unsafe {
++            try_call!(raw::git_transaction_remove(self.raw, refname));
++        }
++
++        Ok(())
++    }
++
++    /// Commit the changes from the transaction.
++    ///
++    /// The updates will be made one by one, and the first failure will stop the
++    /// processing.
++    pub fn commit(self) -> Result<(), Error> {
++        unsafe {
++            try_call!(raw::git_transaction_commit(self.raw));
++        }
++        Ok(())
++    }
++}
++
++#[cfg(test)]
++mod tests {
++    use crate::{Error, ErrorClass, ErrorCode, Oid, Repository};
++
++    #[test]
++    fn smoke() {
++        let (_td, repo) = crate::test::repo_init();
++
++        let mut tx = t!(repo.transaction());
++
++        t!(tx.lock_ref("refs/heads/main"));
++        t!(tx.lock_ref("refs/heads/next"));
++
++        t!(tx.set_target("refs/heads/main", Oid::zero(), None, "set main to zero"));
++        t!(tx.set_symbolic_target(
++            "refs/heads/next",
++            "refs/heads/main",
++            None,
++            "set next to main",
++        ));
++
++        t!(tx.commit());
++
++        assert_eq!(repo.refname_to_id("refs/heads/main").unwrap(), Oid::zero());
++        assert_eq!(
++            repo.find_reference("refs/heads/next")
++                .unwrap()
++                .symbolic_target()
++                .unwrap(),
++            "refs/heads/main"
++        );
++    }
++
++    #[test]
++    fn locks_same_repo_handle() {
++        let (_td, repo) = crate::test::repo_init();
++
++        let mut tx1 = t!(repo.transaction());
++        t!(tx1.lock_ref("refs/heads/seen"));
++
++        let mut tx2 = t!(repo.transaction());
++        assert!(matches!(tx2.lock_ref("refs/heads/seen"), Err(e) if e.code() == ErrorCode::Locked))
++    }
++
++    #[test]
++    fn locks_across_repo_handles() {
++        let (td, repo1) = crate::test::repo_init();
++        let repo2 = t!(Repository::open(&td));
++
++        let mut tx1 = t!(repo1.transaction());
++        t!(tx1.lock_ref("refs/heads/seen"));
++
++        let mut tx2 = t!(repo2.transaction());
++        assert!(matches!(tx2.lock_ref("refs/heads/seen"), Err(e) if e.code() == ErrorCode::Locked))
++    }
++
++    #[test]
++    fn drop_unlocks() {
++        let (_td, repo) = crate::test::repo_init();
++
++        let mut tx = t!(repo.transaction());
++        t!(tx.lock_ref("refs/heads/seen"));
++        drop(tx);
++
++        let mut tx2 = t!(repo.transaction());
++        t!(tx2.lock_ref("refs/heads/seen"))
++    }
++
++    #[test]
++    fn commit_unlocks() {
++        let (_td, repo) = crate::test::repo_init();
++
++        let mut tx = t!(repo.transaction());
++        t!(tx.lock_ref("refs/heads/seen"));
++        t!(tx.commit());
++
++        let mut tx2 = t!(repo.transaction());
++        t!(tx2.lock_ref("refs/heads/seen"));
++    }
++
++    #[test]
++    fn prevents_non_transactional_updates() {
++        let (_td, repo) = crate::test::repo_init();
++        let head = t!(repo.refname_to_id("HEAD"));
++
++        let mut tx = t!(repo.transaction());
++        t!(tx.lock_ref("refs/heads/seen"));
++
++        assert!(matches!(
++            repo.reference("refs/heads/seen", head, true, "competing with lock"),
++            Err(e) if e.code() == ErrorCode::Locked
++        ));
++    }
++
++    #[test]
++    fn remove() {
++        let (_td, repo) = crate::test::repo_init();
++        let head = t!(repo.refname_to_id("HEAD"));
++        let next = "refs/heads/next";
++
++        t!(repo.reference(
++            next,
++            head,
++            true,
++            "refs/heads/next@{0}: branch: Created from HEAD"
++        ));
++
++        {
++            let mut tx = t!(repo.transaction());
++            t!(tx.lock_ref(next));
++            t!(tx.remove(next));
++            t!(tx.commit());
++        }
++        assert!(matches!(repo.refname_to_id(next), Err(e) if e.code() == ErrorCode::NotFound))
++    }
++
++    #[test]
++    fn must_lock_ref() {
++        let (_td, repo) = crate::test::repo_init();
++
++        // 🤷
++        fn is_not_locked_err(e: &Error) -> bool {
++            e.code() == ErrorCode::NotFound
++                && e.class() == ErrorClass::Reference
++                && e.message() == "the specified reference is not locked"
++        }
++
++        let mut tx = t!(repo.transaction());
++        assert!(matches!(
++            tx.set_target("refs/heads/main", Oid::zero(), None, "set main to zero"),
++            Err(e) if is_not_locked_err(&e)
++        ))
++    }
++}
+diff -urN rustc-1.56.0-src/vendor/git2/src/transport.rs rustc-1.56.0-src-git2/vendor/git2/src/transport.rs
+--- rustc-1.56.0-src/vendor/git2/src/transport.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/transport.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -54,7 +54,7 @@
+ }
+ 
+ /// Actions that a smart transport can ask a subtransport to perform
+-#[derive(Copy, Clone)]
++#[derive(Copy, Clone, PartialEq)]
+ #[allow(missing_docs)]
+ pub enum Service {
+     UploadPackLs,
+@@ -87,6 +87,8 @@
+ #[repr(C)]
+ struct RawSmartSubtransport {
+     raw: raw::git_smart_subtransport,
++    stream: Option<*mut raw::git_smart_subtransport_stream>,
++    rpc: bool,
+     obj: Box<dyn SmartSubtransport>,
+ }
+ 
+@@ -142,6 +144,8 @@
+                 close: Some(subtransport_close),
+                 free: Some(subtransport_free),
+             },
++            stream: None,
++            rpc,
+             obj: Box::new(subtransport),
+         });
+         let mut defn = raw::git_smart_subtransport_definition {
+@@ -246,23 +250,36 @@
+             raw::GIT_SERVICE_RECEIVEPACK => Service::ReceivePack,
+             n => panic!("unknown action: {}", n),
+         };
+-        let transport = &mut *(raw_transport as *mut RawSmartSubtransport);
+-        let obj = match transport.obj.action(url, action) {
+-            Ok(s) => s,
+-            Err(e) => {
+-                set_err(&e);
+-                return e.raw_code() as c_int;
++
++        let mut transport = &mut *(raw_transport as *mut RawSmartSubtransport);
++        // Note: we only need to generate if rpc is on. Else, for receive-pack and upload-pack
++        // libgit2 reuses the stream generated for receive-pack-ls or upload-pack-ls.
++        let generate_stream =
++            transport.rpc || action == Service::UploadPackLs || action == Service::ReceivePackLs;
++        if generate_stream {
++            let obj = match transport.obj.action(url, action) {
++                Ok(s) => s,
++                Err(e) => {
++                    set_err(&e);
++                    return e.raw_code() as c_int;
++                }
++            };
++            *stream = mem::transmute(Box::new(RawSmartSubtransportStream {
++                raw: raw::git_smart_subtransport_stream {
++                    subtransport: raw_transport,
++                    read: Some(stream_read),
++                    write: Some(stream_write),
++                    free: Some(stream_free),
++                },
++                obj,
++            }));
++            transport.stream = Some(*stream);
++        } else {
++            if transport.stream.is_none() {
++                return -1;
+             }
+-        };
+-        *stream = mem::transmute(Box::new(RawSmartSubtransportStream {
+-            raw: raw::git_smart_subtransport_stream {
+-                subtransport: raw_transport,
+-                read: Some(stream_read),
+-                write: Some(stream_write),
+-                free: Some(stream_free),
+-            },
+-            obj: obj,
+-        }));
++            *stream = transport.stream.unwrap();
++        }
+         0
+     })
+     .unwrap_or(-1)
+diff -urN rustc-1.56.0-src/vendor/git2/src/treebuilder.rs rustc-1.56.0-src-git2/vendor/git2/src/treebuilder.rs
+--- rustc-1.56.0-src/vendor/git2/src/treebuilder.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/treebuilder.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -141,7 +141,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_treebuilder) -> TreeBuilder<'repo> {
+         TreeBuilder {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+diff -urN rustc-1.56.0-src/vendor/git2/src/tree.rs rustc-1.56.0-src-git2/vendor/git2/src/tree.rs
+--- rustc-1.56.0-src/vendor/git2/src/tree.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/git2/src/tree.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -225,7 +225,7 @@
+ 
+     unsafe fn from_raw(raw: *mut raw::git_tree) -> Tree<'repo> {
+         Tree {
+-            raw: raw,
++            raw,
+             _marker: marker::PhantomData,
+         }
+     }
+@@ -334,7 +334,7 @@
+     type Raw = *mut raw::git_tree_entry;
+     unsafe fn from_raw(raw: *mut raw::git_tree_entry) -> TreeEntry<'a> {
+         TreeEntry {
+-            raw: raw,
++            raw,
+             owned: true,
+             _marker: marker::PhantomData,
+         }
+diff -urN rustc-1.56.0-src/vendor/git2/src/version.rs rustc-1.56.0-src-git2/vendor/git2/src/version.rs
+--- rustc-1.56.0-src/vendor/git2/src/version.rs	1970-01-01 01:00:00.000000000 +0100
++++ rustc-1.56.0-src-git2/vendor/git2/src/version.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -0,0 +1,95 @@
++use crate::raw;
++use libc::c_int;
++use std::fmt;
++
++/// Version information about libgit2 and the capabilities it supports.
++pub struct Version {
++    major: c_int,
++    minor: c_int,
++    rev: c_int,
++    features: c_int,
++}
++
++macro_rules! flag_test {
++    ($features:expr, $flag:expr) => {
++        ($features as u32 & $flag as u32) != 0
++    };
++}
++
++impl Version {
++    /// Returns a [`Version`] which provides information about libgit2.
++    pub fn get() -> Version {
++        let mut v = Version {
++            major: 0,
++            minor: 0,
++            rev: 0,
++            features: 0,
++        };
++        unsafe {
++            raw::git_libgit2_version(&mut v.major, &mut v.minor, &mut v.rev);
++            v.features = raw::git_libgit2_features();
++        }
++        v
++    }
++
++    /// Returns the version of libgit2.
++    ///
++    /// The return value is a tuple of `(major, minor, rev)`
++    pub fn libgit2_version(&self) -> (u32, u32, u32) {
++        (self.major as u32, self.minor as u32, self.rev as u32)
++    }
++
++    /// Returns the version of the libgit2-sys crate.
++    pub fn crate_version(&self) -> &'static str {
++        env!("CARGO_PKG_VERSION")
++    }
++
++    /// Returns true if this was built with the vendored version of libgit2.
++    pub fn vendored(&self) -> bool {
++        raw::vendored()
++    }
++
++    /// Returns true if libgit2 was built thread-aware and can be safely used
++    /// from multiple threads.
++    pub fn threads(&self) -> bool {
++        flag_test!(self.features, raw::GIT_FEATURE_THREADS)
++    }
++
++    /// Returns true if libgit2 was built with and linked against a TLS implementation.
++    ///
++    /// Custom TLS streams may still be added by the user to support HTTPS
++    /// regardless of this.
++    pub fn https(&self) -> bool {
++        flag_test!(self.features, raw::GIT_FEATURE_HTTPS)
++    }
++
++    /// Returns true if libgit2 was built with and linked against libssh2.
++    ///
++    /// A custom transport may still be added by the user to support libssh2
++    /// regardless of this.
++    pub fn ssh(&self) -> bool {
++        flag_test!(self.features, raw::GIT_FEATURE_SSH)
++    }
++
++    /// Returns true if libgit2 was built with support for sub-second
++    /// resolution in file modification times.
++    pub fn nsec(&self) -> bool {
++        flag_test!(self.features, raw::GIT_FEATURE_NSEC)
++    }
++}
++
++impl fmt::Debug for Version {
++    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
++        let mut f = f.debug_struct("Version");
++        f.field("major", &self.major)
++            .field("minor", &self.minor)
++            .field("rev", &self.rev)
++            .field("crate_version", &self.crate_version())
++            .field("vendored", &self.vendored())
++            .field("threads", &self.threads())
++            .field("https", &self.https())
++            .field("ssh", &self.ssh())
++            .field("nsec", &self.nsec());
++        f.finish()
++    }
++}
+diff -urN rustc-1.56.0-src/vendor/libgit2-sys/build.rs rustc-1.56.0-src-git2/vendor/libgit2-sys/build.rs
+--- rustc-1.56.0-src/vendor/libgit2-sys/build.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/libgit2-sys/build.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -7,10 +7,12 @@
+ fn main() {
+     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();
+ 
+     // To use zlib-ng in zlib-compat mode, we have to build libgit2 ourselves.
+-    if !zlib_ng_compat {
++    let try_to_use_system_libgit2 = !vendored && !zlib_ng_compat;
++    if try_to_use_system_libgit2 {
+         let mut cfg = pkg_config::Config::new();
+         if let Ok(lib) = cfg.atleast_version("1.1.0").probe("libgit2") {
+             for include in &lib.include_paths {
+@@ -20,6 +22,8 @@
+         }
+     }
+ 
++    println!("cargo:rustc-cfg=libgit2_vendored");
++
+     if !Path::new("libgit2/.git").exists() {
+         let _ = Command::new("git")
+             .args(&["submodule", "update", "--init", "libgit2"])
+@@ -107,6 +111,7 @@
+     features.push_str("#ifndef INCLUDE_features_h\n");
+     features.push_str("#define INCLUDE_features_h\n");
+     features.push_str("#define GIT_THREADS 1\n");
++    features.push_str("#define GIT_TRACE 1\n");
+ 
+     if !target.contains("android") {
+         features.push_str("#define GIT_USE_NSEC 1\n");
+diff -urN rustc-1.56.0-src/vendor/libgit2-sys/Cargo.toml rustc-1.56.0-src-git2/vendor/libgit2-sys/Cargo.toml
+--- rustc-1.56.0-src/vendor/libgit2-sys/Cargo.toml	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/libgit2-sys/Cargo.toml	2021-10-23 20:47:39.259122276 +0200
+@@ -13,7 +13,7 @@
+ [package]
+ edition = "2018"
+ name = "libgit2-sys"
+-version = "0.12.18+1.1.0"
++version = "0.12.24+1.3.0"
+ authors = ["Josh Triplett <josh at joshtriplett.org>", "Alex Crichton <alex at alexcrichton.com>"]
+ build = "build.rs"
+ links = "git2"
+diff -urN rustc-1.56.0-src/vendor/libgit2-sys/lib.rs rustc-1.56.0-src-git2/vendor/libgit2-sys/lib.rs
+--- rustc-1.56.0-src/vendor/libgit2-sys/lib.rs	2021-10-18 13:05:54.000000000 +0200
++++ rustc-1.56.0-src-git2/vendor/libgit2-sys/lib.rs	2021-10-23 20:47:39.259122276 +0200
+@@ -89,6 +89,8 @@
+ pub enum git_odb_stream {}
+ pub enum git_odb_object {}
+ pub enum git_worktree {}
++pub enum git_transaction {}
++pub enum git_mailmap {}
+ 
+ #[repr(C)]
+ pub struct git_revspec {
+@@ -351,6 +353,8 @@
+ )]
+ pub type git_transfer_progress = git_indexer_progress;
+ 
++pub type git_remote_ready_cb = Option<extern "C" fn(*mut git_remote, c_int, *mut c_void) -> c_int>;
++
+ #[repr(C)]
+ pub struct git_remote_callbacks {
+     pub version: c_uint,
+@@ -366,6 +370,7 @@
+     pub push_update_reference: git_push_update_reference_cb,
+     pub push_negotiation: git_push_negotiation,
+     pub transport: git_transport_cb,
++    pub remote_ready: git_remote_ready_cb,
+     pub payload: *mut c_void,
+     pub resolve_url: git_url_resolve_cb,
+ }
+@@ -1167,6 +1172,7 @@
+ pub const GIT_DIFF_INCLUDE_UNREADABLE: git_diff_option_t = 1 << 16;
+ pub const GIT_DIFF_INCLUDE_UNREADABLE_AS_UNTRACKED: git_diff_option_t = 1 << 17;
+ pub const GIT_DIFF_INDENT_HEURISTIC: git_diff_option_t = 1 << 18;
++pub const GIT_DIFF_IGNORE_BLANK_LINES: git_diff_option_t = 1 << 19;
+ pub const GIT_DIFF_FORCE_TEXT: git_diff_option_t = 1 << 20;
+ pub const GIT_DIFF_FORCE_BINARY: git_diff_option_t = 1 << 21;
+ pub const GIT_DIFF_IGNORE_WHITESPACE: git_diff_option_t = 1 << 22;
+@@ -1247,6 +1253,13 @@
+ pub const GIT_DIFF_FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER: u32 = 1 << 0;
+ 
+ #[repr(C)]
++pub struct git_diff_patchid_options {
++    pub version: c_uint,
++}
++
++pub const GIT_DIFF_PATCHID_OPTIONS_VERSION: c_uint = 1;
++
++#[repr(C)]
+ pub struct git_diff_binary {
+     pub contains_data: c_uint,
+     pub old_file: git_diff_binary_file,
+@@ -1477,6 +1490,8 @@
+         ) -> c_int,
+     >,
+ 
++    pub writemidx: Option<extern "C" fn(*mut git_odb_backend) -> c_int>,
++
+     pub freshen: Option<extern "C" fn(*mut git_odb_backend, *const git_oid) -> c_int>,
+ 
+     pub free: Option<extern "C" fn(*mut git_odb_backend)>,
+@@ -1736,6 +1751,20 @@
+     ) -> c_int,
+ >;
+ 
++pub type git_commit_create_cb = Option<
++    extern "C" fn(
++        *mut git_oid,
++        *const git_signature,
++        *const git_signature,
++        *const c_char,
++        *const c_char,
++        *const git_tree,
++        usize,
++        *const git_commit,
++        *mut c_void,
++    ) -> c_int,
++>;
++
+ pub const GIT_REBASE_NO_OPERATION: usize = usize::max_value();
+ 
+ #[repr(C)]
+@@ -1746,6 +1775,7 @@
+     pub rewrite_notes_ref: *const c_char,
+     pub merge_options: git_merge_options,
+     pub checkout_options: git_checkout_options,
++    pub commit_create_cb: git_commit_create_cb,
+     pub signing_cb: git_commit_signing_cb,
+     pub payload: *mut c_void,
+ }
+@@ -1880,6 +1910,63 @@
+ 
+ pub const GIT_WORKTREE_PRUNE_OPTIONS_VERSION: c_uint = 1;
+ 
++pub type git_repository_mergehead_foreach_cb =
++    Option<extern "C" fn(oid: *const git_oid, payload: *mut c_void) -> c_int>;
++
++pub type git_repository_fetchhead_foreach_cb = Option<
++    extern "C" fn(*const c_char, *const c_char, *const git_oid, c_uint, *mut c_void) -> c_int,
++>;
++
++git_enum! {
++    pub enum git_trace_level_t {
++        /* No tracing will be performed. */
++        GIT_TRACE_NONE = 0,
++
++        /* Severe errors that may impact the program's execution */
++        GIT_TRACE_FATAL = 1,
++
++        /* Errors that do not impact the program's execution */
++        GIT_TRACE_ERROR = 2,
++
++        /* Warnings that suggest abnormal data */
++        GIT_TRACE_WARN = 3,
++
++        /* Informational messages about program execution */
++        GIT_TRACE_INFO = 4,
++
++        /* Detailed data that allows for debugging */
++        GIT_TRACE_DEBUG = 5,
++
++        /* Exceptionally detailed debugging data */
++        GIT_TRACE_TRACE = 6,
++    }
++}
++
++pub type git_trace_cb = Option<extern "C" fn(level: git_trace_level_t, msg: *const c_char)>;
++
++git_enum! {
++    pub enum git_feature_t {
++        GIT_FEATURE_THREADS = 1 << 0,
++        GIT_FEATURE_HTTPS   = 1 << 1,
++        GIT_FEATURE_SSH     = 1 << 2,
++        GIT_FEATURE_NSEC    = 1 << 3,
++    }
++}
++
++#[repr(C)]
++pub struct git_message_trailer {
++    pub key: *const c_char,
++    pub value: *const c_char,
++}
++
++#[repr(C)]
++#[derive(Copy, Clone)]
++pub struct git_message_trailer_array {
++    pub trailers: *mut git_message_trailer,
++    pub count: size_t,
++    pub _trailer_block: *mut c_char,
++}
++
+ extern "C" {
+     // threads
+     pub fn git_libgit2_init() -> c_int;
+@@ -1972,6 +2059,16 @@
+         repo: *mut git_repository,
+         recurse_submodules: c_int,
+     ) -> c_int;
++    pub fn git_repository_mergehead_foreach(
++        repo: *mut git_repository,
++        callback: git_repository_mergehead_foreach_cb,
++        payload: *mut c_void,
++    ) -> c_int;
++    pub fn git_repository_fetchhead_foreach(
++        repo: *mut git_repository,
++        callback: git_repository_fetchhead_foreach_cb,
++        payload: *mut c_void,
++    ) -> c_int;
+     pub fn git_ignore_add_rule(repo: *mut git_repository, rules: *const c_char) -> c_int;
+     pub fn git_ignore_clear_internal_rules(repo: *mut git_repository) -> c_int;
+     pub fn git_ignore_path_is_ignored(
+@@ -2409,6 +2506,7 @@
+     ) -> c_int;
+     pub fn git_submodule_free(submodule: *mut git_submodule);
+     pub fn git_submodule_head_id(submodule: *mut git_submodule) -> *const git_oid;
++    pub fn git_submodule_ignore(submodule: *mut git_submodule) -> git_submodule_ignore_t;
+     pub fn git_submodule_index_id(submodule: *mut git_submodule) -> *const git_oid;
+     pub fn git_submodule_init(submodule: *mut git_submodule, overwrite: c_int) -> c_int;
+     pub fn git_submodule_location(status: *mut c_uint, submodule: *mut git_submodule) -> c_int;
+@@ -2589,7 +2687,17 @@
+ 
+     // commit
+     pub fn git_commit_author(commit: *const git_commit) -> *const git_signature;
++    pub fn git_commit_author_with_mailmap(
++        out: *mut *mut git_signature,
++        commit: *const git_commit,
++        mailmap: *const git_mailmap,
++    ) -> c_int;
+     pub fn git_commit_committer(commit: *const git_commit) -> *const git_signature;
++    pub fn git_commit_committer_with_mailmap(
++        out: *mut *mut git_signature,
++        commit: *const git_commit,
++        mailmap: *const git_mailmap,
++    ) -> c_int;
+     pub fn git_commit_free(commit: *mut git_commit);
+     pub fn git_commit_id(commit: *const git_commit) -> *const git_oid;
+     pub fn git_commit_lookup(
+@@ -2712,6 +2820,7 @@
+         force: c_int,
+     ) -> c_int;
+     pub fn git_branch_name(out: *mut *const c_char, branch: *const git_reference) -> c_int;
++    pub fn git_branch_name_is_valid(valid: *mut c_int, name: *const c_char) -> c_int;
+     pub fn git_branch_remote_name(
+         out: *mut git_buf,
+         repo: *mut git_repository,
+@@ -3434,6 +3543,16 @@
+         version: c_uint,
+     ) -> c_int;
+ 
++    pub fn git_diff_patchid(
++        out: *mut git_oid,
++        diff: *mut git_diff,
++        opts: *mut git_diff_patchid_options,
++    ) -> c_int;
++    pub fn git_diff_patchid_options_init(
++        opts: *mut git_diff_patchid_options,
++        version: c_uint,
++    ) -> c_int;
++
+     // patch
+     pub fn git_patch_from_diff(out: *mut *mut git_patch, diff: *mut git_diff, idx: size_t)
+         -> c_int;
+@@ -3573,6 +3692,13 @@
+         comment_char: c_char,
+     ) -> c_int;
+ 
++    pub fn git_message_trailers(
++        out: *mut git_message_trailer_array,
++        message: *const c_char,
++    ) -> c_int;
++
++    pub fn git_message_trailer_array_free(trailer: *mut git_message_trailer_array);
<Skipped 82 lines>
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/rust.git/commitdiff/dfa5a2fd1435b64589b9fde46ab8f840982b71be




More information about the pld-cvs-commit mailing list