#![doc(html_root_url = "http://alexcrichton.com/git2-rs")]
#![allow(trivial_numeric_casts, trivial_casts)]
#![deny(missing_docs)]
#![cfg_attr(test, deny(warnings))]
extern crate libc;
extern crate url;
extern crate libgit2_sys as raw;
#[macro_use] extern crate bitflags;
#[cfg(test)] extern crate tempdir;
use std::ffi::{CStr, CString};
use std::fmt;
use std::str;
use std::sync::{Once, ONCE_INIT};
pub use blame::{Blame, BlameHunk, BlameIter, BlameOptions};
pub use blob::Blob;
pub use branch::{Branch, Branches};
pub use buf::Buf;
pub use commit::{Commit, Parents};
pub use config::{Config, ConfigEntry, ConfigEntries};
pub use cred::{Cred, CredentialHelper};
pub use describe::{Describe, DescribeFormatOptions, DescribeOptions};
pub use diff::{Diff, DiffDelta, DiffFile, DiffOptions, Deltas};
pub use diff::{DiffBinary, DiffBinaryFile, DiffBinaryKind};
pub use diff::{DiffLine, DiffHunk, DiffStats, DiffFindOptions};
pub use error::Error;
pub use index::{Index, IndexEntry, IndexEntries, IndexMatchedPath};
pub use merge::{AnnotatedCommit, MergeOptions};
pub use message::{message_prettify, DEFAULT_COMMENT_CHAR};
pub use note::{Note, Notes};
pub use object::Object;
pub use oid::Oid;
pub use packbuilder::{PackBuilder, PackBuilderStage};
pub use pathspec::{Pathspec, PathspecMatchList, PathspecFailedEntries};
pub use pathspec::{PathspecDiffEntries, PathspecEntries};
pub use patch::Patch;
pub use proxy_options::ProxyOptions;
pub use reference::{Reference, References, ReferenceNames};
pub use reflog::{Reflog, ReflogEntry, ReflogIter};
pub use refspec::Refspec;
pub use remote::{Remote, Refspecs, RemoteHead, FetchOptions, PushOptions};
pub use remote_callbacks::{RemoteCallbacks, Credentials, TransferProgress};
pub use remote_callbacks::{TransportMessage, Progress, UpdateTips};
pub use repo::{Repository, RepositoryInitOptions};
pub use revspec::Revspec;
pub use revwalk::Revwalk;
pub use signature::Signature;
pub use status::{StatusOptions, Statuses, StatusIter, StatusEntry, StatusShow};
pub use submodule::Submodule;
pub use tag::Tag;
pub use time::{Time, IndexTime};
pub use tree::{Tree, TreeEntry, TreeIter};
pub use treebuilder::TreeBuilder;
pub use util::IntoCString;
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
pub enum ErrorCode {
GenericError,
NotFound,
Exists,
Ambiguous,
BufSize,
User,
BareRepo,
UnbornBranch,
Unmerged,
NotFastForward,
InvalidSpec,
Conflict,
Locked,
Modified,
Auth,
Certificate,
Applied,
Peel,
Eof,
Invalid,
Uncommitted,
Directory,
}
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
pub enum ErrorClass {
None,
NoMemory,
Os,
Invalid,
Reference,
Zlib,
Repository,
Config,
Regex,
Odb,
Index,
Object,
Net,
Tag,
Tree,
Indexer,
Ssl,
Submodule,
Thread,
Stash,
Checkout,
FetchHead,
Merge,
Ssh,
Filter,
Revert,
Callback,
CherryPick,
Describe,
Rebase,
Filesystem,
}
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
#[allow(missing_docs)]
pub enum RepositoryState {
Clean,
Merge,
Revert,
RevertSequence,
CherryPick,
CherryPickSequence,
Bisect,
Rebase,
RebaseInteractive,
RebaseMerge,
ApplyMailbox,
ApplyMailboxOrRebase,
}
#[derive(Copy, Clone)]
pub enum Direction {
Fetch,
Push,
}
#[derive(Copy, Clone)]
pub enum ResetType {
Soft,
Mixed,
Hard,
}
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum ObjectType {
Any,
Commit,
Tree,
Blob,
Tag,
}
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum BranchType {
Local,
Remote,
}
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum ConfigLevel {
ProgramData,
System,
XDG,
Global,
Local,
App,
Highest,
}
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
pub enum FileFavor {
Normal,
Ours,
Theirs,
Union,
}
bitflags! {
pub flags Sort: u32 {
const SORT_NONE = raw::GIT_SORT_NONE as u32,
const SORT_TOPOLOGICAL = raw::GIT_SORT_TOPOLOGICAL as u32,
const SORT_TIME = raw::GIT_SORT_TIME as u32,
const SORT_REVERSE = raw::GIT_SORT_REVERSE as u32,
}
}
bitflags! {
pub flags CredentialType: u32 {
#[allow(missing_docs)]
const USER_PASS_PLAINTEXT = raw::GIT_CREDTYPE_USERPASS_PLAINTEXT as u32,
#[allow(missing_docs)]
const SSH_KEY = raw::GIT_CREDTYPE_SSH_KEY as u32,
#[allow(missing_docs)]
const SSH_MEMORY = raw::GIT_CREDTYPE_SSH_MEMORY as u32,
#[allow(missing_docs)]
const SSH_CUSTOM = raw::GIT_CREDTYPE_SSH_CUSTOM as u32,
#[allow(missing_docs)]
const DEFAULT = raw::GIT_CREDTYPE_DEFAULT as u32,
#[allow(missing_docs)]
const SSH_INTERACTIVE = raw::GIT_CREDTYPE_SSH_INTERACTIVE as u32,
#[allow(missing_docs)]
const USERNAME = raw::GIT_CREDTYPE_USERNAME as u32,
}
}
bitflags! {
pub flags IndexEntryFlag: u16 {
const IDXENTRY_EXTENDED = raw::GIT_IDXENTRY_EXTENDED as u16,
const IDXENTRY_VALID = raw::GIT_IDXENTRY_VALID as u16,
}
}
bitflags! {
pub flags IndexEntryExtendedFlag: u16 {
const IDXENTRY_INTENT_TO_ADD = raw::GIT_IDXENTRY_INTENT_TO_ADD as u16,
const IDXENTRY_SKIP_WORKTREE = raw::GIT_IDXENTRY_SKIP_WORKTREE as u16,
const IDXENTRY_EXTENDED2 = raw::GIT_IDXENTRY_EXTENDED2 as u16,
#[allow(missing_docs)]
const IDXENTRY_UPDATE = raw::GIT_IDXENTRY_UPDATE as u16,
#[allow(missing_docs)]
const IDXENTRY_REMOVE = raw::GIT_IDXENTRY_REMOVE as u16,
#[allow(missing_docs)]
const IDXENTRY_UPTODATE = raw::GIT_IDXENTRY_UPTODATE as u16,
#[allow(missing_docs)]
const IDXENTRY_ADDED = raw::GIT_IDXENTRY_ADDED as u16,
#[allow(missing_docs)]
const IDXENTRY_HASHED = raw::GIT_IDXENTRY_HASHED as u16,
#[allow(missing_docs)]
const IDXENTRY_UNHASHED = raw::GIT_IDXENTRY_UNHASHED as u16,
#[allow(missing_docs)]
const IDXENTRY_WT_REMOVE = raw::GIT_IDXENTRY_WT_REMOVE as u16,
#[allow(missing_docs)]
const IDXENTRY_CONFLICTED = raw::GIT_IDXENTRY_CONFLICTED as u16,
#[allow(missing_docs)]
const IDXENTRY_UNPACKED = raw::GIT_IDXENTRY_UNPACKED as u16,
#[allow(missing_docs)]
const IDXENTRY_NEW_SKIP_WORKTREE = raw::GIT_IDXENTRY_NEW_SKIP_WORKTREE as u16,
}
}
bitflags! {
pub flags IndexAddOption: u32 {
#[allow(missing_docs)]
const ADD_DEFAULT = raw::GIT_INDEX_ADD_DEFAULT as u32,
#[allow(missing_docs)]
const ADD_FORCE = raw::GIT_INDEX_ADD_FORCE as u32,
#[allow(missing_docs)]
const ADD_DISABLE_PATHSPEC_MATCH =
raw::GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH as u32,
#[allow(missing_docs)]
const ADD_CHECK_PATHSPEC = raw::GIT_INDEX_ADD_CHECK_PATHSPEC as u32,
}
}
bitflags! {
pub flags RepositoryOpenFlags: u32 {
const REPOSITORY_OPEN_NO_SEARCH = raw::GIT_REPOSITORY_OPEN_NO_SEARCH as u32,
const REPOSITORY_OPEN_CROSS_FS = raw::GIT_REPOSITORY_OPEN_CROSS_FS as u32,
const REPOSITORY_OPEN_BARE = raw::GIT_REPOSITORY_OPEN_BARE as u32,
}
}
bitflags! {
pub flags RevparseMode: u32 {
const REVPARSE_SINGLE = raw::GIT_REVPARSE_SINGLE as u32,
const REVPARSE_RANGE = raw::GIT_REVPARSE_RANGE as u32,
const REVPARSE_MERGE_BASE = raw::GIT_REVPARSE_MERGE_BASE as u32,
}
}
#[cfg(test)] #[macro_use] mod test;
#[macro_use] mod panic;
mod call;
mod util;
pub mod build;
pub mod cert;
pub mod string_array;
pub mod oid_array;
pub mod transport;
mod blame;
mod blob;
mod branch;
mod buf;
mod commit;
mod config;
mod cred;
mod describe;
mod diff;
mod error;
mod index;
mod merge;
mod message;
mod note;
mod object;
mod oid;
mod packbuilder;
mod pathspec;
mod patch;
mod proxy_options;
mod reference;
mod reflog;
mod refspec;
mod remote;
mod remote_callbacks;
mod repo;
mod revspec;
mod revwalk;
mod signature;
mod status;
mod submodule;
mod tag;
mod time;
mod tree;
mod treebuilder;
fn init() {
static INIT: Once = ONCE_INIT;
INIT.call_once(|| unsafe {
openssl_init();
let r = raw::git_libgit2_init();
assert!(r >= 0,
"couldn't initialize the libgit2 library: {}", r);
assert_eq!(libc::atexit(shutdown), 0);
});
extern fn shutdown() {
unsafe { raw::git_libgit2_shutdown(); }
}
}
#[cfg(all(unix, not(target_os = "macos"), not(target_os = "ios"), feature = "https"))]
fn openssl_init() {
extern crate openssl_sys;
extern crate openssl_probe;
openssl_sys::init();
if !cfg!(target_os = "linux") && !cfg!(target_os = "freebsd") { return }
openssl_probe::init_ssl_cert_env_vars();
}
#[cfg(any(windows, target_os = "macos", target_os = "ios", not(feature = "https")))]
fn openssl_init() {}
unsafe fn opt_bytes<'a, T>(_anchor: &'a T,
c: *const libc::c_char) -> Option<&'a [u8]> {
if c.is_null() {
None
} else {
Some(CStr::from_ptr(c).to_bytes())
}
}
fn opt_cstr<T: IntoCString>(o: Option<T>) -> Result<Option<CString>, Error> {
match o {
Some(s) => s.into_c_string().map(Some),
None => Ok(None)
}
}
impl ObjectType {
pub fn str(&self) -> &'static str {
unsafe {
let ptr = call!(raw::git_object_type2string(*self)) as *const _;
let data = CStr::from_ptr(ptr).to_bytes();
str::from_utf8(data).unwrap()
}
}
pub fn is_loose(&self) -> bool {
unsafe { (call!(raw::git_object_typeisloose(*self)) == 1) }
}
pub fn from_raw(raw: raw::git_otype) -> Option<ObjectType> {
match raw {
raw::GIT_OBJ_ANY => Some(ObjectType::Any),
raw::GIT_OBJ_COMMIT => Some(ObjectType::Commit),
raw::GIT_OBJ_TREE => Some(ObjectType::Tree),
raw::GIT_OBJ_BLOB => Some(ObjectType::Blob),
raw::GIT_OBJ_TAG => Some(ObjectType::Tag),
_ => None,
}
}
pub fn raw(&self) -> raw::git_otype {
call::convert(self)
}
pub fn from_str(s: &str) -> Option<ObjectType> {
let raw = unsafe { call!(raw::git_object_string2type(CString::new(s).unwrap())) };
ObjectType::from_raw(raw)
}
}
impl fmt::Display for ObjectType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.str().fmt(f)
}
}
impl ConfigLevel {
pub fn from_raw(raw: raw::git_config_level_t) -> ConfigLevel {
match raw {
raw::GIT_CONFIG_LEVEL_PROGRAMDATA => ConfigLevel::ProgramData,
raw::GIT_CONFIG_LEVEL_SYSTEM => ConfigLevel::System,
raw::GIT_CONFIG_LEVEL_XDG => ConfigLevel::XDG,
raw::GIT_CONFIG_LEVEL_GLOBAL => ConfigLevel::Global,
raw::GIT_CONFIG_LEVEL_LOCAL => ConfigLevel::Local,
raw::GIT_CONFIG_LEVEL_APP => ConfigLevel::App,
raw::GIT_CONFIG_HIGHEST_LEVEL => ConfigLevel::Highest,
n => panic!("unknown config level: {}", n),
}
}
}
bitflags! {
pub flags Status: u32 {
#[allow(missing_docs)]
const STATUS_CURRENT = raw::GIT_STATUS_CURRENT as u32,
#[allow(missing_docs)]
const STATUS_INDEX_NEW = raw::GIT_STATUS_INDEX_NEW as u32,
#[allow(missing_docs)]
const STATUS_INDEX_MODIFIED = raw::GIT_STATUS_INDEX_MODIFIED as u32,
#[allow(missing_docs)]
const STATUS_INDEX_DELETED = raw::GIT_STATUS_INDEX_DELETED as u32,
#[allow(missing_docs)]
const STATUS_INDEX_RENAMED = raw::GIT_STATUS_INDEX_RENAMED as u32,
#[allow(missing_docs)]
const STATUS_INDEX_TYPECHANGE = raw::GIT_STATUS_INDEX_TYPECHANGE as u32,
#[allow(missing_docs)]
const STATUS_WT_NEW = raw::GIT_STATUS_WT_NEW as u32,
#[allow(missing_docs)]
const STATUS_WT_MODIFIED = raw::GIT_STATUS_WT_MODIFIED as u32,
#[allow(missing_docs)]
const STATUS_WT_DELETED = raw::GIT_STATUS_WT_DELETED as u32,
#[allow(missing_docs)]
const STATUS_WT_TYPECHANGE = raw::GIT_STATUS_WT_TYPECHANGE as u32,
#[allow(missing_docs)]
const STATUS_WT_RENAMED = raw::GIT_STATUS_WT_RENAMED as u32,
#[allow(missing_docs)]
const STATUS_IGNORED = raw::GIT_STATUS_IGNORED as u32,
#[allow(missing_docs)]
const STATUS_CONFLICTED = raw::GIT_STATUS_CONFLICTED as u32,
}
}
bitflags! {
pub flags RepositoryInitMode: u32 {
const REPOSITORY_INIT_SHARED_UMASK =
raw::GIT_REPOSITORY_INIT_SHARED_UMASK as u32,
const REPOSITORY_INIT_SHARED_GROUP =
raw::GIT_REPOSITORY_INIT_SHARED_GROUP as u32,
const REPOSITORY_INIT_SHARED_ALL =
raw::GIT_REPOSITORY_INIT_SHARED_ALL as u32,
}
}
#[derive(Copy, Clone, Debug)]
pub enum Delta {
Unmodified,
Added,
Deleted,
Modified,
Renamed,
Copied,
Ignored,
Untracked,
Typechange,
Unreadable,
Conflicted,
}
bitflags! {
pub flags SubmoduleStatus: u32 {
#[allow(missing_docs)]
const SUBMODULE_STATUS_IN_HEAD =
raw::GIT_SUBMODULE_STATUS_IN_HEAD as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_IN_INDEX =
raw::GIT_SUBMODULE_STATUS_IN_INDEX as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_IN_CONFIG =
raw::GIT_SUBMODULE_STATUS_IN_CONFIG as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_IN_WD =
raw::GIT_SUBMODULE_STATUS_IN_WD as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_INDEX_ADDED =
raw::GIT_SUBMODULE_STATUS_INDEX_ADDED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_INDEX_DELETED =
raw::GIT_SUBMODULE_STATUS_INDEX_DELETED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_INDEX_MODIFIED =
raw::GIT_SUBMODULE_STATUS_INDEX_MODIFIED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_WD_UNINITIALIZED =
raw::GIT_SUBMODULE_STATUS_WD_UNINITIALIZED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_WD_ADDED =
raw::GIT_SUBMODULE_STATUS_WD_ADDED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_WD_DELETED =
raw::GIT_SUBMODULE_STATUS_WD_DELETED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_WD_MODIFIED =
raw::GIT_SUBMODULE_STATUS_WD_MODIFIED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_WD_INDEX_MODIFIED =
raw::GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_WD_WD_MODIFIED =
raw::GIT_SUBMODULE_STATUS_WD_WD_MODIFIED as u32,
#[allow(missing_docs)]
const SUBMODULE_STATUS_WD_UNTRACKED =
raw::GIT_SUBMODULE_STATUS_WD_UNTRACKED as u32,
}
}
pub enum SubmoduleIgnore {
Unspecified,
None,
Untracked,
Dirty,
All,
}
bitflags! {
pub flags PathspecFlags: u32 {
const PATHSPEC_DEFAULT = raw::GIT_PATHSPEC_DEFAULT as u32,
const PATHSPEC_IGNORE_CASE = raw::GIT_PATHSPEC_IGNORE_CASE as u32,
const PATHSPEC_USE_CASE = raw::GIT_PATHSPEC_USE_CASE as u32,
const PATHSPEC_NO_GLOB = raw::GIT_PATHSPEC_NO_GLOB as u32,
const PATHSPEC_NO_MATCH_ERROR = raw::GIT_PATHSPEC_NO_MATCH_ERROR as u32,
const PATHSPEC_FIND_FAILURES = raw::GIT_PATHSPEC_FIND_FAILURES as u32,
const PATHSPEC_FAILURES_ONLY = raw::GIT_PATHSPEC_FAILURES_ONLY as u32,
}
}
bitflags! {
pub flags CheckoutNotificationType: u32 {
const CHECKOUT_NOTIFICATION_CONFLICT = raw::GIT_CHECKOUT_NOTIFY_CONFLICT as u32,
const CHECKOUT_NOTIFICATION_DIRTY = raw::GIT_CHECKOUT_NOTIFY_DIRTY as u32,
const CHECKOUT_NOTIFICATION_UPDATED = raw::GIT_CHECKOUT_NOTIFY_UPDATED as u32,
const CHECKOUT_NOTIFICATION_UNTRACKED = raw::GIT_CHECKOUT_NOTIFY_UNTRACKED as u32,
const CHECKOUT_NOTIFICATION_IGNORED = raw::GIT_CHECKOUT_NOTIFY_IGNORED as u32,
}
}
#[derive(Copy, Clone)]
pub enum DiffFormat {
Patch,
PatchHeader,
Raw,
NameOnly,
NameStatus,
}
bitflags! {
pub flags DiffStatsFormat: raw::git_diff_stats_format_t {
const DIFF_STATS_NONE = raw::GIT_DIFF_STATS_NONE,
const DIFF_STATS_FULL = raw::GIT_DIFF_STATS_FULL,
const DIFF_STATS_SHORT = raw::GIT_DIFF_STATS_SHORT,
const DIFF_STATS_NUMBER = raw::GIT_DIFF_STATS_NUMBER,
const DIFF_STATS_INCLUDE_SUMMARY =
raw::GIT_DIFF_STATS_INCLUDE_SUMMARY,
}
}
pub enum AutotagOption {
Unspecified,
Auto,
None,
All,
}
pub enum FetchPrune {
Unspecified,
On,
Off,
}
#[cfg(test)]
mod tests {
use super::ObjectType;
#[test]
fn convert() {
assert_eq!(ObjectType::Blob.str(), "blob");
assert_eq!(ObjectType::from_str("blob"), Some(ObjectType::Blob));
assert!(ObjectType::Blob.is_loose());
}
}