use libc::{c_char, c_int, c_uint, c_void, size_t};
use std::env;
use std::ffi::{CStr, CString, OsStr};
use std::iter::IntoIterator;
use std::mem;
use std::path::Path;
use std::ptr;
use std::str;

use crate::build::{CheckoutBuilder, RepoBuilder};
use crate::diff::{
    binary_cb_c, file_cb_c, hunk_cb_c, line_cb_c, BinaryCb, DiffCallbacks, FileCb, HunkCb, LineCb,
};
use crate::oid_array::OidArray;
use crate::stash::{stash_cb, StashApplyOptions, StashCbData};
use crate::string_array::StringArray;
use crate::tagforeach::{tag_foreach_cb, TagForeachCB, TagForeachData};
use crate::util::{self, path_to_repo_path, Binding};
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, 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, 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.
///
/// This structure corresponds to a `git_repository` in libgit2. Many other
/// types in git2-rs are derivative from this structure and are attached to its
/// lifetime.
///
/// When a repository goes out of scope it is freed in memory but not deleted
/// from the filesystem.
pub struct Repository {
    raw: *mut raw::git_repository,
}

// It is the current belief that a `Repository` can be sent among threads, or
// even shared among threads in a mutex.
unsafe impl Send for Repository {}

/// Options which can be used to configure how a repository is initialized
pub struct RepositoryInitOptions {
    flags: u32,
    mode: u32,
    workdir_path: Option<CString>,
    description: Option<CString>,
    template_path: Option<CString>,
    initial_head: Option<CString>,
    origin_url: Option<CString>,
}

