1 //! # libgit2 bindings for Rust
3 //! This library contains bindings to the [libgit2][1] C library which is used
4 //! to manage git repositories. The library itself is a work in progress and is
5 //! likely lacking some bindings here and there, so be warned.
7 //! [1]: https://libgit2.github.com/
9 //! The git2-rs library strives to be as close to libgit2 as possible, but also
10 //! strives to make using libgit2 as safe as possible. All resource management
11 //! is automatic as well as adding strong types to all interfaces (including
14 //! ## Creating a `Repository`
16 //! The `Repository` is the source from which almost all other objects in git-rs
17 //! are spawned. A repository can be created through opening, initializing, or
20 //! ### Initializing a new repository
22 //! The `init` method will create a new repository, assuming one does not
26 //! # #![allow(unstable)]
27 //! use git2::Repository;
29 //! let repo = match Repository::init("/path/to/a/repo") {
31 //! Err(e) => panic!("failed to init: {}", e),
35 //! ### Opening an existing repository
38 //! # #![allow(unstable)]
39 //! use git2::Repository;
41 //! let repo = match Repository::open("/path/to/a/repo") {
43 //! Err(e) => panic!("failed to open: {}", e),
47 //! ### Cloning an existing repository
50 //! # #![allow(unstable)]
51 //! use git2::Repository;
53 //! let url = "https://github.com/alexcrichton/git2-rs";
54 //! let repo = match Repository::clone(url, "/path/to/a/repo") {
56 //! Err(e) => panic!("failed to clone: {}", e),
60 //! To clone using SSH, refer to [RepoBuilder](./build/struct.RepoBuilder.html).
62 //! ## Working with a `Repository`
64 //! All derivative objects, references, etc are attached to the lifetime of the
65 //! source `Repository`, to ensure that they do not outlive the repository
68 #![doc(html_root_url = "https://docs.rs/git2/0.17")]
69 #![allow(trivial_numeric_casts, trivial_casts)]
70 #![deny(missing_docs)]
71 #![warn(rust_2018_idioms)]
72 #![cfg_attr(test, deny(warnings))]
74 use bitflags
::bitflags
;
75 use libgit2_sys
as raw
;
77 use std
::ffi
::{CStr, CString}
;
82 pub use crate::apply
::{ApplyLocation, ApplyOptions}
;
83 pub use crate::attr
::AttrValue
;
84 pub use crate::blame
::{Blame, BlameHunk, BlameIter, BlameOptions}
;
85 pub use crate::blob
::{Blob, BlobWriter}
;
86 pub use crate::branch
::{Branch, Branches}
;
87 pub use crate::buf
::Buf
;
88 pub use crate::cherrypick
::CherrypickOptions
;
89 pub use crate::commit
::{Commit, Parents}
;
90 pub use crate::config
::{Config, ConfigEntries, ConfigEntry}
;
91 pub use crate::cred
::{Cred, CredentialHelper}
;
92 pub use crate::describe
::{Describe, DescribeFormatOptions, DescribeOptions}
;
93 pub use crate::diff
::{Deltas, Diff, DiffDelta, DiffFile, DiffOptions}
;
94 pub use crate::diff
::{DiffBinary, DiffBinaryFile, DiffBinaryKind}
;
95 pub use crate::diff
::{DiffFindOptions, DiffHunk, DiffLine, DiffLineType, DiffStats}
;
96 pub use crate::email
::{Email, EmailCreateOptions}
;
97 pub use crate::error
::Error
;
98 pub use crate::index
::{
99 Index
, IndexConflict
, IndexConflicts
, IndexEntries
, IndexEntry
, IndexMatchedPath
,
101 pub use crate::indexer
::{Indexer, IndexerProgress, Progress}
;
102 pub use crate::mailmap
::Mailmap
;
103 pub use crate::mempack
::Mempack
;
104 pub use crate::merge
::{AnnotatedCommit, MergeOptions}
;
105 pub use crate::message
::{
106 message_prettify
, message_trailers_bytes
, message_trailers_strs
, MessageTrailersBytes
,
107 MessageTrailersBytesIterator
, MessageTrailersStrs
, MessageTrailersStrsIterator
,
108 DEFAULT_COMMENT_CHAR
,
110 pub use crate::note
::{Note, Notes}
;
111 pub use crate::object
::Object
;
112 pub use crate::odb
::{Odb, OdbObject, OdbPackwriter, OdbReader, OdbWriter}
;
113 pub use crate::oid
::Oid
;
114 pub use crate::packbuilder
::{PackBuilder, PackBuilderStage}
;
115 pub use crate::patch
::Patch
;
116 pub use crate::pathspec
::{Pathspec, PathspecFailedEntries, PathspecMatchList}
;
117 pub use crate::pathspec
::{PathspecDiffEntries, PathspecEntries}
;
118 pub use crate::proxy_options
::ProxyOptions
;
119 pub use crate::push_update
::PushUpdate
;
120 pub use crate::rebase
::{Rebase, RebaseOperation, RebaseOperationType, RebaseOptions}
;
121 pub use crate::reference
::{Reference, ReferenceNames, References}
;
122 pub use crate::reflog
::{Reflog, ReflogEntry, ReflogIter}
;
123 pub use crate::refspec
::Refspec
;
124 pub use crate::remote
::{
125 FetchOptions
, PushOptions
, Refspecs
, Remote
, RemoteConnection
, RemoteHead
, RemoteRedirect
,
127 pub use crate::remote_callbacks
::{CertificateCheckStatus, Credentials, RemoteCallbacks}
;
128 pub use crate::remote_callbacks
::{TransportMessage, UpdateTips}
;
129 pub use crate::repo
::{Repository, RepositoryInitOptions}
;
130 pub use crate::revert
::RevertOptions
;
131 pub use crate::revspec
::Revspec
;
132 pub use crate::revwalk
::Revwalk
;
133 pub use crate::signature
::Signature
;
134 pub use crate::stash
::{StashApplyOptions, StashApplyProgressCb, StashCb}
;
135 pub use crate::status
::{StatusEntry, StatusIter, StatusOptions, StatusShow, Statuses}
;
136 pub use crate::submodule
::{Submodule, SubmoduleUpdateOptions}
;
137 pub use crate::tag
::Tag
;
138 pub use crate::time
::{IndexTime, Time}
;
139 pub use crate::tracing
::{trace_set, TraceLevel}
;
140 pub use crate::transaction
::Transaction
;
141 pub use crate::tree
::{Tree, TreeEntry, TreeIter, TreeWalkMode, TreeWalkResult}
;
142 pub use crate::treebuilder
::TreeBuilder
;
143 pub use crate::util
::IntoCString
;
144 pub use crate::version
::Version
;
145 pub use crate::worktree
::{Worktree, WorktreeAddOptions, WorktreeLockStatus, WorktreePruneOptions}
;
147 // Create a convinience method on bitflag struct which checks the given flag
148 macro_rules
! is_bit_set
{
149 ($name
:ident
, $flag
:expr
) => {
150 #[allow(missing_docs)]
151 pub fn $
name(&self) -> bool
{
152 self.intersects($flag
)
157 /// An enumeration of possible errors that can happen when working with a git
159 // Note: We omit a few native error codes, as they are unlikely to be propagated
160 // to the library user. Currently:
162 // * GIT_EPASSTHROUGH
165 #[derive(PartialEq, Eq, Clone, Debug, Copy)]
169 /// Requested object could not be found
171 /// Object exists preventing operation
173 /// More than one object matches
175 /// Output buffer too short to hold data
177 /// User-generated error
179 /// Operation not allowed on bare repository
181 /// HEAD refers to branch with no commits
183 /// Merge in progress prevented operation
185 /// Reference was not fast-forwardable
187 /// Name/ref spec was not in a valid format
189 /// Checkout conflicts prevented operation
191 /// Lock file prevented operation
193 /// Reference value does not match expected
195 /// Authentication error
197 /// Server certificate is invalid
199 /// Patch/merge has already been applied
201 /// The requested peel operation is not possible
205 /// Invalid operation or input
207 /// Uncommitted changes in index prevented operation
209 /// Operation was not valid for a directory
211 /// A merge conflict exists and cannot continue
213 /// Hashsum mismatch in object
215 /// Unsaved changes in the index would be overwritten
217 /// Patch application failed
219 /// The object is not owned by the current user
223 /// An enumeration of possible categories of things that can have
224 /// errors when working with a git repository.
225 #[derive(PartialEq, Eq, Clone, Debug, Copy)]
226 pub enum ErrorClass
{
229 /// Out of memory or insufficient allocated space
231 /// Syscall or standard system library error
235 /// Error resolving or manipulating a reference
239 /// Bad repository state
241 /// Bad configuration
247 /// Invalid index data
249 /// Error creating or obtaining an object
253 /// Error manipulating a tag
255 /// Invalid value in tree
257 /// Hashing or packing error
261 /// Error involving submodules
265 /// Error manipulating a stash
269 /// Invalid FETCH_HEAD
275 /// Error manipulating filters
277 /// Error reverting commit
279 /// Error from a user callback
281 /// Error cherry-picking commit
283 /// Can't describe object
285 /// Error during rebase
287 /// Filesystem-related error
289 /// Invalid patch data
291 /// Error involving worktrees
293 /// Hash library error or SHA-1 collision
299 /// A listing of the possible states that a repository can be in.
300 #[derive(PartialEq, Eq, Clone, Debug, Copy)]
301 #[allow(missing_docs)]
302 pub enum RepositoryState
{
314 ApplyMailboxOrRebase
,
317 /// An enumeration of the possible directions for a remote.
318 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
320 /// Data will be fetched (read) from this remote.
322 /// Data will be pushed (written) to this remote.
326 /// An enumeration of the operations that can be performed for the `reset`
327 /// method on a `Repository`.
328 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
330 /// Move the head to the given commit.
332 /// Soft plus reset the index to the commit.
334 /// Mixed plus changes in the working tree are discarded.
338 /// An enumeration all possible kinds objects may have.
339 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
340 pub enum ObjectType
{
341 /// Any kind of git object
343 /// An object which corresponds to a git commit
345 /// An object which corresponds to a git tree
347 /// An object which corresponds to a git blob
349 /// An object which corresponds to a git tag
353 /// An enumeration of all possible kinds of references.
354 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
355 pub enum ReferenceType
{
356 /// A reference which points at an object id.
359 /// A reference which points at another reference.
363 /// An enumeration for the possible types of branches
364 #[derive(PartialEq, Eq, Debug, Copy, Clone)]
365 pub enum BranchType
{
366 /// A local branch not on a remote.
368 /// A branch for a remote.
372 /// An enumeration of the possible priority levels of a config file.
374 /// The levels corresponding to the escalation logic (higher to lower) when
375 /// searching for config entries.
376 #[derive(PartialEq, Eq, Debug, Copy, Clone)]
377 pub enum ConfigLevel
{
378 /// System-wide on Windows, for compatibility with portable git
380 /// System-wide configuration file, e.g. /etc/gitconfig
382 /// XDG-compatible configuration file, e.g. ~/.config/git/config
384 /// User-specific configuration, e.g. ~/.gitconfig
386 /// Repository specific config, e.g. $PWD/.git/config
388 /// Application specific configuration file
390 /// Highest level available
394 /// Merge file favor options for `MergeOptions` instruct the file-level
395 /// merging functionality how to deal with conflicting regions of the files.
396 #[derive(PartialEq, Eq, Debug, Copy, Clone)]
398 /// When a region of a file is changed in both branches, a conflict will be
399 /// recorded in the index so that git_checkout can produce a merge file with
400 /// conflict markers in the working directory. This is the default.
402 /// When a region of a file is changed in both branches, the file created
403 /// in the index will contain the "ours" side of any conflicting region.
404 /// The index will not record a conflict.
406 /// When a region of a file is changed in both branches, the file created
407 /// in the index will contain the "theirs" side of any conflicting region.
408 /// The index will not record a conflict.
410 /// When a region of a file is changed in both branches, the file created
411 /// in the index will contain each unique line from each side, which has
412 /// the result of combining both files. The index will not record a conflict.
417 /// Orderings that may be specified for Revwalk iteration.
418 pub struct Sort
: u32 {
419 /// Sort the repository contents in no particular ordering.
421 /// This sorting is arbitrary, implementation-specific, and subject to
422 /// change at any time. This is the default sorting for new walkers.
423 const NONE
= raw
::GIT_SORT_NONE
as u32;
425 /// Sort the repository contents in topological order (children before
428 /// This sorting mode can be combined with time sorting.
429 const TOPOLOGICAL
= raw
::GIT_SORT_TOPOLOGICAL
as u32;
431 /// Sort the repository contents by commit time.
433 /// This sorting mode can be combined with topological sorting.
434 const TIME
= raw
::GIT_SORT_TIME
as u32;
436 /// Iterate through the repository contents in reverse order.
438 /// This sorting mode can be combined with any others.
439 const REVERSE
= raw
::GIT_SORT_REVERSE
as u32;
444 is_bit_set
!(is_none
, Sort
::NONE
);
445 is_bit_set
!(is_topological
, Sort
::TOPOLOGICAL
);
446 is_bit_set
!(is_time
, Sort
::TIME
);
447 is_bit_set
!(is_reverse
, Sort
::REVERSE
);
451 /// Types of credentials that can be requested by a credential callback.
452 pub struct CredentialType
: u32 {
453 #[allow(missing_docs)]
454 const USER_PASS_PLAINTEXT
= raw
::GIT_CREDTYPE_USERPASS_PLAINTEXT
as u32;
455 #[allow(missing_docs)]
456 const SSH_KEY
= raw
::GIT_CREDTYPE_SSH_KEY
as u32;
457 #[allow(missing_docs)]
458 const SSH_MEMORY
= raw
::GIT_CREDTYPE_SSH_MEMORY
as u32;
459 #[allow(missing_docs)]
460 const SSH_CUSTOM
= raw
::GIT_CREDTYPE_SSH_CUSTOM
as u32;
461 #[allow(missing_docs)]
462 const DEFAULT
= raw
::GIT_CREDTYPE_DEFAULT
as u32;
463 #[allow(missing_docs)]
464 const SSH_INTERACTIVE
= raw
::GIT_CREDTYPE_SSH_INTERACTIVE
as u32;
465 #[allow(missing_docs)]
466 const USERNAME
= raw
::GIT_CREDTYPE_USERNAME
as u32;
470 impl CredentialType
{
471 is_bit_set
!(is_user_pass_plaintext
, CredentialType
::USER_PASS_PLAINTEXT
);
472 is_bit_set
!(is_ssh_key
, CredentialType
::SSH_KEY
);
473 is_bit_set
!(is_ssh_memory
, CredentialType
::SSH_MEMORY
);
474 is_bit_set
!(is_ssh_custom
, CredentialType
::SSH_CUSTOM
);
475 is_bit_set
!(is_default
, CredentialType
::DEFAULT
);
476 is_bit_set
!(is_ssh_interactive
, CredentialType
::SSH_INTERACTIVE
);
477 is_bit_set
!(is_username
, CredentialType
::USERNAME
);
480 impl Default
for CredentialType
{
481 fn default() -> Self {
482 CredentialType
::DEFAULT
487 /// Flags for the `flags` field of an IndexEntry.
488 pub struct IndexEntryFlag
: u16 {
489 /// Set when the `extended_flags` field is valid.
490 const EXTENDED
= raw
::GIT_INDEX_ENTRY_EXTENDED
as u16;
491 /// "Assume valid" flag
492 const VALID
= raw
::GIT_INDEX_ENTRY_VALID
as u16;
496 impl IndexEntryFlag
{
497 is_bit_set
!(is_extended
, IndexEntryFlag
::EXTENDED
);
498 is_bit_set
!(is_valid
, IndexEntryFlag
::VALID
);
502 /// Flags for the `extended_flags` field of an IndexEntry.
503 pub struct IndexEntryExtendedFlag
: u16 {
504 /// An "intent to add" entry from "git add -N"
505 const INTENT_TO_ADD
= raw
::GIT_INDEX_ENTRY_INTENT_TO_ADD
as u16;
506 /// Skip the associated worktree file, for sparse checkouts
507 const SKIP_WORKTREE
= raw
::GIT_INDEX_ENTRY_SKIP_WORKTREE
as u16;
509 #[allow(missing_docs)]
510 const UPTODATE
= raw
::GIT_INDEX_ENTRY_UPTODATE
as u16;
514 impl IndexEntryExtendedFlag
{
515 is_bit_set
!(is_intent_to_add
, IndexEntryExtendedFlag
::INTENT_TO_ADD
);
516 is_bit_set
!(is_skip_worktree
, IndexEntryExtendedFlag
::SKIP_WORKTREE
);
517 is_bit_set
!(is_up_to_date
, IndexEntryExtendedFlag
::UPTODATE
);
521 /// Flags for APIs that add files matching pathspec
522 pub struct IndexAddOption
: u32 {
523 #[allow(missing_docs)]
524 const DEFAULT
= raw
::GIT_INDEX_ADD_DEFAULT
as u32;
525 #[allow(missing_docs)]
526 const FORCE
= raw
::GIT_INDEX_ADD_FORCE
as u32;
527 #[allow(missing_docs)]
528 const DISABLE_PATHSPEC_MATCH
=
529 raw
::GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH
as u32;
530 #[allow(missing_docs)]
531 const CHECK_PATHSPEC
= raw
::GIT_INDEX_ADD_CHECK_PATHSPEC
as u32;
535 impl IndexAddOption
{
536 is_bit_set
!(is_default
, IndexAddOption
::DEFAULT
);
537 is_bit_set
!(is_force
, IndexAddOption
::FORCE
);
539 is_disable_pathspec_match
,
540 IndexAddOption
::DISABLE_PATHSPEC_MATCH
542 is_bit_set
!(is_check_pathspec
, IndexAddOption
::CHECK_PATHSPEC
);
545 impl Default
for IndexAddOption
{
546 fn default() -> Self {
547 IndexAddOption
::DEFAULT
552 /// Flags for `Repository::open_ext`
553 pub struct RepositoryOpenFlags
: u32 {
554 /// Only open the specified path; don't walk upward searching.
555 const NO_SEARCH
= raw
::GIT_REPOSITORY_OPEN_NO_SEARCH
as u32;
556 /// Search across filesystem boundaries.
557 const CROSS_FS
= raw
::GIT_REPOSITORY_OPEN_CROSS_FS
as u32;
558 /// Force opening as bare repository, and defer loading its config.
559 const BARE
= raw
::GIT_REPOSITORY_OPEN_BARE
as u32;
560 /// Don't try appending `/.git` to the specified repository path.
561 const NO_DOTGIT
= raw
::GIT_REPOSITORY_OPEN_NO_DOTGIT
as u32;
562 /// Respect environment variables like `$GIT_DIR`.
563 const FROM_ENV
= raw
::GIT_REPOSITORY_OPEN_FROM_ENV
as u32;
567 impl RepositoryOpenFlags
{
568 is_bit_set
!(is_no_search
, RepositoryOpenFlags
::NO_SEARCH
);
569 is_bit_set
!(is_cross_fs
, RepositoryOpenFlags
::CROSS_FS
);
570 is_bit_set
!(is_bare
, RepositoryOpenFlags
::BARE
);
571 is_bit_set
!(is_no_dotgit
, RepositoryOpenFlags
::NO_DOTGIT
);
572 is_bit_set
!(is_from_env
, RepositoryOpenFlags
::FROM_ENV
);
576 /// Flags for the return value of `Repository::revparse`
577 pub struct RevparseMode
: u32 {
578 /// The spec targeted a single object
579 const SINGLE
= raw
::GIT_REVPARSE_SINGLE
as u32;
580 /// The spec targeted a range of commits
581 const RANGE
= raw
::GIT_REVPARSE_RANGE
as u32;
582 /// The spec used the `...` operator, which invokes special semantics.
583 const MERGE_BASE
= raw
::GIT_REVPARSE_MERGE_BASE
as u32;
588 is_bit_set
!(is_no_single
, RevparseMode
::SINGLE
);
589 is_bit_set
!(is_range
, RevparseMode
::RANGE
);
590 is_bit_set
!(is_merge_base
, RevparseMode
::MERGE_BASE
);
594 /// The results of `merge_analysis` indicating the merge opportunities.
595 pub struct MergeAnalysis
: u32 {
596 /// No merge is possible.
597 const ANALYSIS_NONE
= raw
::GIT_MERGE_ANALYSIS_NONE
as u32;
598 /// A "normal" merge; both HEAD and the given merge input have diverged
599 /// from their common ancestor. The divergent commits must be merged.
600 const ANALYSIS_NORMAL
= raw
::GIT_MERGE_ANALYSIS_NORMAL
as u32;
601 /// All given merge inputs are reachable from HEAD, meaning the
602 /// repository is up-to-date and no merge needs to be performed.
603 const ANALYSIS_UP_TO_DATE
= raw
::GIT_MERGE_ANALYSIS_UP_TO_DATE
as u32;
604 /// The given merge input is a fast-forward from HEAD and no merge
605 /// needs to be performed. Instead, the client can check out the
606 /// given merge input.
607 const ANALYSIS_FASTFORWARD
= raw
::GIT_MERGE_ANALYSIS_FASTFORWARD
as u32;
608 /// The HEAD of the current repository is "unborn" and does not point to
609 /// a valid commit. No merge can be performed, but the caller may wish
610 /// to simply set HEAD to the target commit(s).
611 const ANALYSIS_UNBORN
= raw
::GIT_MERGE_ANALYSIS_UNBORN
as u32;
616 is_bit_set
!(is_none
, MergeAnalysis
::ANALYSIS_NONE
);
617 is_bit_set
!(is_normal
, MergeAnalysis
::ANALYSIS_NORMAL
);
618 is_bit_set
!(is_up_to_date
, MergeAnalysis
::ANALYSIS_UP_TO_DATE
);
619 is_bit_set
!(is_fast_forward
, MergeAnalysis
::ANALYSIS_FASTFORWARD
);
620 is_bit_set
!(is_unborn
, MergeAnalysis
::ANALYSIS_UNBORN
);
624 /// The user's stated preference for merges.
625 pub struct MergePreference
: u32 {
626 /// No configuration was found that suggests a preferred behavior for
628 const NONE
= raw
::GIT_MERGE_PREFERENCE_NONE
as u32;
629 /// There is a `merge.ff=false` configuration setting, suggesting that
630 /// the user does not want to allow a fast-forward merge.
631 const NO_FAST_FORWARD
= raw
::GIT_MERGE_PREFERENCE_NO_FASTFORWARD
as u32;
632 /// There is a `merge.ff=only` configuration setting, suggesting that
633 /// the user only wants fast-forward merges.
634 const FASTFORWARD_ONLY
= raw
::GIT_MERGE_PREFERENCE_FASTFORWARD_ONLY
as u32;
638 impl MergePreference
{
639 is_bit_set
!(is_none
, MergePreference
::NONE
);
640 is_bit_set
!(is_no_fast_forward
, MergePreference
::NO_FAST_FORWARD
);
641 is_bit_set
!(is_fastforward_only
, MergePreference
::FASTFORWARD_ONLY
);
645 /// Flags controlling the behavior of ODB lookup operations
646 pub struct OdbLookupFlags
: u32 {
647 /// Don't call `git_odb_refresh` if the lookup fails. Useful when doing
648 /// a batch of lookup operations for objects that may legitimately not
649 /// exist. When using this flag, you may wish to manually call
650 /// `git_odb_refresh` before processing a batch of objects.
651 const NO_REFRESH
= raw
::GIT_ODB_LOOKUP_NO_REFRESH
as u32;
668 pub mod string_array
;
704 mod remote_callbacks
;
724 static INIT
: Once
= Once
::new();
735 not(target_os
= "macos"),
736 not(target_os
= "ios"),
739 fn openssl_env_init() {
740 // Currently, libgit2 leverages OpenSSL for SSL support when cloning
741 // repositories over HTTPS. This means that we're picking up an OpenSSL
742 // dependency on non-Windows platforms (where it has its own HTTPS
743 // subsystem). As a result, we need to link to OpenSSL.
745 // Now actually *linking* to OpenSSL isn't so hard. We just need to make
746 // sure to use pkg-config to discover any relevant system dependencies for
747 // differences between distributions like CentOS and Ubuntu. The actual
748 // trickiness comes about when we start *distributing* the resulting
749 // binaries. Currently Cargo is distributed in binary form as nightlies,
750 // which means we're distributing a binary with OpenSSL linked in.
752 // For historical reasons, the Linux nightly builder is running a CentOS
753 // distribution in order to have as much ABI compatibility with other
754 // distributions as possible. Sadly, however, this compatibility does not
755 // extend to OpenSSL. Currently OpenSSL has two major versions, 0.9 and 1.0,
756 // which are incompatible (many ABI differences). The CentOS builder we
757 // build on has version 1.0, as do most distributions today. Some still have
758 // 0.9, however. This means that if we are to distribute the binaries built
759 // by the CentOS machine, we would only be compatible with OpenSSL 1.0 and
760 // we would fail to run (a dynamic linker error at runtime) on systems with
761 // only 9.8 installed (hopefully).
763 // But wait, the plot thickens! Apparently CentOS has dubbed their OpenSSL
764 // library as `libssl.so.10`, notably the `10` is included at the end. On
765 // the other hand Ubuntu, for example, only distributes `libssl.so`. This
766 // means that the binaries created at CentOS are hard-wired to probe for a
767 // file called `libssl.so.10` at runtime (using the LD_LIBRARY_PATH), which
768 // will not be found on ubuntu. The conclusion of this is that binaries
769 // built on CentOS cannot be distributed to Ubuntu and run successfully.
771 // There are a number of sneaky things we could do, including, but not
774 // 1. Create a shim program which runs "just before" cargo runs. The
775 // responsibility of this shim program would be to locate `libssl.so`,
776 // whatever it's called, on the current system, make sure there's a
777 // symlink *somewhere* called `libssl.so.10`, and then set up
778 // LD_LIBRARY_PATH and run the actual cargo.
780 // This approach definitely seems unconventional, and is borderline
781 // overkill for this problem. It's also dubious if we can find a
782 // libssl.so reliably on the target system.
784 // 2. Somehow re-work the CentOS installation so that the linked-against
785 // library is called libssl.so instead of libssl.so.10
787 // The problem with this approach is that systems with 0.9 installed will
788 // start to silently fail, due to also having libraries called libssl.so
789 // (probably symlinked under a more appropriate version).
791 // 3. Compile Cargo against both OpenSSL 1.0 *and* OpenSSL 0.9, and
792 // distribute both. Also make sure that the linked-against name of the
793 // library is `libssl.so`. At runtime we determine which version is
794 // installed, and we then the appropriate binary.
796 // This approach clearly has drawbacks in terms of infrastructure and
799 // 4. Build a nightly of Cargo for each distribution we'd like to support.
800 // You would then pick the appropriate Cargo nightly to install locally.
802 // So, with all this in mind, the decision was made to *statically* link
803 // OpenSSL. This solves any problem of relying on a downstream OpenSSL
804 // version being available. This does, however, open a can of worms related
805 // to security issues. It's generally a good idea to dynamically link
806 // OpenSSL as you'll get security updates over time without having to do
807 // anything (the system administrator will update the local openssl
808 // package). By statically linking, we're forfeiting this feature.
810 // The conclusion was made it is likely appropriate for the Cargo nightlies
811 // to statically link OpenSSL, but highly encourage distributions and
812 // packagers of Cargo to dynamically link OpenSSL. Packagers are targeting
813 // one system and are distributing to only that system, so none of the
814 // problems mentioned above would arise.
816 // In order to support this, a new package was made: openssl-static-sys.
817 // This package currently performs a fairly simple task:
819 // 1. Run pkg-config to discover where openssl is installed.
820 // 2. If openssl is installed in a nonstandard location, *and* static copies
821 // of the libraries are available, copy them to $OUT_DIR.
823 // This library will bring in libssl.a and libcrypto.a into the local build,
824 // allowing them to be picked up by this crate. This allows us to configure
825 // our own buildbots to have pkg-config point to these local pre-built
826 // copies of a static OpenSSL (with very few dependencies) while allowing
827 // most other builds of Cargo to naturally dynamically link OpenSSL.
829 // So in summary, if you're with me so far, we've statically linked OpenSSL
830 // to the Cargo binary (or any binary, for that matter) and we're ready to
831 // distribute it to *all* linux distributions. Remember that our original
832 // intent for openssl was for HTTPS support, which implies that we need some
833 // for of CA certificate store to validate certificates. This is normally
834 // installed in a standard system location.
836 // Unfortunately, as one might imagine, OpenSSL is configured for where this
837 // standard location is at *build time*, but it often varies widely
838 // per-system. Consequently, it was discovered that OpenSSL will respect the
839 // SSL_CERT_FILE and SSL_CERT_DIR environment variables in order to assist
840 // in discovering the location of this file (hurray!).
842 // So, finally getting to the point, this function solely exists to support
843 // our static builds of OpenSSL by probing for the "standard system
844 // location" of certificates and setting relevant environment variable to
847 // Ah, and as a final note, this is only a problem on Linux, not on OS X. On
848 // OS X the OpenSSL binaries are stable enough that we can just rely on
849 // dynamic linkage (plus they have some weird modifications to OpenSSL which
850 // means we wouldn't want to link statically).
851 openssl_probe
::init_ssl_cert_env_vars();
858 not(feature
= "https")
860 fn openssl_env_init() {}
862 unsafe fn opt_bytes
<'a
, T
>(_anchor
: &'a T
, c
: *const libc
::c_char
) -> Option
<&'a
[u8]> {
866 Some(CStr
::from_ptr(c
).to_bytes())
870 fn opt_cstr
<T
: IntoCString
>(o
: Option
<T
>) -> Result
<Option
<CString
>, Error
> {
872 Some(s
) => s
.into_c_string().map(Some
),
878 /// Convert an object type to its string representation.
879 pub fn str(&self) -> &'
static str {
881 let ptr
= call
!(raw
::git_object_type2string(*self)) as *const _
;
882 let data
= CStr
::from_ptr(ptr
).to_bytes();
883 str::from_utf8(data
).unwrap()
887 /// Determine if the given git_object_t is a valid loose object type.
888 pub fn is_loose(&self) -> bool
{
889 unsafe { call!(raw::git_object_typeisloose(*self)) == 1 }
892 /// Convert a raw git_object_t to an ObjectType
893 pub fn from_raw(raw
: raw
::git_object_t
) -> Option
<ObjectType
> {
895 raw
::GIT_OBJECT_ANY
=> Some(ObjectType
::Any
),
896 raw
::GIT_OBJECT_COMMIT
=> Some(ObjectType
::Commit
),
897 raw
::GIT_OBJECT_TREE
=> Some(ObjectType
::Tree
),
898 raw
::GIT_OBJECT_BLOB
=> Some(ObjectType
::Blob
),
899 raw
::GIT_OBJECT_TAG
=> Some(ObjectType
::Tag
),
904 /// Convert this kind into its raw representation
905 pub fn raw(&self) -> raw
::git_object_t
{
909 /// Convert a string object type representation to its object type.
910 pub fn from_str(s
: &str) -> Option
<ObjectType
> {
911 let raw
= unsafe { call!(raw::git_object_string2type(CString::new(s).unwrap())) }
;
912 ObjectType
::from_raw(raw
)
916 impl fmt
::Display
for ObjectType
{
917 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
923 /// Convert an object type to its string representation.
924 pub fn str(&self) -> &'
static str {
926 ReferenceType
::Direct
=> "direct",
927 ReferenceType
::Symbolic
=> "symbolic",
931 /// Convert a raw git_reference_t to a ReferenceType.
932 pub fn from_raw(raw
: raw
::git_reference_t
) -> Option
<ReferenceType
> {
934 raw
::GIT_REFERENCE_DIRECT
=> Some(ReferenceType
::Direct
),
935 raw
::GIT_REFERENCE_SYMBOLIC
=> Some(ReferenceType
::Symbolic
),
941 impl fmt
::Display
for ReferenceType
{
942 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
948 /// Converts a raw configuration level to a ConfigLevel
949 pub fn from_raw(raw
: raw
::git_config_level_t
) -> ConfigLevel
{
951 raw
::GIT_CONFIG_LEVEL_PROGRAMDATA
=> ConfigLevel
::ProgramData
,
952 raw
::GIT_CONFIG_LEVEL_SYSTEM
=> ConfigLevel
::System
,
953 raw
::GIT_CONFIG_LEVEL_XDG
=> ConfigLevel
::XDG
,
954 raw
::GIT_CONFIG_LEVEL_GLOBAL
=> ConfigLevel
::Global
,
955 raw
::GIT_CONFIG_LEVEL_LOCAL
=> ConfigLevel
::Local
,
956 raw
::GIT_CONFIG_LEVEL_APP
=> ConfigLevel
::App
,
957 raw
::GIT_CONFIG_HIGHEST_LEVEL
=> ConfigLevel
::Highest
,
958 n
=> panic
!("unknown config level: {}", n
),
963 impl SubmoduleIgnore
{
964 /// Converts a [`raw::git_submodule_ignore_t`] to a [`SubmoduleIgnore`]
965 pub fn from_raw(raw
: raw
::git_submodule_ignore_t
) -> Self {
967 raw
::GIT_SUBMODULE_IGNORE_UNSPECIFIED
=> SubmoduleIgnore
::Unspecified
,
968 raw
::GIT_SUBMODULE_IGNORE_NONE
=> SubmoduleIgnore
::None
,
969 raw
::GIT_SUBMODULE_IGNORE_UNTRACKED
=> SubmoduleIgnore
::Untracked
,
970 raw
::GIT_SUBMODULE_IGNORE_DIRTY
=> SubmoduleIgnore
::Dirty
,
971 raw
::GIT_SUBMODULE_IGNORE_ALL
=> SubmoduleIgnore
::All
,
972 n
=> panic
!("unknown submodule ignore rule: {}", n
),
977 impl SubmoduleUpdate
{
978 /// Converts a [`raw::git_submodule_update_t`] to a [`SubmoduleUpdate`]
979 pub fn from_raw(raw
: raw
::git_submodule_update_t
) -> Self {
981 raw
::GIT_SUBMODULE_UPDATE_CHECKOUT
=> SubmoduleUpdate
::Checkout
,
982 raw
::GIT_SUBMODULE_UPDATE_REBASE
=> SubmoduleUpdate
::Rebase
,
983 raw
::GIT_SUBMODULE_UPDATE_MERGE
=> SubmoduleUpdate
::Merge
,
984 raw
::GIT_SUBMODULE_UPDATE_NONE
=> SubmoduleUpdate
::None
,
985 raw
::GIT_SUBMODULE_UPDATE_DEFAULT
=> SubmoduleUpdate
::Default
,
986 n
=> panic
!("unknown submodule update strategy: {}", n
),
992 /// Status flags for a single file
994 /// A combination of these values will be returned to indicate the status of
995 /// a file. Status compares the working directory, the index, and the
996 /// current HEAD of the repository. The `STATUS_INDEX_*` set of flags
997 /// represents the status of file in the index relative to the HEAD, and the
998 /// `STATUS_WT_*` set of flags represent the status of the file in the
999 /// working directory relative to the index.
1000 pub struct Status
: u32 {
1001 #[allow(missing_docs)]
1002 const CURRENT
= raw
::GIT_STATUS_CURRENT
as u32;
1004 #[allow(missing_docs)]
1005 const INDEX_NEW
= raw
::GIT_STATUS_INDEX_NEW
as u32;
1006 #[allow(missing_docs)]
1007 const INDEX_MODIFIED
= raw
::GIT_STATUS_INDEX_MODIFIED
as u32;
1008 #[allow(missing_docs)]
1009 const INDEX_DELETED
= raw
::GIT_STATUS_INDEX_DELETED
as u32;
1010 #[allow(missing_docs)]
1011 const INDEX_RENAMED
= raw
::GIT_STATUS_INDEX_RENAMED
as u32;
1012 #[allow(missing_docs)]
1013 const INDEX_TYPECHANGE
= raw
::GIT_STATUS_INDEX_TYPECHANGE
as u32;
1015 #[allow(missing_docs)]
1016 const WT_NEW
= raw
::GIT_STATUS_WT_NEW
as u32;
1017 #[allow(missing_docs)]
1018 const WT_MODIFIED
= raw
::GIT_STATUS_WT_MODIFIED
as u32;
1019 #[allow(missing_docs)]
1020 const WT_DELETED
= raw
::GIT_STATUS_WT_DELETED
as u32;
1021 #[allow(missing_docs)]
1022 const WT_TYPECHANGE
= raw
::GIT_STATUS_WT_TYPECHANGE
as u32;
1023 #[allow(missing_docs)]
1024 const WT_RENAMED
= raw
::GIT_STATUS_WT_RENAMED
as u32;
1026 #[allow(missing_docs)]
1027 const IGNORED
= raw
::GIT_STATUS_IGNORED
as u32;
1028 #[allow(missing_docs)]
1029 const CONFLICTED
= raw
::GIT_STATUS_CONFLICTED
as u32;
1034 is_bit_set
!(is_index_new
, Status
::INDEX_NEW
);
1035 is_bit_set
!(is_index_modified
, Status
::INDEX_MODIFIED
);
1036 is_bit_set
!(is_index_deleted
, Status
::INDEX_DELETED
);
1037 is_bit_set
!(is_index_renamed
, Status
::INDEX_RENAMED
);
1038 is_bit_set
!(is_index_typechange
, Status
::INDEX_TYPECHANGE
);
1039 is_bit_set
!(is_wt_new
, Status
::WT_NEW
);
1040 is_bit_set
!(is_wt_modified
, Status
::WT_MODIFIED
);
1041 is_bit_set
!(is_wt_deleted
, Status
::WT_DELETED
);
1042 is_bit_set
!(is_wt_typechange
, Status
::WT_TYPECHANGE
);
1043 is_bit_set
!(is_wt_renamed
, Status
::WT_RENAMED
);
1044 is_bit_set
!(is_ignored
, Status
::IGNORED
);
1045 is_bit_set
!(is_conflicted
, Status
::CONFLICTED
);
1049 /// Mode options for RepositoryInitOptions
1050 pub struct RepositoryInitMode
: u32 {
1051 /// Use permissions configured by umask - the default
1052 const SHARED_UMASK
= raw
::GIT_REPOSITORY_INIT_SHARED_UMASK
as u32;
1053 /// Use `--shared=group` behavior, chmod'ing the new repo to be
1054 /// group writable and \"g+sx\" for sticky group assignment
1055 const SHARED_GROUP
= raw
::GIT_REPOSITORY_INIT_SHARED_GROUP
as u32;
1056 /// Use `--shared=all` behavior, adding world readability.
1057 const SHARED_ALL
= raw
::GIT_REPOSITORY_INIT_SHARED_ALL
as u32;
1061 impl RepositoryInitMode
{
1062 is_bit_set
!(is_shared_umask
, RepositoryInitMode
::SHARED_UMASK
);
1063 is_bit_set
!(is_shared_group
, RepositoryInitMode
::SHARED_GROUP
);
1064 is_bit_set
!(is_shared_all
, RepositoryInitMode
::SHARED_ALL
);
1067 /// What type of change is described by a `DiffDelta`?
1068 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1072 /// Entry does not exist in old version
1074 /// Entry does not exist in new version
1076 /// Entry content changed between old and new
1078 /// Entry was renamed between old and new
1080 /// Entry was copied from another old entry
1082 /// Entry is ignored item in workdir
1084 /// Entry is untracked item in workdir
1086 /// Type of entry changed between old and new
1088 /// Entry is unreadable
1090 /// Entry in the index is conflicted
1094 /// Valid modes for index and tree entries.
1095 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1103 /// Group writable blob. Obsolete mode kept for compatibility reasons
1113 impl From
<FileMode
> for i32 {
1114 fn from(mode
: FileMode
) -> i32 {
1116 FileMode
::Unreadable
=> raw
::GIT_FILEMODE_UNREADABLE
as i32,
1117 FileMode
::Tree
=> raw
::GIT_FILEMODE_TREE
as i32,
1118 FileMode
::Blob
=> raw
::GIT_FILEMODE_BLOB
as i32,
1119 FileMode
::BlobGroupWritable
=> raw
::GIT_FILEMODE_BLOB_GROUP_WRITABLE
as i32,
1120 FileMode
::BlobExecutable
=> raw
::GIT_FILEMODE_BLOB_EXECUTABLE
as i32,
1121 FileMode
::Link
=> raw
::GIT_FILEMODE_LINK
as i32,
1122 FileMode
::Commit
=> raw
::GIT_FILEMODE_COMMIT
as i32,
1127 impl From
<FileMode
> for u32 {
1128 fn from(mode
: FileMode
) -> u32 {
1130 FileMode
::Unreadable
=> raw
::GIT_FILEMODE_UNREADABLE
as u32,
1131 FileMode
::Tree
=> raw
::GIT_FILEMODE_TREE
as u32,
1132 FileMode
::Blob
=> raw
::GIT_FILEMODE_BLOB
as u32,
1133 FileMode
::BlobGroupWritable
=> raw
::GIT_FILEMODE_BLOB_GROUP_WRITABLE
as u32,
1134 FileMode
::BlobExecutable
=> raw
::GIT_FILEMODE_BLOB_EXECUTABLE
as u32,
1135 FileMode
::Link
=> raw
::GIT_FILEMODE_LINK
as u32,
1136 FileMode
::Commit
=> raw
::GIT_FILEMODE_COMMIT
as u32,
1142 /// Return codes for submodule status.
1144 /// A combination of these flags will be returned to describe the status of a
1145 /// submodule. Depending on the "ignore" property of the submodule, some of
1146 /// the flags may never be returned because they indicate changes that are
1147 /// supposed to be ignored.
1149 /// Submodule info is contained in 4 places: the HEAD tree, the index, config
1150 /// files (both .git/config and .gitmodules), and the working directory. Any
1151 /// or all of those places might be missing information about the submodule
1152 /// depending on what state the repo is in. We consider all four places to
1153 /// build the combination of status flags.
1155 /// There are four values that are not really status, but give basic info
1156 /// about what sources of submodule data are available. These will be
1157 /// returned even if ignore is set to "ALL".
1159 /// * IN_HEAD - superproject head contains submodule
1160 /// * IN_INDEX - superproject index contains submodule
1161 /// * IN_CONFIG - superproject gitmodules has submodule
1162 /// * IN_WD - superproject workdir has submodule
1164 /// The following values will be returned so long as ignore is not "ALL".
1166 /// * INDEX_ADDED - in index, not in head
1167 /// * INDEX_DELETED - in head, not in index
1168 /// * INDEX_MODIFIED - index and head don't match
1169 /// * WD_UNINITIALIZED - workdir contains empty directory
1170 /// * WD_ADDED - in workdir, not index
1171 /// * WD_DELETED - in index, not workdir
1172 /// * WD_MODIFIED - index and workdir head don't match
1174 /// The following can only be returned if ignore is "NONE" or "UNTRACKED".
1176 /// * WD_INDEX_MODIFIED - submodule workdir index is dirty
1177 /// * WD_WD_MODIFIED - submodule workdir has modified files
1179 /// Lastly, the following will only be returned for ignore "NONE".
1181 /// * WD_UNTRACKED - workdir contains untracked files
1182 pub struct SubmoduleStatus
: u32 {
1183 #[allow(missing_docs)]
1184 const IN_HEAD
= raw
::GIT_SUBMODULE_STATUS_IN_HEAD
as u32;
1185 #[allow(missing_docs)]
1186 const IN_INDEX
= raw
::GIT_SUBMODULE_STATUS_IN_INDEX
as u32;
1187 #[allow(missing_docs)]
1188 const IN_CONFIG
= raw
::GIT_SUBMODULE_STATUS_IN_CONFIG
as u32;
1189 #[allow(missing_docs)]
1190 const IN_WD
= raw
::GIT_SUBMODULE_STATUS_IN_WD
as u32;
1191 #[allow(missing_docs)]
1192 const INDEX_ADDED
= raw
::GIT_SUBMODULE_STATUS_INDEX_ADDED
as u32;
1193 #[allow(missing_docs)]
1194 const INDEX_DELETED
= raw
::GIT_SUBMODULE_STATUS_INDEX_DELETED
as u32;
1195 #[allow(missing_docs)]
1196 const INDEX_MODIFIED
= raw
::GIT_SUBMODULE_STATUS_INDEX_MODIFIED
as u32;
1197 #[allow(missing_docs)]
1198 const WD_UNINITIALIZED
=
1199 raw
::GIT_SUBMODULE_STATUS_WD_UNINITIALIZED
as u32;
1200 #[allow(missing_docs)]
1201 const WD_ADDED
= raw
::GIT_SUBMODULE_STATUS_WD_ADDED
as u32;
1202 #[allow(missing_docs)]
1203 const WD_DELETED
= raw
::GIT_SUBMODULE_STATUS_WD_DELETED
as u32;
1204 #[allow(missing_docs)]
1205 const WD_MODIFIED
= raw
::GIT_SUBMODULE_STATUS_WD_MODIFIED
as u32;
1206 #[allow(missing_docs)]
1207 const WD_INDEX_MODIFIED
=
1208 raw
::GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED
as u32;
1209 #[allow(missing_docs)]
1210 const WD_WD_MODIFIED
= raw
::GIT_SUBMODULE_STATUS_WD_WD_MODIFIED
as u32;
1211 #[allow(missing_docs)]
1212 const WD_UNTRACKED
= raw
::GIT_SUBMODULE_STATUS_WD_UNTRACKED
as u32;
1216 impl SubmoduleStatus
{
1217 is_bit_set
!(is_in_head
, SubmoduleStatus
::IN_HEAD
);
1218 is_bit_set
!(is_in_index
, SubmoduleStatus
::IN_INDEX
);
1219 is_bit_set
!(is_in_config
, SubmoduleStatus
::IN_CONFIG
);
1220 is_bit_set
!(is_in_wd
, SubmoduleStatus
::IN_WD
);
1221 is_bit_set
!(is_index_added
, SubmoduleStatus
::INDEX_ADDED
);
1222 is_bit_set
!(is_index_deleted
, SubmoduleStatus
::INDEX_DELETED
);
1223 is_bit_set
!(is_index_modified
, SubmoduleStatus
::INDEX_MODIFIED
);
1224 is_bit_set
!(is_wd_uninitialized
, SubmoduleStatus
::WD_UNINITIALIZED
);
1225 is_bit_set
!(is_wd_added
, SubmoduleStatus
::WD_ADDED
);
1226 is_bit_set
!(is_wd_deleted
, SubmoduleStatus
::WD_DELETED
);
1227 is_bit_set
!(is_wd_modified
, SubmoduleStatus
::WD_MODIFIED
);
1228 is_bit_set
!(is_wd_wd_modified
, SubmoduleStatus
::WD_WD_MODIFIED
);
1229 is_bit_set
!(is_wd_untracked
, SubmoduleStatus
::WD_UNTRACKED
);
1232 /// Submodule ignore values
1234 /// These values represent settings for the `submodule.$name.ignore`
1235 /// configuration value which says how deeply to look at the working
1236 /// directory when getting the submodule status.
1237 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1238 pub enum SubmoduleIgnore
{
1239 /// Use the submodule's configuration
1241 /// Any change or untracked file is considered dirty
1243 /// Only dirty if tracked files have changed
1245 /// Only dirty if HEAD has moved
1251 /// Submodule update values
1253 /// These values represent settings for the `submodule.$name.update`
1254 /// configuration value which says how to handle `git submodule update`
1255 /// for this submodule. The value is usually set in the ".gitmodules"
1256 /// file and copied to ".git/config" when the submodule is initialized.
1257 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1258 pub enum SubmoduleUpdate
{
1259 /// The default; when a submodule is updated, checkout the new detached
1260 /// HEAD to the submodule directory.
1262 /// Update by rebasing the current checked out branch onto the commit from
1263 /// the superproject.
1265 /// Update by merging the commit in the superproject into the current
1266 /// checkout out branch of the submodule.
1268 /// Do not update this submodule even when the commit in the superproject
1271 /// Not used except as static initializer when we don't want any particular
1272 /// update rule to be specified.
1278 pub struct PathspecFlags
: u32 {
1279 /// Use the default pathspec matching configuration.
1280 const DEFAULT
= raw
::GIT_PATHSPEC_DEFAULT
as u32;
1281 /// Force matching to ignore case, otherwise matching will use native
1282 /// case sensitivity of the platform filesystem.
1283 const IGNORE_CASE
= raw
::GIT_PATHSPEC_IGNORE_CASE
as u32;
1284 /// Force case sensitive matches, otherwise match will use the native
1285 /// case sensitivity of the platform filesystem.
1286 const USE_CASE
= raw
::GIT_PATHSPEC_USE_CASE
as u32;
1287 /// Disable glob patterns and just use simple string comparison for
1289 const NO_GLOB
= raw
::GIT_PATHSPEC_NO_GLOB
as u32;
1290 /// Means that match functions return the error code `NotFound` if no
1291 /// matches are found. By default no matches is a success.
1292 const NO_MATCH_ERROR
= raw
::GIT_PATHSPEC_NO_MATCH_ERROR
as u32;
1293 /// Means that the list returned should track which patterns matched
1294 /// which files so that at the end of the match we can identify patterns
1295 /// that did not match any files.
1296 const FIND_FAILURES
= raw
::GIT_PATHSPEC_FIND_FAILURES
as u32;
1297 /// Means that the list returned does not need to keep the actual
1298 /// matching filenames. Use this to just test if there were any matches
1299 /// at all or in combination with `PATHSPEC_FAILURES` to validate a
1301 const FAILURES_ONLY
= raw
::GIT_PATHSPEC_FAILURES_ONLY
as u32;
1305 impl PathspecFlags
{
1306 is_bit_set
!(is_default
, PathspecFlags
::DEFAULT
);
1307 is_bit_set
!(is_ignore_case
, PathspecFlags
::IGNORE_CASE
);
1308 is_bit_set
!(is_use_case
, PathspecFlags
::USE_CASE
);
1309 is_bit_set
!(is_no_glob
, PathspecFlags
::NO_GLOB
);
1310 is_bit_set
!(is_no_match_error
, PathspecFlags
::NO_MATCH_ERROR
);
1311 is_bit_set
!(is_find_failures
, PathspecFlags
::FIND_FAILURES
);
1312 is_bit_set
!(is_failures_only
, PathspecFlags
::FAILURES_ONLY
);
1315 impl Default
for PathspecFlags
{
1316 fn default() -> Self {
1317 PathspecFlags
::DEFAULT
1322 /// Types of notifications emitted from checkouts.
1323 pub struct CheckoutNotificationType
: u32 {
1324 /// Notification about a conflict.
1325 const CONFLICT
= raw
::GIT_CHECKOUT_NOTIFY_CONFLICT
as u32;
1326 /// Notification about a dirty file.
1327 const DIRTY
= raw
::GIT_CHECKOUT_NOTIFY_DIRTY
as u32;
1328 /// Notification about an updated file.
1329 const UPDATED
= raw
::GIT_CHECKOUT_NOTIFY_UPDATED
as u32;
1330 /// Notification about an untracked file.
1331 const UNTRACKED
= raw
::GIT_CHECKOUT_NOTIFY_UNTRACKED
as u32;
1332 /// Notification about an ignored file.
1333 const IGNORED
= raw
::GIT_CHECKOUT_NOTIFY_IGNORED
as u32;
1337 impl CheckoutNotificationType
{
1338 is_bit_set
!(is_conflict
, CheckoutNotificationType
::CONFLICT
);
1339 is_bit_set
!(is_dirty
, CheckoutNotificationType
::DIRTY
);
1340 is_bit_set
!(is_updated
, CheckoutNotificationType
::UPDATED
);
1341 is_bit_set
!(is_untracked
, CheckoutNotificationType
::UNTRACKED
);
1342 is_bit_set
!(is_ignored
, CheckoutNotificationType
::IGNORED
);
1345 /// Possible output formats for diff data
1346 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1347 pub enum DiffFormat
{
1350 /// just the headers of the patch
1352 /// like git diff --raw
1354 /// like git diff --name-only
1356 /// like git diff --name-status
1358 /// git diff as used by git patch-id
1363 /// Formatting options for diff stats
1364 pub struct DiffStatsFormat
: raw
::git_diff_stats_format_t
{
1365 /// Don't generate any stats
1366 const NONE
= raw
::GIT_DIFF_STATS_NONE
;
1367 /// Equivalent of `--stat` in git
1368 const FULL
= raw
::GIT_DIFF_STATS_FULL
;
1369 /// Equivalent of `--shortstat` in git
1370 const SHORT
= raw
::GIT_DIFF_STATS_SHORT
;
1371 /// Equivalent of `--numstat` in git
1372 const NUMBER
= raw
::GIT_DIFF_STATS_NUMBER
;
1373 /// Extended header information such as creations, renames and mode
1374 /// changes, equivalent of `--summary` in git
1375 const INCLUDE_SUMMARY
= raw
::GIT_DIFF_STATS_INCLUDE_SUMMARY
;
1379 impl DiffStatsFormat
{
1380 is_bit_set
!(is_none
, DiffStatsFormat
::NONE
);
1381 is_bit_set
!(is_full
, DiffStatsFormat
::FULL
);
1382 is_bit_set
!(is_short
, DiffStatsFormat
::SHORT
);
1383 is_bit_set
!(is_number
, DiffStatsFormat
::NUMBER
);
1384 is_bit_set
!(is_include_summary
, DiffStatsFormat
::INCLUDE_SUMMARY
);
1387 /// Automatic tag following options.
1388 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1389 pub enum AutotagOption
{
1390 /// Use the setting from the remote's configuration
1392 /// Ask the server for tags pointing to objects we're already downloading
1394 /// Don't ask for any tags beyond the refspecs
1396 /// Ask for all the tags
1400 /// Configuration for how pruning is done on a fetch
1401 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1402 pub enum FetchPrune
{
1403 /// Use the setting from the configuration
1405 /// Force pruning on
1407 /// Force pruning off
1411 #[allow(missing_docs)]
1412 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1413 pub enum StashApplyProgress
{
1416 /// Loading the stashed data from the object database
1418 /// The stored index is being analyzed
1420 /// The modified files are being analyzed
1422 /// The untracked and ignored files are being analyzed
1424 /// The untracked files are being written to disk
1426 /// The modified files are being written to disk
1428 /// The stash was applied successfully
1433 #[allow(missing_docs)]
1434 pub struct StashApplyFlags
: u32 {
1435 #[allow(missing_docs)]
1436 const DEFAULT
= raw
::GIT_STASH_APPLY_DEFAULT
as u32;
1437 /// Try to reinstate not only the working tree's changes,
1438 /// but also the index's changes.
1439 const REINSTATE_INDEX
= raw
::GIT_STASH_APPLY_REINSTATE_INDEX
as u32;
1443 impl StashApplyFlags
{
1444 is_bit_set
!(is_default
, StashApplyFlags
::DEFAULT
);
1445 is_bit_set
!(is_reinstate_index
, StashApplyFlags
::REINSTATE_INDEX
);
1448 impl Default
for StashApplyFlags
{
1449 fn default() -> Self {
1450 StashApplyFlags
::DEFAULT
1455 #[allow(missing_docs)]
1456 pub struct StashFlags
: u32 {
1457 #[allow(missing_docs)]
1458 const DEFAULT
= raw
::GIT_STASH_DEFAULT
as u32;
1459 /// All changes already added to the index are left intact in
1460 /// the working directory
1461 const KEEP_INDEX
= raw
::GIT_STASH_KEEP_INDEX
as u32;
1462 /// All untracked files are also stashed and then cleaned up
1463 /// from the working directory
1464 const INCLUDE_UNTRACKED
= raw
::GIT_STASH_INCLUDE_UNTRACKED
as u32;
1465 /// All ignored files are also stashed and then cleaned up from
1466 /// the working directory
1467 const INCLUDE_IGNORED
= raw
::GIT_STASH_INCLUDE_IGNORED
as u32;
1468 /// All changes in the index and working directory are left intact
1469 const KEEP_ALL
= raw
::GIT_STASH_KEEP_ALL
as u32;
1474 is_bit_set
!(is_default
, StashFlags
::DEFAULT
);
1475 is_bit_set
!(is_keep_index
, StashFlags
::KEEP_INDEX
);
1476 is_bit_set
!(is_include_untracked
, StashFlags
::INCLUDE_UNTRACKED
);
1477 is_bit_set
!(is_include_ignored
, StashFlags
::INCLUDE_IGNORED
);
1480 impl Default
for StashFlags
{
1481 fn default() -> Self {
1487 #[allow(missing_docs)]
1488 pub struct AttrCheckFlags
: u32 {
1489 /// Check the working directory, then the index.
1490 const FILE_THEN_INDEX
= raw
::GIT_ATTR_CHECK_FILE_THEN_INDEX
as u32;
1491 /// Check the index, then the working directory.
1492 const INDEX_THEN_FILE
= raw
::GIT_ATTR_CHECK_INDEX_THEN_FILE
as u32;
1493 /// Check the index only.
1494 const INDEX_ONLY
= raw
::GIT_ATTR_CHECK_INDEX_ONLY
as u32;
1495 /// Do not use the system gitattributes file.
1496 const NO_SYSTEM
= raw
::GIT_ATTR_CHECK_NO_SYSTEM
as u32;
1500 impl Default
for AttrCheckFlags
{
1501 fn default() -> Self {
1502 AttrCheckFlags
::FILE_THEN_INDEX
1507 #[allow(missing_docs)]
1508 pub struct DiffFlags
: u32 {
1509 /// File(s) treated as binary data.
1510 const BINARY
= raw
::GIT_DIFF_FLAG_BINARY
as u32;
1511 /// File(s) treated as text data.
1512 const NOT_BINARY
= raw
::GIT_DIFF_FLAG_NOT_BINARY
as u32;
1513 /// `id` value is known correct.
1514 const VALID_ID
= raw
::GIT_DIFF_FLAG_VALID_ID
as u32;
1515 /// File exists at this side of the delta.
1516 const EXISTS
= raw
::GIT_DIFF_FLAG_EXISTS
as u32;
1521 is_bit_set
!(is_binary
, DiffFlags
::BINARY
);
1522 is_bit_set
!(is_not_binary
, DiffFlags
::NOT_BINARY
);
1523 is_bit_set
!(has_valid_id
, DiffFlags
::VALID_ID
);
1524 is_bit_set
!(exists
, DiffFlags
::EXISTS
);
1528 /// Options for [`Reference::normalize_name`].
1529 pub struct ReferenceFormat
: u32 {
1530 /// No particular normalization.
1531 const NORMAL
= raw
::GIT_REFERENCE_FORMAT_NORMAL
as u32;
1532 /// Control whether one-level refname are accepted (i.e., refnames that
1533 /// do not contain multiple `/`-separated components). Those are
1534 /// expected to be written only using uppercase letters and underscore
1535 /// (e.g. `HEAD`, `FETCH_HEAD`).
1536 const ALLOW_ONELEVEL
= raw
::GIT_REFERENCE_FORMAT_ALLOW_ONELEVEL
as u32;
1537 /// Interpret the provided name as a reference pattern for a refspec (as
1538 /// used with remote repositories). If this option is enabled, the name
1539 /// is allowed to contain a single `*` in place of a full pathname
1540 /// components (e.g., `foo/*/bar` but not `foo/bar*`).
1541 const REFSPEC_PATTERN
= raw
::GIT_REFERENCE_FORMAT_REFSPEC_PATTERN
as u32;
1542 /// Interpret the name as part of a refspec in shorthand form so the
1543 /// `ALLOW_ONELEVEL` naming rules aren't enforced and `main` becomes a
1545 const REFSPEC_SHORTHAND
= raw
::GIT_REFERENCE_FORMAT_REFSPEC_SHORTHAND
as u32;
1549 impl ReferenceFormat
{
1550 is_bit_set
!(is_allow_onelevel
, ReferenceFormat
::ALLOW_ONELEVEL
);
1551 is_bit_set
!(is_refspec_pattern
, ReferenceFormat
::REFSPEC_PATTERN
);
1552 is_bit_set
!(is_refspec_shorthand
, ReferenceFormat
::REFSPEC_SHORTHAND
);
1555 impl Default
for ReferenceFormat
{
1556 fn default() -> Self {
1557 ReferenceFormat
::NORMAL
1563 use super::{FileMode, ObjectType}
;
1567 assert_eq
!(ObjectType
::Blob
.str(), "blob");
1568 assert_eq
!(ObjectType
::from_str("blob"), Some(ObjectType
::Blob
));
1569 assert
!(ObjectType
::Blob
.is_loose());
1573 fn convert_filemode() {
1574 assert_eq
!(i32::from(FileMode
::Blob
), 0o100644);
1575 assert_eq
!(i32::from(FileMode
::BlobGroupWritable
), 0o100664);
1576 assert_eq
!(i32::from(FileMode
::BlobExecutable
), 0o100755);
1577 assert_eq
!(u32::from(FileMode
::Blob
), 0o100644);
1578 assert_eq
!(u32::from(FileMode
::BlobGroupWritable
), 0o100664);
1579 assert_eq
!(u32::from(FileMode
::BlobExecutable
), 0o100755);