impl Repository {
    /// Attempt to open an already-existing repository at `path`.
    ///
    /// The path can point to either a normal or bare repository.
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Repository, Error> {
        crate::init();
        // Normal file path OK (does not need Windows conversion).
        let path = path.as_ref().into_c_string()?;
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_open(&mut ret, path));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Attempt to open an already-existing bare repository at `path`.
    ///
    /// The path can point to only a bare repository.
    pub fn open_bare<P: AsRef<Path>>(path: P) -> Result<Repository, Error> {
        crate::init();
        // Normal file path OK (does not need Windows conversion).
        let path = path.as_ref().into_c_string()?;
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_open_bare(&mut ret, path));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Find and open an existing repository, respecting git environment
    /// variables.  This acts like `open_ext` with the
    /// `REPOSITORY_OPEN_FROM_ENV` flag, but additionally respects `$GIT_DIR`.
    /// With `$GIT_DIR` unset, this will search for a repository starting in
    /// the current directory.
    pub fn open_from_env() -> Result<Repository, Error> {
        crate::init();
        let mut ret = ptr::null_mut();
        let flags = raw::GIT_REPOSITORY_OPEN_FROM_ENV;
        unsafe {
            try_call!(raw::git_repository_open_ext(
                &mut ret,
                ptr::null(),
                flags as c_uint,
                ptr::null()
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Find and open an existing repository, with additional options.
    ///
    /// If flags contains REPOSITORY_OPEN_NO_SEARCH, the path must point
    /// directly to a repository; otherwise, this may point to a subdirectory
    /// of a repository, and `open_ext` will search up through parent
    /// directories.
    ///
    /// If flags contains REPOSITORY_OPEN_CROSS_FS, the search through parent
    /// directories will not cross a filesystem boundary (detected when the
    /// stat st_dev field changes).
    ///
    /// If flags contains REPOSITORY_OPEN_BARE, force opening the repository as
    /// bare even if it isn't, ignoring any working directory, and defer
    /// loading the repository configuration for performance.
    ///
    /// If flags contains REPOSITORY_OPEN_NO_DOTGIT, don't try appending
    /// `/.git` to `path`.
    ///
    /// If flags contains REPOSITORY_OPEN_FROM_ENV, `open_ext` will ignore
    /// other flags and `ceiling_dirs`, and respect the same environment
    /// variables git does. Note, however, that `path` overrides `$GIT_DIR`; to
    /// respect `$GIT_DIR` as well, use `open_from_env`.
    ///
    /// ceiling_dirs specifies a list of paths that the search through parent
    /// directories will stop before entering.  Use the functions in std::env
    /// to construct or manipulate such a path list.
    pub fn open_ext<P, O, I>(
        path: P,
        flags: RepositoryOpenFlags,
        ceiling_dirs: I,
    ) -> Result<Repository, Error>
    where
        P: AsRef<Path>,
        O: AsRef<OsStr>,
        I: IntoIterator<Item = O>,
    {
        crate::init();
        // Normal file path OK (does not need Windows conversion).
        let path = path.as_ref().into_c_string()?;
        let ceiling_dirs_os = env::join_paths(ceiling_dirs)?;
        let ceiling_dirs = ceiling_dirs_os.into_c_string()?;
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_open_ext(
                &mut ret,
                path,
                flags.bits() as c_uint,
                ceiling_dirs
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Attempt to open an already-existing repository from a worktree.
    pub fn open_from_worktree(worktree: &Worktree) -> Result<Repository, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_open_from_worktree(
                &mut ret,
                worktree.raw()
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Attempt to open an already-existing repository at or above `path`
    ///
    /// This starts at `path` and looks up the filesystem hierarchy
    /// until it finds a repository.
    pub fn discover<P: AsRef<Path>>(path: P) -> Result<Repository, Error> {
        // TODO: this diverges significantly from the libgit2 API
        crate::init();
        let buf = Buf::new();
        // Normal file path OK (does not need Windows conversion).
        let path = path.as_ref().into_c_string()?;
        unsafe {
            try_call!(raw::git_repository_discover(
                buf.raw(),
                path,
                1,
                ptr::null()
            ));
        }
        Repository::open(util::bytes2path(&*buf))
    }

    /// Creates a new repository in the specified folder.
    ///
    /// This by default will create any necessary directories to create the
    /// repository, and it will read any user-specified templates when creating
    /// the repository. This behavior can be configured through `init_opts`.
    pub fn init<P: AsRef<Path>>(path: P) -> Result<Repository, Error> {
        Repository::init_opts(path, &RepositoryInitOptions::new())
    }

    /// Creates a new `--bare` repository in the specified folder.
    ///
    /// The folder must exist prior to invoking this function.
    pub fn init_bare<P: AsRef<Path>>(path: P) -> Result<Repository, Error> {
        Repository::init_opts(path, RepositoryInitOptions::new().bare(true))
    }

    /// Creates a new repository in the specified folder with the given options.
    ///
    /// See `RepositoryInitOptions` struct for more information.
    pub fn init_opts<P: AsRef<Path>>(
        path: P,
        opts: &RepositoryInitOptions,
    ) -> Result<Repository, Error> {
        crate::init();
        // Normal file path OK (does not need Windows conversion).
        let path = path.as_ref().into_c_string()?;
        let mut ret = ptr::null_mut();
        unsafe {
            let mut opts = opts.raw();
            try_call!(raw::git_repository_init_ext(&mut ret, path, &mut opts));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Clone a remote repository.
    ///
    /// See the `RepoBuilder` struct for more information. This function will
    /// delegate to a fresh `RepoBuilder`
    pub fn clone<P: AsRef<Path>>(url: &str, into: P) -> Result<Repository, Error> {
        crate::init();
        RepoBuilder::new().clone(url, into.as_ref())
    }

    /// Clone a remote repository, initialize and update its submodules
    /// recursively.
    ///
    /// This is similar to `git clone --recursive`.
    pub fn clone_recurse<P: AsRef<Path>>(url: &str, into: P) -> Result<Repository, Error> {
        let repo = Repository::clone(url, into)?;
        repo.update_submodules()?;
        Ok(repo)
    }

    /// Attempt to wrap an object database as a repository.
    pub fn from_odb(odb: Odb<'_>) -> Result<Repository, Error> {
        crate::init();
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_wrap_odb(&mut ret, odb.raw()));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Update submodules recursively.
    ///
    /// Uninitialized submodules will be initialized.
    fn update_submodules(&self) -> Result<(), Error> {
        fn add_subrepos(repo: &Repository, list: &mut Vec<Repository>) -> Result<(), Error> {
            for mut subm in repo.submodules()? {
                subm.update(true, None)?;
                list.push(subm.open()?);
            }
            Ok(())
        }

        let mut repos = Vec::new();
        add_subrepos(self, &mut repos)?;
        while let Some(repo) = repos.pop() {
            add_subrepos(&repo, &mut repos)?;
        }
        Ok(())
    }

    /// Execute a rev-parse operation against the `spec` listed.
    ///
    /// The resulting revision specification is returned, or an error is
    /// returned if one occurs.
    pub fn revparse(&self, spec: &str) -> Result<Revspec<'_>, Error> {
        let mut raw = raw::git_revspec {
            from: ptr::null_mut(),
            to: ptr::null_mut(),
            flags: 0,
        };
        let spec = CString::new(spec)?;
        unsafe {
            try_call!(raw::git_revparse(&mut raw, self.raw, spec));
            let to = Binding::from_raw_opt(raw.to);
            let from = Binding::from_raw_opt(raw.from);
            let mode = RevparseMode::from_bits_truncate(raw.flags as u32);
            Ok(Revspec::from_objects(from, to, mode))
        }
    }

    /// Find a single object, as specified by a revision string.
    pub fn revparse_single(&self, spec: &str) -> Result<Object<'_>, Error> {
        let spec = CString::new(spec)?;
        let mut obj = ptr::null_mut();
        unsafe {
            try_call!(raw::git_revparse_single(&mut obj, self.raw, spec));
            assert!(!obj.is_null());
            Ok(Binding::from_raw(obj))
        }
    }

    /// Find a single object and intermediate reference by a revision string.
    ///
    /// See `man gitrevisions`, or
    /// <http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions> for
    /// information on the syntax accepted.
    ///
    /// In some cases (`@{<-n>}` or `<branchname>@{upstream}`), the expression
    /// may point to an intermediate reference. When such expressions are being
    /// passed in, this intermediate reference is returned.
    pub fn revparse_ext(&self, spec: &str) -> Result<(Object<'_>, Option<Reference<'_>>), Error> {
        let spec = CString::new(spec)?;
        let mut git_obj = ptr::null_mut();
        let mut git_ref = ptr::null_mut();
        unsafe {
            try_call!(raw::git_revparse_ext(
                &mut git_obj,
                &mut git_ref,
                self.raw,
                spec
            ));
            assert!(!git_obj.is_null());
            Ok((Binding::from_raw(git_obj), Binding::from_raw_opt(git_ref)))
        }
    }

    /// Tests whether this repository is a bare repository or not.
    pub fn is_bare(&self) -> bool {
        unsafe { raw::git_repository_is_bare(self.raw) == 1 }
    }

    /// Tests whether this repository is a shallow clone.
    pub fn is_shallow(&self) -> bool {
        unsafe { raw::git_repository_is_shallow(self.raw) == 1 }
    }

    /// Tests whether this repository is a worktree.
    pub fn is_worktree(&self) -> bool {
        unsafe { raw::git_repository_is_worktree(self.raw) == 1 }
    }

    /// Tests whether this repository is empty.
    pub fn is_empty(&self) -> Result<bool, Error> {
        let empty = unsafe { try_call!(raw::git_repository_is_empty(self.raw)) };
        Ok(empty == 1)
    }

    /// Returns the path to the `.git` folder for normal repositories or the
    /// repository itself for bare repositories.
    pub fn path(&self) -> &Path {
        unsafe {
            let ptr = raw::git_repository_path(self.raw);
            util::bytes2path(crate::opt_bytes(self, ptr).unwrap())
        }
    }

    /// Returns the current state of this repository
    pub fn state(&self) -> RepositoryState {
        let state = unsafe { raw::git_repository_state(self.raw) };
        macro_rules! check( ($($raw:ident => $real:ident),*) => (
            $(if state == raw::$raw as c_int {
                super::RepositoryState::$real
            }) else *
            else {
                panic!("unknown repository state: {}", state)
            }
        ) );

        check!(
            GIT_REPOSITORY_STATE_NONE => Clean,
            GIT_REPOSITORY_STATE_MERGE => Merge,
            GIT_REPOSITORY_STATE_REVERT => Revert,
            GIT_REPOSITORY_STATE_REVERT_SEQUENCE => RevertSequence,
            GIT_REPOSITORY_STATE_CHERRYPICK => CherryPick,
            GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE => CherryPickSequence,
            GIT_REPOSITORY_STATE_BISECT => Bisect,
            GIT_REPOSITORY_STATE_REBASE => Rebase,
            GIT_REPOSITORY_STATE_REBASE_INTERACTIVE => RebaseInteractive,
            GIT_REPOSITORY_STATE_REBASE_MERGE => RebaseMerge,
            GIT_REPOSITORY_STATE_APPLY_MAILBOX => ApplyMailbox,
            GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE => ApplyMailboxOrRebase
        )
    }

    /// Get the path of the working directory for this repository.
    ///
    /// If this repository is bare, then `None` is returned.
    pub fn workdir(&self) -> Option<&Path> {
        unsafe {
            let ptr = raw::git_repository_workdir(self.raw);
            if ptr.is_null() {
                None
            } else {
                Some(util::bytes2path(CStr::from_ptr(ptr).to_bytes()))
            }
        }
    }

    /// Set the path to the working directory for this repository.
    ///
    /// If `update_link` is true, create/update the gitlink file in the workdir
    /// and set config "core.worktree" (if workdir is not the parent of the .git
    /// directory).
    pub fn set_workdir(&self, path: &Path, update_gitlink: bool) -> Result<(), Error> {
        // Normal file path OK (does not need Windows conversion).
        let path = path.into_c_string()?;
        unsafe {
            try_call!(raw::git_repository_set_workdir(
                self.raw(),
                path,
                update_gitlink
            ));
        }
        Ok(())
    }

    /// Get the currently active namespace for this repository.
    ///
    /// If there is no namespace, or the namespace is not a valid utf8 string,
    /// `None` is returned.
    pub fn namespace(&self) -> Option<&str> {
        self.namespace_bytes().and_then(|s| str::from_utf8(s).ok())
    }

    /// Get the currently active namespace for this repository as a byte array.
    ///
    /// If there is no namespace, `None` is returned.
    pub fn namespace_bytes(&self) -> Option<&[u8]> {
        unsafe { crate::opt_bytes(self, raw::git_repository_get_namespace(self.raw)) }
    }

    /// Set the active namespace for this repository.
    pub fn set_namespace(&self, namespace: &str) -> Result<(), Error> {
        self.set_namespace_bytes(namespace.as_bytes())
    }

    /// Set the active namespace for this repository as a byte array.
    pub fn set_namespace_bytes(&self, namespace: &[u8]) -> Result<(), Error> {
        unsafe {
            let namespace = CString::new(namespace)?;
            try_call!(raw::git_repository_set_namespace(self.raw, namespace));
            Ok(())
        }
    }

    /// Remove the active namespace for this repository.
    pub fn remove_namespace(&self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_repository_set_namespace(self.raw, ptr::null()));
            Ok(())
        }
    }

    /// Retrieves the Git merge message.
    /// Remember to remove the message when finished.
    pub fn message(&self) -> Result<String, Error> {
        unsafe {
            let buf = Buf::new();
            try_call!(raw::git_repository_message(buf.raw(), self.raw));
            Ok(str::from_utf8(&buf).unwrap().to_string())
        }
    }

    /// Remove the Git merge message.
    pub fn remove_message(&self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_repository_message_remove(self.raw));
            Ok(())
        }
    }

    /// List all remotes for a given repository
    pub fn remotes(&self) -> Result<StringArray, Error> {
        let mut arr = raw::git_strarray {
            strings: ptr::null_mut(),
            count: 0,
        };
        unsafe {
            try_call!(raw::git_remote_list(&mut arr, self.raw));
            Ok(Binding::from_raw(arr))
        }
    }

    /// Get the information for a particular remote
    pub fn find_remote(&self, name: &str) -> Result<Remote<'_>, Error> {
        let mut ret = ptr::null_mut();
        let name = CString::new(name)?;
        unsafe {
            try_call!(raw::git_remote_lookup(&mut ret, self.raw, name));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Add a remote with the default fetch refspec to the repository's
    /// configuration.
    pub fn remote(&self, name: &str, url: &str) -> Result<Remote<'_>, Error> {
        let mut ret = ptr::null_mut();
        let name = CString::new(name)?;
        let url = CString::new(url)?;
        unsafe {
            try_call!(raw::git_remote_create(&mut ret, self.raw, name, url));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Add a remote with the provided fetch refspec to the repository's
    /// configuration.
    pub fn remote_with_fetch(
        &self,
        name: &str,
        url: &str,
        fetch: &str,
    ) -> Result<Remote<'_>, Error> {
        let mut ret = ptr::null_mut();
        let name = CString::new(name)?;
        let url = CString::new(url)?;
        let fetch = CString::new(fetch)?;
        unsafe {
            try_call!(raw::git_remote_create_with_fetchspec(
                &mut ret, self.raw, name, url, fetch
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create an anonymous remote
    ///
    /// Create a remote with the given url and refspec in memory. You can use
    /// this when you have a URL instead of a remote's name. Note that anonymous
    /// remotes cannot be converted to persisted remotes.
    pub fn remote_anonymous(&self, url: &str) -> Result<Remote<'_>, Error> {
        let mut ret = ptr::null_mut();
        let url = CString::new(url)?;
        unsafe {
            try_call!(raw::git_remote_create_anonymous(&mut ret, self.raw, url));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Give a remote a new name
    ///
    /// All remote-tracking branches and configuration settings for the remote
    /// are updated.
    ///
    /// A temporary in-memory remote cannot be given a name with this method.
    ///
    /// No loaded instances of the remote with the old name will change their
    /// name or their list of refspecs.
    ///
    /// The returned array of strings is a list of the non-default refspecs
    /// which cannot be renamed and are returned for further processing by the
    /// caller.
    pub fn remote_rename(&self, name: &str, new_name: &str) -> Result<StringArray, Error> {
        let name = CString::new(name)?;
        let new_name = CString::new(new_name)?;
        let mut problems = raw::git_strarray {
            count: 0,
            strings: ptr::null_mut(),
        };
        unsafe {
            try_call!(raw::git_remote_rename(
                &mut problems,
                self.raw,
                name,
                new_name
            ));
            Ok(Binding::from_raw(problems))
        }
    }

    /// Delete an existing persisted remote.
    ///
    /// All remote-tracking branches and configuration settings for the remote
    /// will be removed.
    pub fn remote_delete(&self, name: &str) -> Result<(), Error> {
        let name = CString::new(name)?;
        unsafe {
            try_call!(raw::git_remote_delete(self.raw, name));
        }
        Ok(())
    }

    /// Add a fetch refspec to the remote's configuration
    ///
    /// Add the given refspec to the fetch list in the configuration. No loaded
    /// remote instances will be affected.
    pub fn remote_add_fetch(&self, name: &str, spec: &str) -> Result<(), Error> {
        let name = CString::new(name)?;
        let spec = CString::new(spec)?;
        unsafe {
            try_call!(raw::git_remote_add_fetch(self.raw, name, spec));
        }
        Ok(())
    }

    /// Add a push refspec to the remote's configuration.
    ///
    /// Add the given refspec to the push list in the configuration. No
    /// loaded remote instances will be affected.
    pub fn remote_add_push(&self, name: &str, spec: &str) -> Result<(), Error> {
        let name = CString::new(name)?;
        let spec = CString::new(spec)?;
        unsafe {
            try_call!(raw::git_remote_add_push(self.raw, name, spec));
        }
        Ok(())
    }

    /// Set the remote's url in the configuration
    ///
    /// Remote objects already in memory will not be affected. This assumes
    /// the common case of a single-url remote and will otherwise return an
    /// error.
    pub fn remote_set_url(&self, name: &str, url: &str) -> Result<(), Error> {
        let name = CString::new(name)?;
        let url = CString::new(url)?;
        unsafe {
            try_call!(raw::git_remote_set_url(self.raw, name, url));
        }
        Ok(())
    }

    /// Set the remote's url for pushing in the configuration.
    ///
    /// Remote objects already in memory will not be affected. This assumes
    /// the common case of a single-url remote and will otherwise return an
    /// error.
    ///
    /// `None` indicates that it should be cleared.
    pub fn remote_set_pushurl(&self, name: &str, pushurl: Option<&str>) -> Result<(), Error> {
        let name = CString::new(name)?;
        let pushurl = crate::opt_cstr(pushurl)?;
        unsafe {
            try_call!(raw::git_remote_set_pushurl(self.raw, name, pushurl));
        }
        Ok(())
    }

    /// Sets the current head to the specified object and optionally resets
    /// the index and working tree to match.
    ///
    /// A soft reset means the head will be moved to the commit.
    ///
    /// A mixed reset will trigger a soft reset, plus the index will be
    /// replaced with the content of the commit tree.
    ///
    /// A hard reset will trigger a mixed reset and the working directory will
    /// be replaced with the content of the index. (Untracked and ignored files
    /// will be left alone, however.)
    ///
    /// The `target` is a commit-ish to which the head should be moved to. The
    /// object can either be a commit or a tag, but tags must be dereferenceable
    /// to a commit.
    ///
    /// The `checkout` options will only be used for a hard reset.
    pub fn reset(
        &self,
        target: &Object<'_>,
        kind: ResetType,
        checkout: Option<&mut CheckoutBuilder<'_>>,
    ) -> Result<(), Error> {
        unsafe {
            let mut opts: raw::git_checkout_options = mem::zeroed();
            try_call!(raw::git_checkout_init_options(
                &mut opts,
                raw::GIT_CHECKOUT_OPTIONS_VERSION
            ));
            let opts = checkout.map(|c| {
                c.configure(&mut opts);
                &mut opts
            });
            try_call!(raw::git_reset(self.raw, target.raw(), kind, opts));
        }
        Ok(())
    }

    /// Updates some entries in the index from the target commit tree.
    ///
    /// The scope of the updated entries is determined by the paths being
    /// in the iterator provided.
    ///
    /// Passing a `None` target will result in removing entries in the index
    /// matching the provided pathspecs.
    pub fn reset_default<T, I>(&self, target: Option<&Object<'_>>, paths: I) -> Result<(), Error>
    where
        T: IntoCString,
        I: IntoIterator<Item = T>,
    {
        let (_a, _b, mut arr) = crate::util::iter2cstrs_paths(paths)?;
        let target = target.map(|t| t.raw());
        unsafe {
            try_call!(raw::git_reset_default(self.raw, target, &mut arr));
        }
        Ok(())
    }

    /// Retrieve and resolve the reference pointed at by HEAD.
    pub fn head(&self) -> Result<Reference<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_head(&mut ret, self.raw));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Make the repository HEAD point to the specified reference.
    ///
    /// If the provided reference points to a tree or a blob, the HEAD is
    /// unaltered and an error is returned.
    ///
    /// If the provided reference points to a branch, the HEAD will point to
    /// that branch, staying attached, or become attached if it isn't yet. If
    /// the branch doesn't exist yet, no error will be returned. The HEAD will
    /// then be attached to an unborn branch.
    ///
    /// Otherwise, the HEAD will be detached and will directly point to the
    /// commit.
    pub fn set_head(&self, refname: &str) -> Result<(), Error> {
        let refname = CString::new(refname)?;
        unsafe {
            try_call!(raw::git_repository_set_head(self.raw, refname));
        }
        Ok(())
    }

    /// Determines whether the repository HEAD is detached.
    pub fn head_detached(&self) -> Result<bool, Error> {
        unsafe {
            let value = raw::git_repository_head_detached(self.raw);
            match value {
                0 => Ok(false),
                1 => Ok(true),
                _ => Err(Error::last_error(value).unwrap()),
            }
        }
    }

    /// Make the repository HEAD directly point to the commit.
    ///
    /// If the provided commitish cannot be found in the repository, the HEAD
    /// is unaltered and an error is returned.
    ///
    /// If the provided commitish cannot be peeled into a commit, the HEAD is
    /// unaltered and an error is returned.
    ///
    /// Otherwise, the HEAD will eventually be detached and will directly point
    /// to the peeled commit.
    pub fn set_head_detached(&self, commitish: Oid) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_repository_set_head_detached(
                self.raw,
                commitish.raw()
            ));
        }
        Ok(())
    }

    /// Make the repository HEAD directly point to the commit.
    ///
    /// If the provided commitish cannot be found in the repository, the HEAD
    /// is unaltered and an error is returned.
    /// If the provided commitish cannot be peeled into a commit, the HEAD is
    /// unaltered and an error is returned.
    /// Otherwise, the HEAD will eventually be detached and will directly point
    /// to the peeled commit.
    pub fn set_head_detached_from_annotated(
        &self,
        commitish: AnnotatedCommit<'_>,
    ) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_repository_set_head_detached_from_annotated(
                self.raw,
                commitish.raw()
            ));
        }
        Ok(())
    }

    /// Create an iterator for the repo's references
    pub fn references(&self) -> Result<References<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_reference_iterator_new(&mut ret, self.raw));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create an iterator for the repo's references that match the specified
    /// glob
    pub fn references_glob(&self, glob: &str) -> Result<References<'_>, Error> {
        let mut ret = ptr::null_mut();
        let glob = CString::new(glob)?;
        unsafe {
            try_call!(raw::git_reference_iterator_glob_new(
                &mut ret, self.raw, glob
            ));

            Ok(Binding::from_raw(ret))
        }
    }

    /// Load all submodules for this repository and return them.
    pub fn submodules(&self) -> Result<Vec<Submodule<'_>>, Error> {
        struct Data<'a, 'b> {
            repo: &'b Repository,
            ret: &'a mut Vec<Submodule<'b>>,
        }
        let mut ret = Vec::new();

        unsafe {
            let mut data = Data {
                repo: self,
                ret: &mut ret,
            };
            let cb: raw::git_submodule_cb = Some(append);
            try_call!(raw::git_submodule_foreach(
                self.raw,
                cb,
                &mut data as *mut _ as *mut c_void
            ));
        }

        return Ok(ret);

        extern "C" fn append(
            _repo: *mut raw::git_submodule,
            name: *const c_char,
            data: *mut c_void,
        ) -> c_int {
            unsafe {
                let data = &mut *(data as *mut Data<'_, '_>);
                let mut raw = ptr::null_mut();
                let rc = raw::git_submodule_lookup(&mut raw, data.repo.raw(), name);
                assert_eq!(rc, 0);
                data.ret.push(Binding::from_raw(raw));
            }
            0
        }
    }

    /// Gather file status information and populate the returned structure.
    ///
    /// Note that if a pathspec is given in the options to filter the
    /// status, then the results from rename detection (if you enable it) may
    /// not be accurate. To do rename detection properly, this must be called
    /// with no pathspec so that all files can be considered.
    pub fn statuses(&self, options: Option<&mut StatusOptions>) -> Result<Statuses<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_status_list_new(
                &mut ret,
                self.raw,
                options.map(|s| s.raw()).unwrap_or(ptr::null())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Test if the ignore rules apply to a given file.
    ///
    /// This function checks the ignore rules to see if they would apply to the
    /// given file. This indicates if the file would be ignored regardless of
    /// whether the file is already in the index or committed to the repository.
    ///
    /// One way to think of this is if you were to do "git add ." on the
    /// directory containing the file, would it be added or not?
    pub fn status_should_ignore(&self, path: &Path) -> Result<bool, Error> {
        let mut ret = 0 as c_int;
        let path = util::cstring_to_repo_path(path)?;
        unsafe {
            try_call!(raw::git_status_should_ignore(&mut ret, self.raw, path));
        }
        Ok(ret != 0)
    }

    /// Get file status for a single file.
    ///
    /// This tries to get status for the filename that you give. If no files
    /// match that name (in either the HEAD, index, or working directory), this
    /// returns NotFound.
    ///
    /// If the name matches multiple files (for example, if the path names a
    /// directory or if running on a case- insensitive filesystem and yet the
    /// HEAD has two entries that both match the path), then this returns
    /// Ambiguous because it cannot give correct results.
    ///
    /// This does not do any sort of rename detection. Renames require a set of
    /// targets and because of the path filtering, there is not enough
    /// information to check renames correctly. To check file status with rename
    /// detection, there is no choice but to do a full `statuses` and scan
    /// through looking for the path that you are interested in.
    pub fn status_file(&self, path: &Path) -> Result<Status, Error> {
        let mut ret = 0 as c_uint;
        let path = path_to_repo_path(path)?;
        unsafe {
            try_call!(raw::git_status_file(&mut ret, self.raw, path));
        }
        Ok(Status::from_bits_truncate(ret as u32))
    }

    /// Create an iterator which loops over the requested branches.
    pub fn branches(&self, filter: Option<BranchType>) -> Result<Branches<'_>, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_branch_iterator_new(&mut raw, self.raw(), filter));
            Ok(Branches::from_raw(raw))
        }
    }

    /// Get the Index file for this repository.
    ///
    /// If a custom index has not been set, the default index for the repository
    /// will be returned (the one located in .git/index).
    pub fn index(&self) -> Result<Index, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_index(&mut raw, self.raw()));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Set the Index file for this repository.
    pub fn set_index(&self, index: &mut Index) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_repository_set_index(self.raw(), index.raw()));
        }
        Ok(())
    }

    /// Get the configuration file for this repository.
    ///
    /// If a configuration file has not been set, the default config set for the
    /// repository will be returned, including global and system configurations
    /// (if they are available).
    pub fn config(&self) -> Result<Config, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_config(&mut raw, self.raw()));
            Ok(Binding::from_raw(raw))
        }
    }

    /// 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,
        name: &str,
        flags: AttrCheckFlags,
    ) -> Result<Option<&str>, Error> {
        Ok(self
            .get_attr_bytes(path, name, flags)?
            .and_then(|a| str::from_utf8(a).ok()))
    }

    /// 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,
        name: &str,
        flags: AttrCheckFlags,
    ) -> Result<Option<&[u8]>, Error> {
        let mut ret = ptr::null();
        let path = util::cstring_to_repo_path(path)?;
        let name = CString::new(name)?;
        unsafe {
            try_call!(raw::git_attr_get(
                &mut ret,
                self.raw(),
                flags.bits(),
                path,
                name
            ));
            Ok(crate::opt_bytes(self, ret))
        }
    }

    /// Write an in-memory buffer to the ODB as a blob.
    ///
    /// The Oid returned can in turn be passed to `find_blob` to get a handle to
    /// the blob.
    pub fn blob(&self, data: &[u8]) -> Result<Oid, Error> {
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            let ptr = data.as_ptr() as *const c_void;
            let len = data.len() as size_t;
            try_call!(raw::git_blob_create_frombuffer(
                &mut raw,
                self.raw(),
                ptr,
                len
            ));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Read a file from the filesystem and write its content to the Object
    /// Database as a loose blob
    ///
    /// The Oid returned can in turn be passed to `find_blob` to get a handle to
    /// the blob.
    pub fn blob_path(&self, path: &Path) -> Result<Oid, Error> {
        // Normal file path OK (does not need Windows conversion).
        let path = path.into_c_string()?;
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_blob_create_fromdisk(&mut raw, self.raw(), path));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Create a stream to write blob
    ///
    /// This function may need to buffer the data on disk and will in general
    /// not be the right choice if you know the size of the data to write.
    ///
    /// Use `BlobWriter::commit()` to commit the write to the object db
    /// and get the object id.
    ///
    /// If the `hintpath` parameter is filled, it will be used to determine
    /// what git filters should be applied to the object before it is written
    /// to the object database.
    pub fn blob_writer(&self, hintpath: Option<&Path>) -> Result<BlobWriter<'_>, Error> {
        let path_str = match hintpath {
            Some(path) => Some(path.into_c_string()?),
            None => None,
        };
        let path = match path_str {
            Some(ref path) => path.as_ptr(),
            None => ptr::null(),
        };
        let mut out = ptr::null_mut();
        unsafe {
            try_call!(raw::git_blob_create_fromstream(&mut out, self.raw(), path));
            Ok(BlobWriter::from_raw(out))
        }
    }

    /// Lookup a reference to one of the objects in a repository.
    pub fn find_blob(&self, oid: Oid) -> Result<Blob<'_>, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_blob_lookup(&mut raw, self.raw(), oid.raw()));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Get the object database for this repository
    pub fn odb(&self) -> Result<Odb<'_>, Error> {
        let mut odb = ptr::null_mut();
        unsafe {
            try_call!(raw::git_repository_odb(&mut odb, self.raw()));
            Ok(Odb::from_raw(odb))
        }
    }

    /// Override the object database for this repository
    pub fn set_odb(&self, odb: &Odb<'_>) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_repository_set_odb(self.raw(), odb.raw()));
        }
        Ok(())
    }

    /// Create a new branch pointing at a target commit
    ///
    /// A new direct reference will be created pointing to this target commit.
    /// If `force` is true and a reference already exists with the given name,
    /// it'll be replaced.
    pub fn branch(
        &self,
        branch_name: &str,
        target: &Commit<'_>,
        force: bool,
    ) -> Result<Branch<'_>, Error> {
        let branch_name = CString::new(branch_name)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_branch_create(
                &mut raw,
                self.raw(),
                branch_name,
                target.raw(),
                force
            ));
            Ok(Branch::wrap(Binding::from_raw(raw)))
        }
    }

    /// Create a new branch pointing at a target commit
    ///
    /// This behaves like `Repository::branch()` but takes
    /// an annotated commit, which lets you specify which
    /// extended sha syntax string was specified by a user,
    /// allowing for more exact reflog messages.
    ///
    /// See the documentation for `Repository::branch()`
    pub fn branch_from_annotated_commit(
        &self,
        branch_name: &str,
        target: &AnnotatedCommit<'_>,
        force: bool,
    ) -> Result<Branch<'_>, Error> {
        let branch_name = CString::new(branch_name)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_branch_create_from_annotated(
                &mut raw,
                self.raw(),
                branch_name,
                target.raw(),
                force
            ));
            Ok(Branch::wrap(Binding::from_raw(raw)))
        }
    }

    /// Lookup a branch by its name in a repository.
    pub fn find_branch(&self, name: &str, branch_type: BranchType) -> Result<Branch<'_>, Error> {
        let name = CString::new(name)?;
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_branch_lookup(
                &mut ret,
                self.raw(),
                name,
                branch_type
            ));
            Ok(Branch::wrap(Binding::from_raw(ret)))
        }
    }

    /// Create new commit in the repository
    ///
    /// If the `update_ref` is not `None`, name of the reference that will be
    /// updated to point to this commit. If the reference is not direct, it will
    /// be resolved to a direct reference. Use "HEAD" to update the HEAD of the
    /// current branch and make it point to this commit. If the reference
    /// doesn't exist yet, it will be created. If it does exist, the first
    /// parent must be the tip of this branch.
    pub fn commit(
        &self,
        update_ref: Option<&str>,
        author: &Signature<'_>,
        committer: &Signature<'_>,
        message: &str,
        tree: &Tree<'_>,
        parents: &[&Commit<'_>],
    ) -> Result<Oid, Error> {
        let update_ref = crate::opt_cstr(update_ref)?;
        let mut parent_ptrs = parents
            .iter()
            .map(|p| p.raw() as *const raw::git_commit)
            .collect::<Vec<_>>();
        let message = CString::new(message)?;
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_commit_create(
                &mut raw,
                self.raw(),
                update_ref,
                author.raw(),
                committer.raw(),
                ptr::null(),
                message,
                tree.raw(),
                parents.len() as size_t,
                parent_ptrs.as_mut_ptr()
            ));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Create a commit object and return that as a Buf.
    ///
    /// That can be converted to a string like this `str::from_utf8(&buf).unwrap().to_string()`.
    /// And that string can be passed to the `commit_signed` function,
    /// the arguments behave the same as in the `commit` function.
    pub fn commit_create_buffer(
        &self,
        author: &Signature<'_>,
        committer: &Signature<'_>,
        message: &str,
        tree: &Tree<'_>,
        parents: &[&Commit<'_>],
    ) -> Result<Buf, Error> {
        let mut parent_ptrs = parents
            .iter()
            .map(|p| p.raw() as *const raw::git_commit)
            .collect::<Vec<_>>();
        let message = CString::new(message)?;
        let buf = Buf::new();
        unsafe {
            try_call!(raw::git_commit_create_buffer(
                buf.raw(),
                self.raw(),
                author.raw(),
                committer.raw(),
                ptr::null(),
                message,
                tree.raw(),
                parents.len() as size_t,
                parent_ptrs.as_mut_ptr()
            ));
            Ok(buf)
        }
    }

    /// Create a commit object from the given buffer and signature
    ///
    /// Given the unsigned commit object's contents, its signature and the
    /// header field in which to store the signature, attach the signature to
    /// the commit and write it into the given repository.
    ///
    /// Use `None` in `signature_field` to use the default of `gpgsig`, which is
    /// almost certainly what you want.
    ///
    /// Returns the resulting (signed) commit id.
    pub fn commit_signed(
        &self,
        commit_content: &str,
        signature: &str,
        signature_field: Option<&str>,
    ) -> Result<Oid, Error> {
        let commit_content = CString::new(commit_content)?;
        let signature = CString::new(signature)?;
        let signature_field = crate::opt_cstr(signature_field)?;
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_commit_create_with_signature(
                &mut raw,
                self.raw(),
                commit_content,
                signature,
                signature_field
            ));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Extract the signature from a commit
    ///
    /// Returns a tuple containing the signature in the first value and the
    /// signed data in the second.
    pub fn extract_signature(
        &self,
        commit_id: &Oid,
        signature_field: Option<&str>,
    ) -> Result<(Buf, Buf), Error> {
        let signature_field = crate::opt_cstr(signature_field)?;
        let signature = Buf::new();
        let content = Buf::new();
        unsafe {
            try_call!(raw::git_commit_extract_signature(
                signature.raw(),
                content.raw(),
                self.raw(),
                commit_id.raw() as *mut _,
                signature_field
            ));
            Ok((signature, content))
        }
    }

    /// Lookup a reference to one of the commits in a repository.
    pub fn find_commit(&self, oid: Oid) -> Result<Commit<'_>, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_commit_lookup(&mut raw, self.raw(), oid.raw()));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Creates an `AnnotatedCommit` from the given commit id.
    pub fn find_annotated_commit(&self, id: Oid) -> Result<AnnotatedCommit<'_>, Error> {
        unsafe {
            let mut raw = ptr::null_mut();
            try_call!(raw::git_annotated_commit_lookup(
                &mut raw,
                self.raw(),
                id.raw()
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Lookup a reference to one of the objects in a repository.
    pub fn find_object(&self, oid: Oid, kind: Option<ObjectType>) -> Result<Object<'_>, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_object_lookup(
                &mut raw,
                self.raw(),
                oid.raw(),
                kind
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Create a new direct reference.
    ///
    /// This function will return an error if a reference already exists with
    /// the given name unless force is true, in which case it will be
    /// overwritten.
    pub fn reference(
        &self,
        name: &str,
        id: Oid,
        force: bool,
        log_message: &str,
    ) -> Result<Reference<'_>, Error> {
        let name = CString::new(name)?;
        let log_message = CString::new(log_message)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_reference_create(
                &mut raw,
                self.raw(),
                name,
                id.raw(),
                force,
                log_message
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Conditionally create new direct reference.
    ///
    /// A direct reference (also called an object id reference) refers directly
    /// to a specific object id (a.k.a. OID or SHA) in the repository.  The id
    /// permanently refers to the object (although the reference itself can be
    /// moved).  For example, in libgit2 the direct ref "refs/tags/v0.17.0"
    /// refers to OID 5b9fac39d8a76b9139667c26a63e6b3f204b3977.
    ///
    /// The direct reference will be created in the repository and written to
    /// the disk.
    ///
    /// Valid reference names must follow one of two patterns:
    ///
    /// 1. Top-level names must contain only capital letters and underscores,
    ///    and must begin and end with a letter.  (e.g.  "HEAD", "ORIG_HEAD").
    /// 2. Names prefixed with "refs/" can be almost anything.  You must avoid
    ///    the characters `~`, `^`, `:`, `\\`, `?`, `[`, and `*`, and the
    ///    sequences ".." and "@{" which have special meaning to revparse.
    ///
    /// This function will return an error if a reference already exists with
    /// the given name unless `force` is true, in which case it will be
    /// overwritten.
    ///
    /// The message for the reflog will be ignored if the reference does not
    /// belong in the standard set (HEAD, branches and remote-tracking
    /// branches) and it does not have a reflog.
    ///
    /// It will return GIT_EMODIFIED if the reference's value at the time of
    /// updating does not match the one passed through `current_id` (i.e. if the
    /// ref has changed since the user read it).
    pub fn reference_matching(
        &self,
        name: &str,
        id: Oid,
        force: bool,
        current_id: Oid,
        log_message: &str,
    ) -> Result<Reference<'_>, Error> {
        let name = CString::new(name)?;
        let log_message = CString::new(log_message)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_reference_create_matching(
                &mut raw,
                self.raw(),
                name,
                id.raw(),
                force,
                current_id.raw(),
                log_message
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Create a new symbolic reference.
    ///
    /// This function will return an error if a reference already exists with
    /// the given name unless force is true, in which case it will be
    /// overwritten.
    pub fn reference_symbolic(
        &self,
        name: &str,
        target: &str,
        force: bool,
        log_message: &str,
    ) -> Result<Reference<'_>, Error> {
        let name = CString::new(name)?;
        let target = CString::new(target)?;
        let log_message = CString::new(log_message)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_reference_symbolic_create(
                &mut raw,
                self.raw(),
                name,
                target,
                force,
                log_message
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Create a new symbolic reference.
    ///
    /// This function will return an error if a reference already exists with
    /// the given name unless force is true, in which case it will be
    /// overwritten.
    ///
    /// It will return GIT_EMODIFIED if the reference's value at the time of
    /// updating does not match the one passed through current_value (i.e. if
    /// the ref has changed since the user read it).
    pub fn reference_symbolic_matching(
        &self,
        name: &str,
        target: &str,
        force: bool,
        current_value: &str,
        log_message: &str,
    ) -> Result<Reference<'_>, Error> {
        let name = CString::new(name)?;
        let target = CString::new(target)?;
        let current_value = CString::new(current_value)?;
        let log_message = CString::new(log_message)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_reference_symbolic_create_matching(
                &mut raw,
                self.raw(),
                name,
                target,
                force,
                current_value,
                log_message
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Lookup a reference to one of the objects in a repository.
    pub fn find_reference(&self, name: &str) -> Result<Reference<'_>, Error> {
        let name = CString::new(name)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_reference_lookup(&mut raw, self.raw(), name));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Lookup a reference to one of the objects in a repository.
    /// `Repository::find_reference` with teeth; give the method your reference in
    /// human-readable format e.g. 'main' instead of 'refs/heads/main', and it
    /// will do-what-you-mean, returning the `Reference`.
    pub fn resolve_reference_from_short_name(&self, refname: &str) -> Result<Reference<'_>, Error> {
        let refname = CString::new(refname)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_reference_dwim(&mut raw, self.raw(), refname));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Lookup a reference by name and resolve immediately to OID.
    ///
    /// This function provides a quick way to resolve a reference name straight
    /// through to the object id that it refers to. This avoids having to
    /// allocate or free any `Reference` objects for simple situations.
    pub fn refname_to_id(&self, name: &str) -> Result<Oid, Error> {
        let name = CString::new(name)?;
        let mut ret = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_reference_name_to_id(&mut ret, self.raw(), name));
            Ok(Binding::from_raw(&ret as *const _))
        }
    }

    /// Creates a git_annotated_commit from the given reference.
    pub fn reference_to_annotated_commit(
        &self,
        reference: &Reference<'_>,
    ) -> Result<AnnotatedCommit<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_annotated_commit_from_ref(
                &mut ret,
                self.raw(),
                reference.raw()
            ));
            Ok(AnnotatedCommit::from_raw(ret))
        }
    }

    /// Creates a git_annotated_commit from FETCH_HEAD.
    pub fn annotated_commit_from_fetchhead(
        &self,
        branch_name: &str,
        remote_url: &str,
        id: &Oid,
    ) -> Result<AnnotatedCommit<'_>, Error> {
        let branch_name = CString::new(branch_name)?;
        let remote_url = CString::new(remote_url)?;

        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_annotated_commit_from_fetchhead(
                &mut ret,
                self.raw(),
                branch_name,
                remote_url,
                id.raw()
            ));
            Ok(AnnotatedCommit::from_raw(ret))
        }
    }

    /// Create a new action signature with default user and now timestamp.
    ///
    /// This looks up the user.name and user.email from the configuration and
    /// uses the current time as the timestamp, and creates a new signature
    /// based on that information. It will return `NotFound` if either the
    /// user.name or user.email are not set.
    pub fn signature(&self) -> Result<Signature<'static>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_signature_default(&mut ret, self.raw()));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Set up a new git submodule for checkout.
    ///
    /// This does "git submodule add" up to the fetch and checkout of the
    /// submodule contents. It preps a new submodule, creates an entry in
    /// `.gitmodules` and creates an empty initialized repository either at the
    /// given path in the working directory or in `.git/modules` with a gitlink
    /// from the working directory to the new repo.
    ///
    /// To fully emulate "git submodule add" call this function, then `open()`
    /// the submodule repo and perform the clone step as needed. Lastly, call
    /// `add_finalize()` to wrap up adding the new submodule and `.gitmodules`
    /// to the index to be ready to commit.
    pub fn submodule(
        &self,
        url: &str,
        path: &Path,
        use_gitlink: bool,
    ) -> Result<Submodule<'_>, Error> {
        let url = CString::new(url)?;
        let path = path_to_repo_path(path)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_submodule_add_setup(
                &mut raw,
                self.raw(),
                url,
                path,
                use_gitlink
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Lookup submodule information by name or path.
    ///
    /// Given either the submodule name or path (they are usually the same),
    /// this returns a structure describing the submodule.
    pub fn find_submodule(&self, name: &str) -> Result<Submodule<'_>, Error> {
        let name = CString::new(name)?;
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_submodule_lookup(&mut raw, self.raw(), name));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Get the status for a submodule.
    ///
    /// This looks at a submodule and tries to determine the status.  It
    /// will return a combination of the `SubmoduleStatus` values.
    pub fn submodule_status(
        &self,
        name: &str,
        ignore: SubmoduleIgnore,
    ) -> Result<SubmoduleStatus, Error> {
        let mut ret = 0;
        let name = CString::new(name)?;
        unsafe {
            try_call!(raw::git_submodule_status(&mut ret, self.raw, name, ignore));
        }
        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();
        unsafe {
            try_call!(raw::git_tree_lookup(&mut raw, self.raw(), oid.raw()));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Create a new TreeBuilder, optionally initialized with the
    /// entries of the given Tree.
    ///
    /// The tree builder can be used to create or modify trees in memory and
    /// write them as tree objects to the database.
    pub fn treebuilder(&self, tree: Option<&Tree<'_>>) -> Result<TreeBuilder<'_>, Error> {
        unsafe {
            let mut ret = ptr::null_mut();
            let tree = match tree {
                Some(tree) => tree.raw(),
                None => ptr::null_mut(),
            };
            try_call!(raw::git_treebuilder_new(&mut ret, self.raw, tree));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create a new tag in the repository from an object
    ///
    /// A new reference will also be created pointing to this tag object. If
    /// `force` is true and a reference already exists with the given name,
    /// it'll be replaced.
    ///
    /// The message will not be cleaned up.
    ///
    /// The tag name will be checked for validity. You must avoid the characters
    /// '~', '^', ':', ' \ ', '?', '[', and '*', and the sequences ".." and " @
    /// {" which have special meaning to revparse.
    pub fn tag(
        &self,
        name: &str,
        target: &Object<'_>,
        tagger: &Signature<'_>,
        message: &str,
        force: bool,
    ) -> Result<Oid, Error> {
        let name = CString::new(name)?;
        let message = CString::new(message)?;
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_tag_create(
                &mut raw,
                self.raw,
                name,
                target.raw(),
                tagger.raw(),
                message,
                force
            ));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Create a new lightweight tag pointing at a target object
    ///
    /// A new direct reference will be created pointing to this target object.
    /// If force is true and a reference already exists with the given name,
    /// it'll be replaced.
    pub fn tag_lightweight(
        &self,
        name: &str,
        target: &Object<'_>,
        force: bool,
    ) -> Result<Oid, Error> {
        let name = CString::new(name)?;
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_tag_create_lightweight(
                &mut raw,
                self.raw,
                name,
                target.raw(),
                force
            ));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Lookup a tag object from the repository.
    pub fn find_tag(&self, id: Oid) -> Result<Tag<'_>, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_tag_lookup(&mut raw, self.raw, id.raw()));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Delete an existing tag reference.
    ///
    /// The tag name will be checked for validity, see `tag` for some rules
    /// about valid names.
    pub fn tag_delete(&self, name: &str) -> Result<(), Error> {
        let name = CString::new(name)?;
        unsafe {
            try_call!(raw::git_tag_delete(self.raw, name));
            Ok(())
        }
    }

    /// Get a list with all the tags in the repository.
    ///
    /// An optional fnmatch pattern can also be specified.
    pub fn tag_names(&self, pattern: Option<&str>) -> Result<StringArray, Error> {
        let mut arr = raw::git_strarray {
            strings: ptr::null_mut(),
            count: 0,
        };
        unsafe {
            match pattern {
                Some(s) => {
                    let s = CString::new(s)?;
                    try_call!(raw::git_tag_list_match(&mut arr, s, self.raw));
                }
                None => {
                    try_call!(raw::git_tag_list(&mut arr, self.raw));
                }
            }
            Ok(Binding::from_raw(arr))
        }
    }

    /// iterate over all tags calling `cb` on each.
    /// the callback is provided the tag id and name
    pub fn tag_foreach<T>(&self, cb: T) -> Result<(), Error>
    where
        T: FnMut(Oid, &[u8]) -> bool,
    {
        let mut data = TagForeachData {
            cb: Box::new(cb) as TagForeachCB<'_>,
        };

        unsafe {
            raw::git_tag_foreach(
                self.raw,
                Some(tag_foreach_cb),
                (&mut data) as *mut _ as *mut _,
            );
        }
        Ok(())
    }

    /// Updates files in the index and the working tree to match the content of
    /// the commit pointed at by HEAD.
    pub fn checkout_head(&self, opts: Option<&mut CheckoutBuilder<'_>>) -> Result<(), Error> {
        unsafe {
            let mut raw_opts = mem::zeroed();
            try_call!(raw::git_checkout_init_options(
                &mut raw_opts,
                raw::GIT_CHECKOUT_OPTIONS_VERSION
            ));
            if let Some(c) = opts {
                c.configure(&mut raw_opts);
            }

            try_call!(raw::git_checkout_head(self.raw, &raw_opts));
        }
        Ok(())
    }

    /// Updates files in the working tree to match the content of the index.
    ///
    /// If the index is `None`, the repository's index will be used.
    pub fn checkout_index(
        &self,
        index: Option<&mut Index>,
        opts: Option<&mut CheckoutBuilder<'_>>,
    ) -> Result<(), Error> {
        unsafe {
            let mut raw_opts = mem::zeroed();
            try_call!(raw::git_checkout_init_options(
                &mut raw_opts,
                raw::GIT_CHECKOUT_OPTIONS_VERSION
            ));
            if let Some(c) = opts {
                c.configure(&mut raw_opts);
            }

            try_call!(raw::git_checkout_index(
                self.raw,
                index.map(|i| &mut *i.raw()),
                &raw_opts
            ));
        }
        Ok(())
    }

    /// Updates files in the index and working tree to match the content of the
    /// tree pointed at by the treeish.
    pub fn checkout_tree(
        &self,
        treeish: &Object<'_>,
        opts: Option<&mut CheckoutBuilder<'_>>,
    ) -> Result<(), Error> {
        unsafe {
            let mut raw_opts = mem::zeroed();
            try_call!(raw::git_checkout_init_options(
                &mut raw_opts,
                raw::GIT_CHECKOUT_OPTIONS_VERSION
            ));
            if let Some(c) = opts {
                c.configure(&mut raw_opts);
            }

            try_call!(raw::git_checkout_tree(self.raw, &*treeish.raw(), &raw_opts));
        }
        Ok(())
    }

    /// Merges the given commit(s) into HEAD, writing the results into the
    /// working directory. Any changes are staged for commit and any conflicts
    /// are written to the index. Callers should inspect the repository's index
    /// after this completes, resolve any conflicts and prepare a commit.
    ///
    /// For compatibility with git, the repository is put into a merging state.
    /// Once the commit is done (or if the user wishes to abort), you should
    /// clear this state by calling cleanup_state().
    pub fn merge(
        &self,
        annotated_commits: &[&AnnotatedCommit<'_>],
        merge_opts: Option<&mut MergeOptions>,
        checkout_opts: Option<&mut CheckoutBuilder<'_>>,
    ) -> Result<(), Error> {
        unsafe {
            let mut raw_checkout_opts = mem::zeroed();
            try_call!(raw::git_checkout_init_options(
                &mut raw_checkout_opts,
                raw::GIT_CHECKOUT_OPTIONS_VERSION
            ));
            if let Some(c) = checkout_opts {
                c.configure(&mut raw_checkout_opts);
            }

            let mut commit_ptrs = annotated_commits
                .iter()
                .map(|c| c.raw() as *const raw::git_annotated_commit)
                .collect::<Vec<_>>();

            try_call!(raw::git_merge(
                self.raw,
                commit_ptrs.as_mut_ptr(),
                annotated_commits.len() as size_t,
                merge_opts.map(|o| o.raw()).unwrap_or(ptr::null()),
                &raw_checkout_opts
            ));
        }
        Ok(())
    }

    /// Merge two commits, producing an index that reflects the result of
    /// the merge. The index may be written as-is to the working directory or
    /// checked out. If the index is to be converted to a tree, the caller
    /// should resolve any conflicts that arose as part of the merge.
    pub fn merge_commits(
        &self,
        our_commit: &Commit<'_>,
        their_commit: &Commit<'_>,
        opts: Option<&MergeOptions>,
    ) -> Result<Index, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_merge_commits(
                &mut raw,
                self.raw,
                our_commit.raw(),
                their_commit.raw(),
                opts.map(|o| o.raw())
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Merge two trees, producing an index that reflects the result of
    /// the merge. The index may be written as-is to the working directory or
    /// checked out. If the index is to be converted to a tree, the caller
    /// should resolve any conflicts that arose as part of the merge.
    pub fn merge_trees(
        &self,
        ancestor_tree: &Tree<'_>,
        our_tree: &Tree<'_>,
        their_tree: &Tree<'_>,
        opts: Option<&MergeOptions>,
    ) -> Result<Index, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_merge_trees(
                &mut raw,
                self.raw,
                ancestor_tree.raw(),
                our_tree.raw(),
                their_tree.raw(),
                opts.map(|o| o.raw())
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Remove all the metadata associated with an ongoing command like merge,
    /// revert, cherry-pick, etc. For example: MERGE_HEAD, MERGE_MSG, etc.
    pub fn cleanup_state(&self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_repository_state_cleanup(self.raw));
        }
        Ok(())
    }

    /// Analyzes the given branch(es) and determines the opportunities for
    /// merging them into the HEAD of the repository.
    pub fn merge_analysis(
        &self,
        their_heads: &[&AnnotatedCommit<'_>],
    ) -> Result<(MergeAnalysis, MergePreference), Error> {
        unsafe {
            let mut raw_merge_analysis = 0 as raw::git_merge_analysis_t;
            let mut raw_merge_preference = 0 as raw::git_merge_preference_t;
            let mut their_heads = their_heads
                .iter()
                .map(|v| v.raw() as *const _)
                .collect::<Vec<_>>();
            try_call!(raw::git_merge_analysis(
                &mut raw_merge_analysis,
                &mut raw_merge_preference,
                self.raw,
                their_heads.as_mut_ptr() as *mut _,
                their_heads.len()
            ));
            Ok((
                MergeAnalysis::from_bits_truncate(raw_merge_analysis as u32),
                MergePreference::from_bits_truncate(raw_merge_preference as u32),
            ))
        }
    }

    /// Analyzes the given branch(es) and determines the opportunities for
    /// merging them into a reference.
    pub fn merge_analysis_for_ref(
        &self,
        our_ref: &Reference<'_>,
        their_heads: &[&AnnotatedCommit<'_>],
    ) -> Result<(MergeAnalysis, MergePreference), Error> {
        unsafe {
            let mut raw_merge_analysis = 0 as raw::git_merge_analysis_t;
            let mut raw_merge_preference = 0 as raw::git_merge_preference_t;
            let mut their_heads = their_heads
                .iter()
                .map(|v| v.raw() as *const _)
                .collect::<Vec<_>>();
            try_call!(raw::git_merge_analysis_for_ref(
                &mut raw_merge_analysis,
                &mut raw_merge_preference,
                self.raw,
                our_ref.raw(),
                their_heads.as_mut_ptr() as *mut _,
                their_heads.len()
            ));
            Ok((
                MergeAnalysis::from_bits_truncate(raw_merge_analysis as u32),
                MergePreference::from_bits_truncate(raw_merge_preference as u32),
            ))
        }
    }

    /// Initializes a rebase operation to rebase the changes in `branch`
    /// relative to `upstream` onto another branch. To begin the rebase process,
    /// call `next()`.
    pub fn rebase(
        &self,
        branch: Option<&AnnotatedCommit<'_>>,
        upstream: Option<&AnnotatedCommit<'_>>,
        onto: Option<&AnnotatedCommit<'_>>,
        opts: Option<&mut RebaseOptions<'_>>,
    ) -> Result<Rebase<'_>, Error> {
        let mut rebase: *mut raw::git_rebase = ptr::null_mut();
        unsafe {
            try_call!(raw::git_rebase_init(
                &mut rebase,
                self.raw(),
                branch.map(|c| c.raw()),
                upstream.map(|c| c.raw()),
                onto.map(|c| c.raw()),
                opts.map(|o| o.raw()).unwrap_or(ptr::null())
            ));

            Ok(Rebase::from_raw(rebase))
        }
    }

    /// Opens an existing rebase that was previously started by either an
    /// invocation of `rebase()` or by another client.
    pub fn open_rebase(&self, opts: Option<&mut RebaseOptions<'_>>) -> Result<Rebase<'_>, Error> {
        let mut rebase: *mut raw::git_rebase = ptr::null_mut();
        unsafe {
            try_call!(raw::git_rebase_open(
                &mut rebase,
                self.raw(),
                opts.map(|o| o.raw()).unwrap_or(ptr::null())
            ));
            Ok(Rebase::from_raw(rebase))
        }
    }

    /// Add a note for an object
    ///
    /// The `notes_ref` argument is the canonical name of the reference to use,
    /// defaulting to "refs/notes/commits". If `force` is specified then
    /// previous notes are overwritten.
    pub fn note(
        &self,
        author: &Signature<'_>,
        committer: &Signature<'_>,
        notes_ref: Option<&str>,
        oid: Oid,
        note: &str,
        force: bool,
    ) -> Result<Oid, Error> {
        let notes_ref = crate::opt_cstr(notes_ref)?;
        let note = CString::new(note)?;
        let mut ret = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_note_create(
                &mut ret,
                self.raw,
                notes_ref,
                author.raw(),
                committer.raw(),
                oid.raw(),
                note,
                force
            ));
            Ok(Binding::from_raw(&ret as *const _))
        }
    }

    /// Get the default notes reference for this repository
    pub fn note_default_ref(&self) -> Result<String, Error> {
        let ret = Buf::new();
        unsafe {
            try_call!(raw::git_note_default_ref(ret.raw(), self.raw));
        }
        Ok(str::from_utf8(&ret).unwrap().to_string())
    }

    /// Creates a new iterator for notes in this repository.
    ///
    /// The `notes_ref` argument is the canonical name of the reference to use,
    /// defaulting to "refs/notes/commits".
    ///
    /// The iterator returned yields pairs of (Oid, Oid) where the first element
    /// is the id of the note and the second id is the id the note is
    /// annotating.
    pub fn notes(&self, notes_ref: Option<&str>) -> Result<Notes<'_>, Error> {
        let notes_ref = crate::opt_cstr(notes_ref)?;
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_note_iterator_new(&mut ret, self.raw, notes_ref));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Read the note for an object.
    ///
    /// The `notes_ref` argument is the canonical name of the reference to use,
    /// defaulting to "refs/notes/commits".
    ///
    /// The id specified is the Oid of the git object to read the note from.
    pub fn find_note(&self, notes_ref: Option<&str>, id: Oid) -> Result<Note<'_>, Error> {
        let notes_ref = crate::opt_cstr(notes_ref)?;
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_note_read(&mut ret, self.raw, notes_ref, id.raw()));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Remove the note for an object.
    ///
    /// The `notes_ref` argument is the canonical name of the reference to use,
    /// defaulting to "refs/notes/commits".
    ///
    /// The id specified is the Oid of the git object to remove the note from.
    pub fn note_delete(
        &self,
        id: Oid,
        notes_ref: Option<&str>,
        author: &Signature<'_>,
        committer: &Signature<'_>,
    ) -> Result<(), Error> {
        let notes_ref = crate::opt_cstr(notes_ref)?;
        unsafe {
            try_call!(raw::git_note_remove(
                self.raw,
                notes_ref,
                author.raw(),
                committer.raw(),
                id.raw()
            ));
            Ok(())
        }
    }

    /// Create a revwalk that can be used to traverse the commit graph.
    pub fn revwalk(&self) -> Result<Revwalk<'_>, Error> {
        let mut raw = ptr::null_mut();
        unsafe {
            try_call!(raw::git_revwalk_new(&mut raw, self.raw()));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Get the blame for a single file.
    pub fn blame_file(
        &self,
        path: &Path,
        opts: Option<&mut BlameOptions>,
    ) -> Result<Blame<'_>, Error> {
        let path = path_to_repo_path(path)?;
        let mut raw = ptr::null_mut();

        unsafe {
            try_call!(raw::git_blame_file(
                &mut raw,
                self.raw(),
                path,
                opts.map(|s| s.raw())
            ));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Find a merge base between two commits
    pub fn merge_base(&self, one: Oid, two: Oid) -> Result<Oid, Error> {
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };
        unsafe {
            try_call!(raw::git_merge_base(
                &mut raw,
                self.raw,
                one.raw(),
                two.raw()
            ));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Find a merge base given a list of commits
    pub fn merge_base_many(&self, oids: &[Oid]) -> Result<Oid, Error> {
        let mut raw = raw::git_oid {
            id: [0; raw::GIT_OID_RAWSZ],
        };

        unsafe {
            try_call!(raw::git_merge_base_many(
                &mut raw,
                self.raw,
                oids.len() as size_t,
                oids.as_ptr() as *const raw::git_oid
            ));
            Ok(Binding::from_raw(&raw as *const _))
        }
    }

    /// Find all merge bases between two commits
    pub fn merge_bases(&self, one: Oid, two: Oid) -> Result<OidArray, Error> {
        let mut arr = raw::git_oidarray {
            ids: ptr::null_mut(),
            count: 0,
        };
        unsafe {
            try_call!(raw::git_merge_bases(
                &mut arr,
                self.raw,
                one.raw(),
                two.raw()
            ));
            Ok(Binding::from_raw(arr))
        }
    }

    /// Find all merge bases given a list of commits
    pub fn merge_bases_many(&self, oids: &[Oid]) -> Result<OidArray, Error> {
        let mut arr = raw::git_oidarray {
            ids: ptr::null_mut(),
            count: 0,
        };
        unsafe {
            try_call!(raw::git_merge_bases_many(
                &mut arr,
                self.raw,
                oids.len() as size_t,
                oids.as_ptr() as *const raw::git_oid
            ));
            Ok(Binding::from_raw(arr))
        }
    }

    /// Count the number of unique commits between two commit objects
    ///
    /// There is no need for branches containing the commits to have any
    /// upstream relationship, but it helps to think of one as a branch and the
    /// other as its upstream, the ahead and behind values will be what git
    /// would report for the branches.
    pub fn graph_ahead_behind(&self, local: Oid, upstream: Oid) -> Result<(usize, usize), Error> {
        unsafe {
            let mut ahead: size_t = 0;
            let mut behind: size_t = 0;
            try_call!(raw::git_graph_ahead_behind(
                &mut ahead,
                &mut behind,
                self.raw(),
                local.raw(),
                upstream.raw()
            ));
            Ok((ahead as usize, behind as usize))
        }
    }

    /// Determine if a commit is the descendant of another commit
    pub fn graph_descendant_of(&self, commit: Oid, ancestor: Oid) -> Result<bool, Error> {
        unsafe {
            let rv = try_call!(raw::git_graph_descendant_of(
                self.raw(),
                commit.raw(),
                ancestor.raw()
            ));
            Ok(rv != 0)
        }
    }

    /// Read the reflog for the given reference
    ///
    /// If there is no reflog file for the given reference yet, an empty reflog
    /// object will be returned.
    pub fn reflog(&self, name: &str) -> Result<Reflog, Error> {
        let name = CString::new(name)?;
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_reflog_read(&mut ret, self.raw, name));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Delete the reflog for the given reference
    pub fn reflog_delete(&self, name: &str) -> Result<(), Error> {
        let name = CString::new(name)?;
        unsafe {
            try_call!(raw::git_reflog_delete(self.raw, name));
        }
        Ok(())
    }

    /// Rename a reflog
    ///
    /// The reflog to be renamed is expected to already exist.
    pub fn reflog_rename(&self, old_name: &str, new_name: &str) -> Result<(), Error> {
        let old_name = CString::new(old_name)?;
        let new_name = CString::new(new_name)?;
        unsafe {
            try_call!(raw::git_reflog_rename(self.raw, old_name, new_name));
        }
        Ok(())
    }

    /// Check if the given reference has a reflog.
    pub fn reference_has_log(&self, name: &str) -> Result<bool, Error> {
        let name = CString::new(name)?;
        let ret = unsafe { try_call!(raw::git_reference_has_log(self.raw, name)) };
        Ok(ret != 0)
    }

    /// Ensure that the given reference has a reflog.
    pub fn reference_ensure_log(&self, name: &str) -> Result<(), Error> {
        let name = CString::new(name)?;
        unsafe {
            try_call!(raw::git_reference_ensure_log(self.raw, name));
        }
        Ok(())
    }

    /// Describes a commit
    ///
    /// Performs a describe operation on the current commit and the worktree.
    /// After performing a describe on HEAD, a status is run and description is
    /// considered to be dirty if there are.
    pub fn describe(&self, opts: &DescribeOptions) -> Result<Describe<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_describe_workdir(&mut ret, self.raw, opts.raw()));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Directly run a diff on two blobs.
    ///
    /// Compared to a file, a blob lacks some contextual information. As such, the
    /// `DiffFile` given to the callback will have some fake data; i.e. mode will be
    /// 0 and path will be `None`.
    ///
    /// `None` is allowed for either `old_blob` or `new_blob` and will be treated
    /// as an empty blob, with the oid set to zero in the `DiffFile`. Passing `None`
    /// for both blobs is a noop; no callbacks will be made at all.
    ///
    /// We do run a binary content check on the blob content and if either blob looks
    /// like binary data, the `DiffFile` binary attribute will be set to 1 and no call to
    /// the `hunk_cb` nor `line_cb` will be made (unless you set the `force_text`
    /// option).
    pub fn diff_blobs(
        &self,
        old_blob: Option<&Blob<'_>>,
        old_as_path: Option<&str>,
        new_blob: Option<&Blob<'_>>,
        new_as_path: Option<&str>,
        opts: Option<&mut DiffOptions>,
        file_cb: Option<&mut FileCb<'_>>,
        binary_cb: Option<&mut BinaryCb<'_>>,
        hunk_cb: Option<&mut HunkCb<'_>>,
        line_cb: Option<&mut LineCb<'_>>,
    ) -> Result<(), Error> {
        let old_as_path = crate::opt_cstr(old_as_path)?;
        let new_as_path = crate::opt_cstr(new_as_path)?;
        let mut cbs = DiffCallbacks {
            file: file_cb,
            binary: binary_cb,
            hunk: hunk_cb,
            line: line_cb,
        };
        let ptr = &mut cbs as *mut _;
        unsafe {
            let file_cb_c: raw::git_diff_file_cb = if cbs.file.is_some() {
                Some(file_cb_c)
            } else {
                None
            };
            let binary_cb_c: raw::git_diff_binary_cb = if cbs.binary.is_some() {
                Some(binary_cb_c)
            } else {
                None
            };
            let hunk_cb_c: raw::git_diff_hunk_cb = if cbs.hunk.is_some() {
                Some(hunk_cb_c)
            } else {
                None
            };
            let line_cb_c: raw::git_diff_line_cb = if cbs.line.is_some() {
                Some(line_cb_c)
            } else {
                None
            };
            try_call!(raw::git_diff_blobs(
                old_blob.map(|s| s.raw()),
                old_as_path,
                new_blob.map(|s| s.raw()),
                new_as_path,
                opts.map(|s| s.raw()),
                file_cb_c,
                binary_cb_c,
                hunk_cb_c,
                line_cb_c,
                ptr as *mut _
            ));
            Ok(())
        }
    }

    /// Create a diff with the difference between two tree objects.
    ///
    /// This is equivalent to `git diff <old-tree> <new-tree>`
    ///
    /// The first tree will be used for the "old_file" side of the delta and the
    /// second tree will be used for the "new_file" side of the delta.  You can
    /// pass `None` to indicate an empty tree, although it is an error to pass
    /// `None` for both the `old_tree` and `new_tree`.
    pub fn diff_tree_to_tree(
        &self,
        old_tree: Option<&Tree<'_>>,
        new_tree: Option<&Tree<'_>>,
        opts: Option<&mut DiffOptions>,
    ) -> Result<Diff<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_diff_tree_to_tree(
                &mut ret,
                self.raw(),
                old_tree.map(|s| s.raw()),
                new_tree.map(|s| s.raw()),
                opts.map(|s| s.raw())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create a diff between a tree and repository index.
    ///
    /// This is equivalent to `git diff --cached <treeish>` or if you pass
    /// the HEAD tree, then like `git diff --cached`.
    ///
    /// The tree you pass will be used for the "old_file" side of the delta, and
    /// the index will be used for the "new_file" side of the delta.
    ///
    /// If you pass `None` for the index, then the existing index of the `repo`
    /// will be used.  In this case, the index will be refreshed from disk
    /// (if it has changed) before the diff is generated.
    ///
    /// If the tree is `None`, then it is considered an empty tree.
    pub fn diff_tree_to_index(
        &self,
        old_tree: Option<&Tree<'_>>,
        index: Option<&Index>,
        opts: Option<&mut DiffOptions>,
    ) -> Result<Diff<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_diff_tree_to_index(
                &mut ret,
                self.raw(),
                old_tree.map(|s| s.raw()),
                index.map(|s| s.raw()),
                opts.map(|s| s.raw())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create a diff between two index objects.
    ///
    /// The first index will be used for the "old_file" side of the delta, and
    /// the second index will be used for the "new_file" side of the delta.
    pub fn diff_index_to_index(
        &self,
        old_index: &Index,
        new_index: &Index,
        opts: Option<&mut DiffOptions>,
    ) -> Result<Diff<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_diff_index_to_index(
                &mut ret,
                self.raw(),
                old_index.raw(),
                new_index.raw(),
                opts.map(|s| s.raw())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create a diff between the repository index and the workdir directory.
    ///
    /// This matches the `git diff` command.  See the note below on
    /// `tree_to_workdir` for a discussion of the difference between
    /// `git diff` and `git diff HEAD` and how to emulate a `git diff <treeish>`
    /// using libgit2.
    ///
    /// The index will be used for the "old_file" side of the delta, and the
    /// working directory will be used for the "new_file" side of the delta.
    ///
    /// If you pass `None` for the index, then the existing index of the `repo`
    /// will be used.  In this case, the index will be refreshed from disk
    /// (if it has changed) before the diff is generated.
    pub fn diff_index_to_workdir(
        &self,
        index: Option<&Index>,
        opts: Option<&mut DiffOptions>,
    ) -> Result<Diff<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_diff_index_to_workdir(
                &mut ret,
                self.raw(),
                index.map(|s| s.raw()),
                opts.map(|s| s.raw())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create a diff between a tree and the working directory.
    ///
    /// The tree you provide will be used for the "old_file" side of the delta,
    /// and the working directory will be used for the "new_file" side.
    ///
    /// This is not the same as `git diff <treeish>` or `git diff-index
    /// <treeish>`.  Those commands use information from the index, whereas this
    /// function strictly returns the differences between the tree and the files
    /// in the working directory, regardless of the state of the index.  Use
    /// `tree_to_workdir_with_index` to emulate those commands.
    ///
    /// To see difference between this and `tree_to_workdir_with_index`,
    /// consider the example of a staged file deletion where the file has then
    /// been put back into the working dir and further modified.  The
    /// tree-to-workdir diff for that file is 'modified', but `git diff` would
    /// show status 'deleted' since there is a staged delete.
    ///
    /// If `None` is passed for `tree`, then an empty tree is used.
    pub fn diff_tree_to_workdir(
        &self,
        old_tree: Option<&Tree<'_>>,
        opts: Option<&mut DiffOptions>,
    ) -> Result<Diff<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_diff_tree_to_workdir(
                &mut ret,
                self.raw(),
                old_tree.map(|s| s.raw()),
                opts.map(|s| s.raw())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create a diff between a tree and the working directory using index data
    /// to account for staged deletes, tracked files, etc.
    ///
    /// This emulates `git diff <tree>` by diffing the tree to the index and
    /// the index to the working directory and blending the results into a
    /// single diff that includes staged deleted, etc.
    pub fn diff_tree_to_workdir_with_index(
        &self,
        old_tree: Option<&Tree<'_>>,
        opts: Option<&mut DiffOptions>,
    ) -> Result<Diff<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_diff_tree_to_workdir_with_index(
                &mut ret,
                self.raw(),
                old_tree.map(|s| s.raw()),
                opts.map(|s| s.raw())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Create a PackBuilder
    pub fn packbuilder(&self) -> Result<PackBuilder<'_>, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_packbuilder_new(&mut ret, self.raw()));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Save the local modifications to a new stash.
    pub fn stash_save(
        &mut self,
        stasher: &Signature<'_>,
        message: &str,
        flags: Option<StashFlags>,
    ) -> Result<Oid, Error> {
        self.stash_save2(stasher, Some(message), flags)
    }

    /// Save the local modifications to a new stash.
    /// unlike `stash_save` it allows to pass a null `message`
    pub fn stash_save2(
        &mut self,
        stasher: &Signature<'_>,
        message: Option<&str>,
        flags: Option<StashFlags>,
    ) -> Result<Oid, Error> {
        unsafe {
            let mut raw_oid = raw::git_oid {
                id: [0; raw::GIT_OID_RAWSZ],
            };
            let message = crate::opt_cstr(message)?;
            let flags = flags.unwrap_or_else(StashFlags::empty);
            try_call!(raw::git_stash_save(
                &mut raw_oid,
                self.raw(),
                stasher.raw(),
                message,
                flags.bits() as c_uint
            ));
            Ok(Binding::from_raw(&raw_oid as *const _))
        }
    }

    /// Apply a single stashed state from the stash list.
    pub fn stash_apply(
        &mut self,
        index: usize,
        opts: Option<&mut StashApplyOptions<'_>>,
    ) -> Result<(), Error> {
        unsafe {
            let opts = opts.map(|opts| opts.raw());
            try_call!(raw::git_stash_apply(self.raw(), index, opts));
            Ok(())
        }
    }

    /// Loop over all the stashed states and issue a callback for each one.
    ///
    /// Return `true` to continue iterating or `false` to stop.
    pub fn stash_foreach<C>(&mut self, mut callback: C) -> Result<(), Error>
    where
        C: FnMut(usize, &str, &Oid) -> bool,
    {
        unsafe {
            let mut data = StashCbData {
                callback: &mut callback,
            };
            let cb: raw::git_stash_cb = Some(stash_cb);
            try_call!(raw::git_stash_foreach(
                self.raw(),
                cb,
                &mut data as *mut _ as *mut _
            ));
            Ok(())
        }
    }

    /// Remove a single stashed state from the stash list.
    pub fn stash_drop(&mut self, index: usize) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_stash_drop(self.raw(), index));
            Ok(())
        }
    }

    /// Apply a single stashed state from the stash list and remove it from the list if successful.
    pub fn stash_pop(
        &mut self,
        index: usize,
        opts: Option<&mut StashApplyOptions<'_>>,
    ) -> Result<(), Error> {
        unsafe {
            let opts = opts.map(|opts| opts.raw());
            try_call!(raw::git_stash_pop(self.raw(), index, opts));
            Ok(())
        }
    }

    /// Add ignore rules for a repository.
    ///
    /// The format of the rules is the same one of the .gitignore file.
    pub fn add_ignore_rule(&self, rules: &str) -> Result<(), Error> {
        let rules = CString::new(rules)?;
        unsafe {
            try_call!(raw::git_ignore_add_rule(self.raw, rules));
        }
        Ok(())
    }

    /// Clear ignore rules that were explicitly added.
    pub fn clear_ignore_rules(&self) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_ignore_clear_internal_rules(self.raw));
        }
        Ok(())
    }

    /// Test if the ignore rules apply to a given path.
    pub fn is_path_ignored<P: AsRef<Path>>(&self, path: P) -> Result<bool, Error> {
        let path = util::cstring_to_repo_path(path.as_ref())?;
        let mut ignored: c_int = 0;
        unsafe {
            try_call!(raw::git_ignore_path_is_ignored(
                &mut ignored,
                self.raw,
                path
            ));
        }
        Ok(ignored == 1)
    }

    /// Perform a cherrypick
    pub fn cherrypick(
        &self,
        commit: &Commit<'_>,
        options: Option<&mut CherrypickOptions<'_>>,
    ) -> Result<(), Error> {
        let raw_opts = options.map(|o| o.raw());
        let ptr_raw_opts = match raw_opts.as_ref() {
            Some(v) => v,
            None => std::ptr::null(),
        };
        unsafe {
            try_call!(raw::git_cherrypick(self.raw(), commit.raw(), ptr_raw_opts));

            Ok(())
        }
    }

    /// Create an index of uncommitted changes, representing the result of
    /// cherry-picking.
    pub fn cherrypick_commit(
        &self,
        cherrypick_commit: &Commit<'_>,
        our_commit: &Commit<'_>,
        mainline: u32,
        options: Option<&MergeOptions>,
    ) -> Result<Index, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_cherrypick_commit(
                &mut ret,
                self.raw(),
                cherrypick_commit.raw(),
                our_commit.raw(),
                mainline,
                options.map(|o| o.raw())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Find the remote name of a remote-tracking branch
    pub fn branch_remote_name(&self, refname: &str) -> Result<Buf, Error> {
        let refname = CString::new(refname)?;
        unsafe {
            let buf = Buf::new();
            try_call!(raw::git_branch_remote_name(buf.raw(), self.raw, refname));
            Ok(buf)
        }
    }

    /// Retrieves the name of the reference supporting the remote tracking branch,
    /// given the name of a local branch reference.
    pub fn branch_upstream_name(&self, refname: &str) -> Result<Buf, Error> {
        let refname = CString::new(refname)?;
        unsafe {
            let buf = Buf::new();
            try_call!(raw::git_branch_upstream_name(buf.raw(), self.raw, refname));
            Ok(buf)
        }
    }

    /// Retrieve the name of the upstream remote of a local branch.
    pub fn branch_upstream_remote(&self, refname: &str) -> Result<Buf, Error> {
        let refname = CString::new(refname)?;
        unsafe {
            let buf = Buf::new();
            try_call!(raw::git_branch_upstream_remote(
                buf.raw(),
                self.raw,
                refname
            ));
            Ok(buf)
        }
    }

    /// Apply a Diff to the given repo, making changes directly in the working directory, the index, or both.
    pub fn apply(
        &self,
        diff: &Diff<'_>,
        location: ApplyLocation,
        options: Option<&mut ApplyOptions<'_>>,
    ) -> Result<(), Error> {
        unsafe {
            try_call!(raw::git_apply(
                self.raw,
                diff.raw(),
                location.raw(),
                options.map(|s| s.raw()).unwrap_or(ptr::null())
            ));

            Ok(())
        }
    }

    /// 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,
        commit: &Commit<'_>,
        options: Option<&mut RevertOptions<'_>>,
    ) -> Result<(), Error> {
        let raw_opts = options.map(|o| o.raw());
        let ptr_raw_opts = match raw_opts.as_ref() {
            Some(v) => v,
            None => 0 as *const _,
        };
        unsafe {
            try_call!(raw::git_revert(self.raw(), commit.raw(), ptr_raw_opts));
            Ok(())
        }
    }

    /// Reverts the given commit against the given "our" commit,
    /// producing an index that reflects the result of the revert.
    pub fn revert_commit(
        &self,
        revert_commit: &Commit<'_>,
        our_commit: &Commit<'_>,
        mainline: u32,
        options: Option<&MergeOptions>,
    ) -> Result<Index, Error> {
        let mut ret = ptr::null_mut();
        unsafe {
            try_call!(raw::git_revert_commit(
                &mut ret,
                self.raw(),
                revert_commit.raw(),
                our_commit.raw(),
                mainline,
                options.map(|o| o.raw())
            ));
            Ok(Binding::from_raw(ret))
        }
    }

    /// Lists all the worktrees for the repository
    pub fn worktrees(&self) -> Result<StringArray, Error> {
        let mut arr = raw::git_strarray {
            strings: ptr::null_mut(),
            count: 0,
        };
        unsafe {
            try_call!(raw::git_worktree_list(&mut arr, self.raw));
            Ok(Binding::from_raw(arr))
        }
    }

    /// Opens a worktree by name for the given repository
    ///
    /// This can open any worktree that the worktrees method returns.
    pub fn find_worktree(&self, name: &str) -> Result<Worktree, Error> {
        let mut raw = ptr::null_mut();
        let raw_name = CString::new(name)?;
        unsafe {
            try_call!(raw::git_worktree_lookup(&mut raw, self.raw, raw_name));
            Ok(Binding::from_raw(raw))
        }
    }

    /// Creates a new worktree for the repository
    pub fn worktree<'a>(
        &'a self,
        name: &str,
        path: &Path,
        opts: Option<&WorktreeAddOptions<'a>>,
    ) -> Result<Worktree, Error> {
        let mut raw = ptr::null_mut();
        let raw_name = CString::new(name)?;
        let raw_path = path.into_c_string()?;

        unsafe {
            try_call!(raw::git_worktree_add(
                &mut raw,
                self.raw,
                raw_name,
                raw_path,
                opts.map(|o| o.raw())
            ));
            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 {
    type Raw = *mut raw::git_repository;
    unsafe fn from_raw(ptr: *mut raw::git_repository) -> Repository {
        Repository { raw: ptr }
    }
    fn raw(&self) -> *mut raw::git_repository {
        self.raw
    }
}

impl Drop for Repository {
    fn drop(&mut self) {
        unsafe { raw::git_repository_free(self.raw) }
    }
}

impl RepositoryInitOptions {
    /// Creates a default set of initialization options.
    ///
    /// By default this will set flags for creating all necessary directories
    /// and initializing a directory from the user-configured templates path.
    pub fn new() -> RepositoryInitOptions {
        RepositoryInitOptions {
            flags: raw::GIT_REPOSITORY_INIT_MKDIR as u32
                | raw::GIT_REPOSITORY_INIT_MKPATH as u32
                | raw::GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE as u32,
            mode: 0,
            workdir_path: None,
            description: None,
            template_path: None,
            initial_head: None,
            origin_url: None,
        }
    }

    /// Create a bare repository with no working directory.
    ///
    /// Defaults to false.
    pub fn bare(&mut self, bare: bool) -> &mut RepositoryInitOptions {
        self.flag(raw::GIT_REPOSITORY_INIT_BARE, bare)
    }

    /// Return an error if the repository path appears to already be a git
    /// repository.
    ///
    /// Defaults to false.
    pub fn no_reinit(&mut self, enabled: bool) -> &mut RepositoryInitOptions {
        self.flag(raw::GIT_REPOSITORY_INIT_NO_REINIT, enabled)
    }

    /// Normally a '/.git/' will be appended to the repo path for non-bare repos
    /// (if it is not already there), but passing this flag prevents that
    /// behavior.
    ///
    /// Defaults to false.
    pub fn no_dotgit_dir(&mut self, enabled: bool) -> &mut RepositoryInitOptions {
        self.flag(raw::GIT_REPOSITORY_INIT_NO_DOTGIT_DIR, enabled)
    }

    /// Make the repo path (and workdir path) as needed. The ".git" directory
    /// will always be created regardless of this flag.
    ///
    /// Defaults to true.
    pub fn mkdir(&mut self, enabled: bool) -> &mut RepositoryInitOptions {
        self.flag(raw::GIT_REPOSITORY_INIT_MKDIR, enabled)
    }

    /// Recursively make all components of the repo and workdir path as
    /// necessary.
    ///
    /// Defaults to true.
    pub fn mkpath(&mut self, enabled: bool) -> &mut RepositoryInitOptions {
        self.flag(raw::GIT_REPOSITORY_INIT_MKPATH, enabled)
    }

    /// Set to one of the `RepositoryInit` constants, or a custom value.
    pub fn mode(&mut self, mode: RepositoryInitMode) -> &mut RepositoryInitOptions {
        self.mode = mode.bits();
        self
    }

    /// Enable or disable using external templates.
    ///
    /// If enabled, then the `template_path` option will be queried first, then
    /// `init.templatedir` from the global config, and finally
    /// `/usr/share/git-core-templates` will be used (if it exists).
    ///
    /// Defaults to true.
    pub fn external_template(&mut self, enabled: bool) -> &mut RepositoryInitOptions {
        self.flag(raw::GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE, enabled)
    }

    fn flag(
        &mut self,
        flag: raw::git_repository_init_flag_t,
        on: bool,
    ) -> &mut RepositoryInitOptions {
        if on {
            self.flags |= flag as u32;
        } else {
            self.flags &= !(flag as u32);
        }
        self
    }

    /// The path to the working directory.
    ///
    /// If this is a relative path it will be evaulated relative to the repo
    /// path. If this is not the "natural" working directory, a .git gitlink
    /// file will be created here linking to the repo path.
    pub fn workdir_path(&mut self, path: &Path) -> &mut RepositoryInitOptions {
        // Normal file path OK (does not need Windows conversion).
        self.workdir_path = Some(path.into_c_string().unwrap());
        self
    }

    /// If set, this will be used to initialize the "description" file in the
    /// repository instead of using the template content.
    pub fn description(&mut self, desc: &str) -> &mut RepositoryInitOptions {
        self.description = Some(CString::new(desc).unwrap());
        self
    }

    /// When the `external_template` option is set, this is the first location
    /// to check for the template directory.
    ///
    /// If this is not configured, then the default locations will be searched
    /// instead.
    pub fn template_path(&mut self, path: &Path) -> &mut RepositoryInitOptions {
        // Normal file path OK (does not need Windows conversion).
        self.template_path = Some(path.into_c_string().unwrap());
        self
    }

    /// The name of the head to point HEAD at.
    ///
    /// If not configured, this will be taken from your git configuration.
    /// If this begins with `refs/` it will be used verbatim;
    /// otherwise `refs/heads/` will be prefixed
    pub fn initial_head(&mut self, head: &str) -> &mut RepositoryInitOptions {
        self.initial_head = Some(CString::new(head).unwrap());
        self
    }

    /// If set, then after the rest of the repository initialization is
    /// completed an `origin` remote will be added pointing to this URL.
    pub fn origin_url(&mut self, url: &str) -> &mut RepositoryInitOptions {
        self.origin_url = Some(CString::new(url).unwrap());
        self
    }

    /// Creates a set of raw init options to be used with
    /// `git_repository_init_ext`.
    ///
    /// This method is unsafe as the returned value may have pointers to the
    /// interior of this structure.
    pub unsafe fn raw(&self) -> raw::git_repository_init_options {
        let mut opts = mem::zeroed();
        assert_eq!(
            raw::git_repository_init_init_options(
                &mut opts,
                raw::GIT_REPOSITORY_INIT_OPTIONS_VERSION
            ),
            0
        );
        opts.flags = self.flags;
        opts.mode = self.mode;
        opts.workdir_path = crate::call::convert(&self.workdir_path);
        opts.description = crate::call::convert(&self.description);
        opts.template_path = crate::call::convert(&self.template_path);
        opts.initial_head = crate::call::convert(&self.initial_head);
        opts.origin_url = crate::call::convert(&self.origin_url);
        opts
    }
}

#[cfg(test)]
mod tests {
    use crate::build::CheckoutBuilder;
    use crate::CherrypickOptions;
    use crate::{
        ObjectType, Oid, Repository, ResetType, Signature, SubmoduleIgnore, SubmoduleUpdate,
    };
    use std::ffi::OsStr;
    use std::fs;
    use std::path::Path;
    use tempfile::TempDir;

    #[test]
    fn smoke_init() {
        let td = TempDir::new().unwrap();
        let path = td.path();

        let repo = Repository::init(path).unwrap();
        assert!(!repo.is_bare());
    }

    #[test]
    fn smoke_init_bare() {
        let td = TempDir::new().unwrap();
        let path = td.path();

        let repo = Repository::init_bare(path).unwrap();
        assert!(repo.is_bare());
        assert!(repo.namespace().is_none());
    }

    #[test]
    fn smoke_open() {
        let td = TempDir::new().unwrap();
        let path = td.path();
        Repository::init(td.path()).unwrap();
        let repo = Repository::open(path).unwrap();
        assert!(!repo.is_bare());
        assert!(!repo.is_shallow());
        assert!(repo.is_empty().unwrap());
        assert_eq!(
            crate::test::realpath(&repo.path()).unwrap(),
            crate::test::realpath(&td.path().join(".git/")).unwrap()
        );
        assert_eq!(repo.state(), crate::RepositoryState::Clean);
    }

    #[test]
    fn smoke_open_bare() {
        let td = TempDir::new().unwrap();
        let path = td.path();
        Repository::init_bare(td.path()).unwrap();

        let repo = Repository::open(path).unwrap();
        assert!(repo.is_bare());
        assert_eq!(
            crate::test::realpath(&repo.path()).unwrap(),
            crate::test::realpath(&td.path().join("")).unwrap()
        );
    }

    #[test]
    fn smoke_checkout() {
        let (_td, repo) = crate::test::repo_init();
        repo.checkout_head(None).unwrap();
    }

    #[test]
    fn smoke_revparse() {
        let (_td, repo) = crate::test::repo_init();
        let rev = repo.revparse("HEAD").unwrap();
        assert!(rev.to().is_none());
        let from = rev.from().unwrap();
        assert!(rev.from().is_some());

        assert_eq!(repo.revparse_single("HEAD").unwrap().id(), from.id());
        let obj = repo.find_object(from.id(), None).unwrap().clone();
        obj.peel(ObjectType::Any).unwrap();
        obj.short_id().unwrap();
        repo.reset(&obj, ResetType::Hard, None).unwrap();
        let mut opts = CheckoutBuilder::new();
        t!(repo.reset(&obj, ResetType::Soft, Some(&mut opts)));
    }

    #[test]
    fn makes_dirs() {
        let td = TempDir::new().unwrap();
        Repository::init(&td.path().join("a/b/c/d")).unwrap();
    }

    #[test]
    fn smoke_discover() {
        let td = TempDir::new().unwrap();
        let subdir = td.path().join("subdi");
        fs::create_dir(&subdir).unwrap();
        Repository::init_bare(td.path()).unwrap();
        let repo = Repository::discover(&subdir).unwrap();
        assert_eq!(
            crate::test::realpath(&repo.path()).unwrap(),
            crate::test::realpath(&td.path().join("")).unwrap()
        );
    }

    #[test]
    fn smoke_open_ext() {
        let td = TempDir::new().unwrap();
        let subdir = td.path().join("subdir");
        fs::create_dir(&subdir).unwrap();
        Repository::init(td.path()).unwrap();

        let repo = Repository::open_ext(
            &subdir,
            crate::RepositoryOpenFlags::empty(),
            &[] as &[&OsStr],
        )
        .unwrap();
        assert!(!repo.is_bare());
        assert_eq!(
            crate::test::realpath(&repo.path()).unwrap(),
            crate::test::realpath(&td.path().join(".git")).unwrap()
        );

        let repo =
            Repository::open_ext(&subdir, crate::RepositoryOpenFlags::BARE, &[] as &[&OsStr])
                .unwrap();
        assert!(repo.is_bare());
        assert_eq!(
            crate::test::realpath(&repo.path()).unwrap(),
            crate::test::realpath(&td.path().join(".git")).unwrap()
        );

        let err = Repository::open_ext(
            &subdir,
            crate::RepositoryOpenFlags::NO_SEARCH,
            &[] as &[&OsStr],
        )
        .err()
        .unwrap();
        assert_eq!(err.code(), crate::ErrorCode::NotFound);

        assert!(
            Repository::open_ext(&subdir, crate::RepositoryOpenFlags::empty(), &[&subdir]).is_ok()
        );
    }

    fn graph_repo_init() -> (TempDir, Repository) {
        let (_td, repo) = crate::test::repo_init();
        {
            let head = repo.head().unwrap().target().unwrap();
            let head = repo.find_commit(head).unwrap();

            let mut index = repo.index().unwrap();
            let id = index.write_tree().unwrap();

            let tree = repo.find_tree(id).unwrap();
            let sig = repo.signature().unwrap();
            repo.commit(Some("HEAD"), &sig, &sig, "second", &tree, &[&head])
                .unwrap();
        }
        (_td, repo)
    }

    #[test]
    fn smoke_graph_ahead_behind() {
        let (_td, repo) = graph_repo_init();
        let head = repo.head().unwrap().target().unwrap();
        let head = repo.find_commit(head).unwrap();
        let head_id = head.id();
        let head_parent_id = head.parent(0).unwrap().id();
        let (ahead, behind) = repo.graph_ahead_behind(head_id, head_parent_id).unwrap();
        assert_eq!(ahead, 1);
        assert_eq!(behind, 0);
        let (ahead, behind) = repo.graph_ahead_behind(head_parent_id, head_id).unwrap();
        assert_eq!(ahead, 0);
        assert_eq!(behind, 1);
    }

    #[test]
    fn smoke_graph_descendant_of() {
        let (_td, repo) = graph_repo_init();
        let head = repo.head().unwrap().target().unwrap();
        let head = repo.find_commit(head).unwrap();
        let head_id = head.id();
        let head_parent_id = head.parent(0).unwrap().id();
        assert!(repo.graph_descendant_of(head_id, head_parent_id).unwrap());
        assert!(!repo.graph_descendant_of(head_parent_id, head_id).unwrap());
    }

    #[test]
    fn smoke_reference_has_log_ensure_log() {
        let (_td, repo) = crate::test::repo_init();

        assert_eq!(repo.reference_has_log("HEAD").unwrap(), true);
        assert_eq!(repo.reference_has_log("refs/heads/main").unwrap(), true);
        assert_eq!(repo.reference_has_log("NOT_HEAD").unwrap(), false);
        let main_oid = repo.revparse_single("main").unwrap().id();
        assert!(repo
            .reference("NOT_HEAD", main_oid, false, "creating a new branch")
            .is_ok());
        assert_eq!(repo.reference_has_log("NOT_HEAD").unwrap(), false);
        assert!(repo.reference_ensure_log("NOT_HEAD").is_ok());
        assert_eq!(repo.reference_has_log("NOT_HEAD").unwrap(), true);
    }

    #[test]
    fn smoke_set_head() {
        let (_td, repo) = crate::test::repo_init();

        assert!(repo.set_head("refs/heads/does-not-exist").is_ok());
        assert!(repo.head().is_err());

        assert!(repo.set_head("refs/heads/main").is_ok());
        assert!(repo.head().is_ok());

        assert!(repo.set_head("*").is_err());
    }

    #[test]
    fn smoke_set_head_detached() {
        let (_td, repo) = crate::test::repo_init();

        let void_oid = Oid::from_bytes(b"00000000000000000000").unwrap();
        assert!(repo.set_head_detached(void_oid).is_err());

        let main_oid = repo.revparse_single("main").unwrap().id();
        assert!(repo.set_head_detached(main_oid).is_ok());
        assert_eq!(repo.head().unwrap().target().unwrap(), main_oid);
    }

    /// create the following:
    ///    /---o4
    ///   /---o3
    /// o1---o2
    #[test]
    fn smoke_merge_base() {
        let (_td, repo) = graph_repo_init();
        let sig = repo.signature().unwrap();

        // let oid1 = head
        let oid1 = repo.head().unwrap().target().unwrap();
        let commit1 = repo.find_commit(oid1).unwrap();
        println!("created oid1 {:?}", oid1);

        repo.branch("branch_a", &commit1, true).unwrap();
        repo.branch("branch_b", &commit1, true).unwrap();
        repo.branch("branch_c", &commit1, true).unwrap();

        // create commit oid2 on branch_a
        let mut index = repo.index().unwrap();
        let p = Path::new(repo.workdir().unwrap()).join("file_a");
        println!("using path {:?}", p);
        fs::File::create(&p).unwrap();
        index.add_path(Path::new("file_a")).unwrap();
        let id_a = index.write_tree().unwrap();
        let tree_a = repo.find_tree(id_a).unwrap();
        let oid2 = repo
            .commit(
                Some("refs/heads/branch_a"),
                &sig,
                &sig,
                "commit 2",
                &tree_a,
                &[&commit1],
            )
            .unwrap();
        repo.find_commit(oid2).unwrap();
        println!("created oid2 {:?}", oid2);

        t!(repo.reset(commit1.as_object(), ResetType::Hard, None));

        // create commit oid3 on branch_b
        let mut index = repo.index().unwrap();
        let p = Path::new(repo.workdir().unwrap()).join("file_b");
        fs::File::create(&p).unwrap();
        index.add_path(Path::new("file_b")).unwrap();
        let id_b = index.write_tree().unwrap();
        let tree_b = repo.find_tree(id_b).unwrap();
        let oid3 = repo
            .commit(
                Some("refs/heads/branch_b"),
                &sig,
                &sig,
                "commit 3",
                &tree_b,
                &[&commit1],
            )
            .unwrap();
        repo.find_commit(oid3).unwrap();
        println!("created oid3 {:?}", oid3);

        t!(repo.reset(commit1.as_object(), ResetType::Hard, None));

        // create commit oid4 on branch_c
        let mut index = repo.index().unwrap();
        let p = Path::new(repo.workdir().unwrap()).join("file_c");
        fs::File::create(&p).unwrap();
        index.add_path(Path::new("file_c")).unwrap();
        let id_c = index.write_tree().unwrap();
        let tree_c = repo.find_tree(id_c).unwrap();
        let oid4 = repo
            .commit(
                Some("refs/heads/branch_c"),
                &sig,
                &sig,
                "commit 3",
                &tree_c,
                &[&commit1],
            )
            .unwrap();
        repo.find_commit(oid4).unwrap();
        println!("created oid4 {:?}", oid4);

        // the merge base of (oid2,oid3) should be oid1
        let merge_base = repo.merge_base(oid2, oid3).unwrap();
        assert_eq!(merge_base, oid1);

        // the merge base of (oid2,oid3,oid4) should be oid1
        let merge_base = repo.merge_base_many(&[oid2, oid3, oid4]).unwrap();
        assert_eq!(merge_base, oid1);
    }

    /// create an octopus:
    ///   /---o2-o4
    /// o1      X
    ///   \---o3-o5
    /// and checks that the merge bases of (o4,o5) are (o2,o3)
    #[test]
    fn smoke_merge_bases() {
        let (_td, repo) = graph_repo_init();
        let sig = repo.signature().unwrap();

        // let oid1 = head
        let oid1 = repo.head().unwrap().target().unwrap();
        let commit1 = repo.find_commit(oid1).unwrap();
        println!("created oid1 {:?}", oid1);

        repo.branch("branch_a", &commit1, true).unwrap();
        repo.branch("branch_b", &commit1, true).unwrap();

        // create commit oid2 on branchA
        let mut index = repo.index().unwrap();
        let p = Path::new(repo.workdir().unwrap()).join("file_a");
        println!("using path {:?}", p);
        fs::File::create(&p).unwrap();
        index.add_path(Path::new("file_a")).unwrap();
        let id_a = index.write_tree().unwrap();
        let tree_a = repo.find_tree(id_a).unwrap();
        let oid2 = repo
            .commit(
                Some("refs/heads/branch_a"),
                &sig,
                &sig,
                "commit 2",
                &tree_a,
                &[&commit1],
            )
            .unwrap();
        let commit2 = repo.find_commit(oid2).unwrap();
        println!("created oid2 {:?}", oid2);

        t!(repo.reset(commit1.as_object(), ResetType::Hard, None));

        // create commit oid3 on branchB
        let mut index = repo.index().unwrap();
        let p = Path::new(repo.workdir().unwrap()).join("file_b");
        fs::File::create(&p).unwrap();
        index.add_path(Path::new("file_b")).unwrap();
        let id_b = index.write_tree().unwrap();
        let tree_b = repo.find_tree(id_b).unwrap();
        let oid3 = repo
            .commit(
                Some("refs/heads/branch_b"),
                &sig,
                &sig,
                "commit 3",
                &tree_b,
                &[&commit1],
            )
            .unwrap();
        let commit3 = repo.find_commit(oid3).unwrap();
        println!("created oid3 {:?}", oid3);

        // create merge commit oid4 on branchA with parents oid2 and oid3
        //let mut index4 = repo.merge_commits(&commit2, &commit3, None).unwrap();
        repo.set_head("refs/heads/branch_a").unwrap();
        repo.checkout_head(None).unwrap();
        let oid4 = repo
            .commit(
                Some("refs/heads/branch_a"),
                &sig,
                &sig,
                "commit 4",
                &tree_a,
                &[&commit2, &commit3],
            )
            .unwrap();
        //index4.write_tree_to(&repo).unwrap();
        println!("created oid4 {:?}", oid4);

        // create merge commit oid5 on branchB with parents oid2 and oid3
        //let mut index5 = repo.merge_commits(&commit3, &commit2, None).unwrap();
        repo.set_head("refs/heads/branch_b").unwrap();
        repo.checkout_head(None).unwrap();
        let oid5 = repo
            .commit(
                Some("refs/heads/branch_b"),
                &sig,
                &sig,
                "commit 5",
                &tree_a,
                &[&commit3, &commit2],
            )
            .unwrap();
        //index5.write_tree_to(&repo).unwrap();
        println!("created oid5 {:?}", oid5);

        // merge bases of (oid4,oid5) should be (oid2,oid3)
        let merge_bases = repo.merge_bases(oid4, oid5).unwrap();
        let mut found_oid2 = false;
        let mut found_oid3 = false;
        for mg in merge_bases.iter() {
            println!("found merge base {:?}", mg);
            if mg == &oid2 {
                found_oid2 = true;
            } else if mg == &oid3 {
                found_oid3 = true;
            } else {
                assert!(false);
            }
        }
        assert!(found_oid2);
        assert!(found_oid3);
        assert_eq!(merge_bases.len(), 2);

        // merge bases of (oid4,oid5) should be (oid2,oid3)
        let merge_bases = repo.merge_bases_many(&[oid4, oid5]).unwrap();
        let mut found_oid2 = false;
        let mut found_oid3 = false;
        for mg in merge_bases.iter() {
            println!("found merge base {:?}", mg);
            if mg == &oid2 {
                found_oid2 = true;
            } else if mg == &oid3 {
                found_oid3 = true;
            } else {
                assert!(false);
            }
        }
        assert!(found_oid2);
        assert!(found_oid3);
        assert_eq!(merge_bases.len(), 2);
    }

    #[test]
    fn smoke_revparse_ext() {
        let (_td, repo) = graph_repo_init();

        {
            let short_refname = "main";
            let expected_refname = "refs/heads/main";
            let (obj, reference) = repo.revparse_ext(short_refname).unwrap();
            let expected_obj = repo.revparse_single(expected_refname).unwrap();
            assert_eq!(obj.id(), expected_obj.id());
            assert_eq!(reference.unwrap().name().unwrap(), expected_refname);
        }
        {
            let missing_refname = "refs/heads/does-not-exist";
            assert!(repo.revparse_ext(missing_refname).is_err());
        }
        {
            let (_obj, reference) = repo.revparse_ext("HEAD^").unwrap();
            assert!(reference.is_none());
        }
    }

    #[test]
    fn smoke_is_path_ignored() {
        let (_td, repo) = graph_repo_init();

        assert!(!repo.is_path_ignored(Path::new("foo")).unwrap());

        let _ = repo.add_ignore_rule("/foo");
        assert!(repo.is_path_ignored(Path::new("foo")).unwrap());
        if cfg!(windows) {
            assert!(repo.is_path_ignored(Path::new("foo\\thing")).unwrap());
        }

        let _ = repo.clear_ignore_rules();
        assert!(!repo.is_path_ignored(Path::new("foo")).unwrap());
        if cfg!(windows) {
            assert!(!repo.is_path_ignored(Path::new("foo\\thing")).unwrap());
        }
    }

    #[test]
    fn smoke_cherrypick() {
        let (_td, repo) = crate::test::repo_init();
        let sig = repo.signature().unwrap();

        let oid1 = repo.head().unwrap().target().unwrap();
        let commit1 = repo.find_commit(oid1).unwrap();

        repo.branch("branch_a", &commit1, true).unwrap();

        // Add 2 commits on top of the initial one in branch_a
        let mut index = repo.index().unwrap();
        let p1 = Path::new(repo.workdir().unwrap()).join("file_c");
        fs::File::create(&p1).unwrap();
        index.add_path(Path::new("file_c")).unwrap();
        let id = index.write_tree().unwrap();
        let tree_c = repo.find_tree(id).unwrap();
        let oid2 = repo
            .commit(
                Some("refs/heads/branch_a"),
                &sig,
                &sig,
                "commit 2",
                &tree_c,
                &[&commit1],
            )
            .unwrap();
        let commit2 = repo.find_commit(oid2).unwrap();
        println!("created oid2 {:?}", oid2);
        assert!(p1.exists());

        let mut index = repo.index().unwrap();
        let p2 = Path::new(repo.workdir().unwrap()).join("file_d");
        fs::File::create(&p2).unwrap();
        index.add_path(Path::new("file_d")).unwrap();
        let id = index.write_tree().unwrap();
        let tree_d = repo.find_tree(id).unwrap();
        let oid3 = repo
            .commit(
                Some("refs/heads/branch_a"),
                &sig,
                &sig,
                "commit 3",
                &tree_d,
                &[&commit2],
            )
            .unwrap();
        let commit3 = repo.find_commit(oid3).unwrap();
        println!("created oid3 {:?}", oid3);
        assert!(p1.exists());
        assert!(p2.exists());

        // cherry-pick commit3 on top of commit1 in branch b
        repo.reset(commit1.as_object(), ResetType::Hard, None)
            .unwrap();
        let mut cherrypick_opts = CherrypickOptions::new();
        repo.cherrypick(&commit3, Some(&mut cherrypick_opts))
            .unwrap();
        let id = repo.index().unwrap().write_tree().unwrap();
        let tree_d = repo.find_tree(id).unwrap();
        let oid4 = repo
            .commit(Some("HEAD"), &sig, &sig, "commit 4", &tree_d, &[&commit1])
            .unwrap();
        let commit4 = repo.find_commit(oid4).unwrap();
        // should have file from commit3, but not the file from commit2
        assert_eq!(commit4.parent(0).unwrap().id(), commit1.id());
        assert!(!p1.exists());
        assert!(p2.exists());
    }

    #[test]
    fn smoke_revert() {
        let (_td, repo) = crate::test::repo_init();
        let foo_file = Path::new(repo.workdir().unwrap()).join("foo");
        assert!(!foo_file.exists());

        let (oid1, _id) = crate::test::commit(&repo);
        let commit1 = repo.find_commit(oid1).unwrap();
        t!(repo.reset(commit1.as_object(), ResetType::Hard, None));
        assert!(foo_file.exists());

        repo.revert(&commit1, None).unwrap();
        let id = repo.index().unwrap().write_tree().unwrap();
        let tree2 = repo.find_tree(id).unwrap();
        let sig = repo.signature().unwrap();
        repo.commit(Some("HEAD"), &sig, &sig, "commit 1", &tree2, &[&commit1])
            .unwrap();
        // reverting once removes `foo` file
        assert!(!foo_file.exists());

        let oid2 = repo.head().unwrap().target().unwrap();
        let commit2 = repo.find_commit(oid2).unwrap();
        repo.revert(&commit2, None).unwrap();
        let id = repo.index().unwrap().write_tree().unwrap();
        let tree3 = repo.find_tree(id).unwrap();
        repo.commit(Some("HEAD"), &sig, &sig, "commit 2", &tree3, &[&commit2])
            .unwrap();
        // reverting twice restores `foo` file
        assert!(foo_file.exists());
    }

    #[test]
    fn smoke_config_write_and_read() {
        let (td, repo) = crate::test::repo_init();

        let mut config = repo.config().unwrap();

        config.set_bool("commit.gpgsign", false).unwrap();

        let c = fs::read_to_string(td.path().join(".git").join("config")).unwrap();

        assert!(c.contains("[commit]"));
        assert!(c.contains("gpgsign = false"));

        let config = repo.config().unwrap();

        assert!(!config.get_bool("commit.gpgsign").unwrap());
    }

    #[test]
    fn smoke_merge_analysis_for_ref() -> Result<(), crate::Error> {
        let (_td, repo) = graph_repo_init();

        // Set up this repo state:
        // * second (their-branch)
        // * initial (HEAD -> main)
        //
        // We expect that their-branch can be fast-forward merged into main.

        // git checkout --detach HEAD
        let head_commit = repo.head()?.peel_to_commit()?;
        repo.set_head_detached(head_commit.id())?;

        // git branch their-branch HEAD
        let their_branch = repo.branch("their-branch", &head_commit, false)?;

        // git branch -f main HEAD~
        let mut parents_iter = head_commit.parents();
        let parent = parents_iter.next().unwrap();
        assert!(parents_iter.next().is_none());

        let main = repo.branch("main", &parent, true)?;

        // git checkout main
        repo.set_head(main.get().name().expect("should be utf-8"))?;

        let (merge_analysis, _merge_preference) = repo.merge_analysis_for_ref(
            main.get(),
            &[&repo.reference_to_annotated_commit(their_branch.get())?],
        )?;

        assert!(merge_analysis.contains(crate::MergeAnalysis::ANALYSIS_FASTFORWARD));

        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@email> name <email>
Committer Name <committer.proper@email> <committer@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@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@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@email"));
        assert_eq!(mailmapped_committer.name(), Some("Committer Name"));
        assert_eq!(mailmapped_committer.email(), Some("committer.proper@email"));

        // resolve_signature() works
        assert_eq!(mm_resolve_author.email(), mailmapped_author.email());
        assert_eq!(mm_resolve_committer.email(), mailmapped_committer.email());
    }
}
