Merge branch 'new-error-handling' into development

Conflicts:
	.travis.yml
	include/git2/diff.h
	src/config_file.c
	src/diff.c
	src/diff_output.c
	src/mwindow.c
	src/path.c
	tests-clar/clar_helpers.c
	tests-clar/object/tree/frompath.c
	tests/t00-core.c
	tests/t03-objwrite.c
	tests/t08-tag.c
	tests/t10-refs.c
	tests/t12-repo.c
	tests/t18-status.c
	tests/test_helpers.c
	tests/test_main.c
This commit is contained in:
Vicent Martí
2012-05-02 15:59:02 -07:00
281 changed files with 12128 additions and 7327 deletions
+113 -6
View File
@@ -4,12 +4,119 @@
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_branch_h__
#define INCLUDE_branch_h__
#ifndef INCLUDE_git_branch_h__
#define INCLUDE_git_branch_h__
struct git_branch {
char *remote; /* TODO: Make this a git_remote */
char *merge;
};
#include "common.h"
#include "types.h"
/**
* @file git2/branch.h
* @brief Git branch parsing routines
* @defgroup git_branch Git branch management
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
/**
* 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.
*
* @param oid_out Pointer where to store the OID of the target commit.
*
* @param repo Repository where to store the branch.
*
* @param branch_name Name for the branch; this name is
* validated for consistency. It should also not conflict with
* an already existing branch name.
*
* @param target Object to which this branch should point. This object
* must belong to the given `repo` and can either be a git_commit or a
* git_tag. When a git_tag is being passed, it should be dereferencable
* to a git_commit which oid will be used as the target of the branch.
*
* @param force Overwrite existing branch.
*
* @return GIT_SUCCESS or an error code.
* A proper reference is written in the refs/heads namespace
* pointing to the provided target commit.
*/
GIT_EXTERN(int) git_branch_create(
git_oid *oid_out,
git_repository *repo,
const char *branch_name,
const git_object *target,
int force);
/**
* Delete an existing branch reference.
*
* @param repo Repository where lives the branch.
*
* @param branch_name Name of the branch to be deleted;
* this name is validated for consistency.
*
* @param branch_type Type of the considered branch. This should
* be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE.
*
* @return GIT_SUCCESS on success, GIT_ENOTFOUND if the branch
* doesn't exist or an error code.
*/
GIT_EXTERN(int) git_branch_delete(
git_repository *repo,
const char *branch_name,
git_branch_type branch_type);
/**
* Fill a list with all the branches in the Repository
*
* The string array will be filled with the names of the
* matching branches; these values are owned by the user and
* should be free'd manually when no longer needed, using
* `git_strarray_free`.
*
* @param branch_names Pointer to a git_strarray structure
* where the branch names will be stored.
*
* @param repo Repository where to find the branches.
*
* @param list_flags Filtering flags for the branch
* listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE
* or a combination of the two.
*
* @return GIT_SUCCESS or an error code.
*/
GIT_EXTERN(int) git_branch_list(
git_strarray *branch_names,
git_repository *repo,
unsigned int list_flags);
/**
* Move/rename an existing branch reference.
*
* @param repo Repository where lives the branch.
*
* @param old_branch_name Current name of the branch to be moved;
* this name is validated for consistency.
*
* @param new_branch_name Target name of the branch once the move
* is performed; this name is validated for consistency.
*
* @param force Overwrite existing branch.
*
* @return GIT_SUCCESS on success, GIT_ENOTFOUND if the branch
* doesn't exist or an error code.
*/
GIT_EXTERN(int) git_branch_move(
git_repository *repo,
const char *old_branch_name,
const char *new_branch_name,
int force);
/** @} */
GIT_END_DECL
#endif
+1
View File
@@ -87,6 +87,7 @@ typedef struct {
} git_strarray;
GIT_EXTERN(void) git_strarray_free(git_strarray *array);
GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src);
/**
* Return the version of the libgit2 library
+20 -21
View File
@@ -39,7 +39,9 @@ enum {
GIT_DIFF_IGNORE_SUBMODULES = (1 << 5),
GIT_DIFF_PATIENCE = (1 << 6),
GIT_DIFF_INCLUDE_IGNORED = (1 << 7),
GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8)
GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8),
GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9),
GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10),
};
/**
@@ -152,19 +154,22 @@ typedef int (*git_diff_hunk_fn)(
* Line origin constants.
*
* These values describe where a line came from and will be passed to
* the git_diff_line_fn when iterating over a diff. There are some
* the git_diff_data_fn when iterating over a diff. There are some
* special origin contants at the end that are used for the text
* output callbacks to demarcate lines that are actually part of
* the file or hunk headers.
*/
enum {
/* these values will be sent to `git_diff_line_fn` along with the line */
/* these values will be sent to `git_diff_data_fn` along with the line */
GIT_DIFF_LINE_CONTEXT = ' ',
GIT_DIFF_LINE_ADDITION = '+',
GIT_DIFF_LINE_DELETION = '-',
GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< LF was added at end of file */
GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */
/* these values will only be sent to a `git_diff_output_fn` */
/* these values will only be sent to a `git_diff_data_fn` when the content
* of a diff is being formatted (eg. through git_diff_print_patch() or
* git_diff_print_compact(), for instance).
*/
GIT_DIFF_LINE_FILE_HDR = 'F',
GIT_DIFF_LINE_HUNK_HDR = 'H',
GIT_DIFF_LINE_BINARY = 'B'
@@ -172,25 +177,19 @@ enum {
/**
* When iterating over a diff, callback that will be made per text diff
* line.
*/
typedef int (*git_diff_line_fn)(
void *cb_data,
git_diff_delta *delta,
char line_origin, /**< GIT_DIFF_LINE_... value from above */
const char *content,
size_t content_len);
/**
* line. In this context, the provided range will be NULL.
*
* When printing a diff, callback that will be made to output each line
* of text. This uses some extra GIT_DIFF_LINE_... constants for output
* of lines of file and hunk headers.
*/
typedef int (*git_diff_output_fn)(
typedef int (*git_diff_data_fn)(
void *cb_data,
git_diff_delta *delta,
git_diff_range *range,
char line_origin, /**< GIT_DIFF_LINE_... value from above */
const char *formatted_output);
const char *content,
size_t content_len);
/** @name Diff List Generator Functions
*
@@ -309,7 +308,7 @@ GIT_EXTERN(int) git_diff_foreach(
void *cb_data,
git_diff_file_fn file_cb,
git_diff_hunk_fn hunk_cb,
git_diff_line_fn line_cb);
git_diff_data_fn line_cb);
/**
* Iterate over a diff generating text output like "git diff --name-status".
@@ -317,7 +316,7 @@ GIT_EXTERN(int) git_diff_foreach(
GIT_EXTERN(int) git_diff_print_compact(
git_diff_list *diff,
void *cb_data,
git_diff_output_fn print_cb);
git_diff_data_fn print_cb);
/**
* Iterate over a diff generating text output like "git diff".
@@ -327,7 +326,7 @@ GIT_EXTERN(int) git_diff_print_compact(
GIT_EXTERN(int) git_diff_print_patch(
git_diff_list *diff,
void *cb_data,
git_diff_output_fn print_cb);
git_diff_data_fn print_cb);
/**@}*/
@@ -345,7 +344,7 @@ GIT_EXTERN(int) git_diff_blobs(
git_diff_options *options,
void *cb_data,
git_diff_hunk_fn hunk_cb,
git_diff_line_fn line_cb);
git_diff_data_fn line_cb);
GIT_END_DECL
+39 -1
View File
@@ -103,7 +103,7 @@ typedef enum {
GIT_EOBJCORRUPTED = -28,
/** The given short oid is ambiguous */
GIT_EAMBIGUOUSOIDPREFIX = -29,
GIT_EAMBIGUOUS = -29,
/** Skip and passthrough the given ODB backend */
GIT_EPASSTHROUGH = -30,
@@ -113,11 +113,34 @@ typedef enum {
/** The buffer is too short to satisfy the request */
GIT_ESHORTBUFFER = -32,
} git_error_t;
typedef struct {
char *message;
int klass;
} git_error;
typedef enum {
GITERR_NOMEMORY,
GITERR_OS,
GITERR_INVALID,
GITERR_REFERENCE,
GITERR_ZLIB,
GITERR_REPOSITORY,
GITERR_CONFIG,
GITERR_REGEX,
GITERR_ODB,
GITERR_INDEX,
GITERR_OBJECT,
GITERR_NET,
GITERR_TAG,
GITERR_TREE,
} git_error_class;
/**
* Return a detailed error string with the latest error
* that occurred in the library.
* @deprecated This will be replaced in the new error handling
* @return a string explaining the error
*/
GIT_EXTERN(const char *) git_lasterror(void);
@@ -129,6 +152,7 @@ GIT_EXTERN(const char *) git_lasterror(void);
* NOTE: This method will be eventually deprecated in favor
* of the new `git_lasterror`.
*
* @deprecated This will be replaced in the new error handling
* @param num The error code to explain
* @return a string explaining the error code
*/
@@ -136,9 +160,23 @@ GIT_EXTERN(const char *) git_strerror(int num);
/**
* Clear the latest library error
* @deprecated This will be replaced in the new error handling
*/
GIT_EXTERN(void) git_clearerror(void);
/**
* Return the last `git_error` object that was generated for the
* current thread or NULL if no error has occurred.
*
* @return A git_error object.
*/
GIT_EXTERN(const git_error *) git_error_last(void);
/**
* Clear the last library error that occurred for this thread.
*/
GIT_EXTERN(void) git_error_clear(void);
/** @} */
GIT_END_DECL
#endif
+45
View File
@@ -23,6 +23,51 @@ typedef struct git_indexer_stats {
typedef struct git_indexer git_indexer;
typedef struct git_indexer_stream git_indexer_stream;
/**
* Create a new streaming indexer instance
*
* @param out where to store the inexer instance
* @param path to the gitdir (metadata directory)
*/
GIT_EXTERN(int) git_indexer_stream_new(git_indexer_stream **out, const char *gitdir);
/**
* Add data to the indexer
*
* @param idx the indexer
* @param data the data to add
* @param size the size of the data
* @param stats stat storage
*/
GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_indexer_stats *stats);
/**
* Finalize the pack and index
*
* Resolve any pending deltas and write out the index file
*
* @param idx the indexer
*/
GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_indexer_stats *stats);
/**
* Get the packfile's hash
*
* A packfile's name is derived from the sorted hashing of all object
* names. This is only correct after the index has been finalized.
*
* @param idx the indexer instance
*/
GIT_EXTERN(const git_oid *) git_indexer_stream_hash(git_indexer_stream *idx);
/**
* Free the indexer and its resources
*
* @param idx the indexer to free
*/
GIT_EXTERN(void) git_indexer_stream_free(git_indexer_stream *idx);
/**
* Create a new indexer instance
+35
View File
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2009-2012 the libgit2 contributors
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_git_merge_h__
#define INCLUDE_git_merge_h__
#include "common.h"
#include "types.h"
#include "oid.h"
/**
* @file git2/merge.h
* @brief Git merge-base routines
* @defgroup git_revwalk Git merge-base routines
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
/**
* Find a merge base between two commits
*
* @param out the OID of a merge base between 'one' and 'two'
* @param repo the repository where the commits exist
* @param one one of the commits
* @param two the other commit
*/
GIT_EXTERN(int) git_merge_base(git_oid *out, git_repository *repo, git_oid *one, git_oid *two);
/** @} */
GIT_END_DECL
#endif
+20
View File
@@ -32,6 +32,17 @@ GIT_BEGIN_DECL
*/
GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name);
/**
* Lookup a reference by name and resolve immediately to OID.
*
* @param oid Pointer to oid to be filled in
* @param repo The repository in which to look up the reference
* @param name The long name for the reference
* @return 0 on success, -1 if name could not be resolved
*/
GIT_EXTERN(int) git_reference_name_to_oid(
git_oid *out, git_repository *repo, const char *name);
/**
* Create a new symbolic reference.
*
@@ -304,6 +315,15 @@ GIT_EXTERN(int) git_reference_reload(git_reference *ref);
*/
GIT_EXTERN(void) git_reference_free(git_reference *ref);
/**
* Compare two references.
*
* @param ref1 The first git_reference
* @param ref2 The second git_reference
* @return GIT_SUCCESS if the same, else a stable but meaningless ordering.
*/
GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
/** @} */
GIT_END_DECL
#endif
+7 -5
View File
@@ -11,6 +11,7 @@
#include "repository.h"
#include "refspec.h"
#include "net.h"
#include "indexer.h"
/**
* @file git2/remote.h
@@ -150,7 +151,7 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void
* @param filename where to store the temproray filename
* @return GIT_SUCCESS or an error code
*/
GIT_EXTERN(int) git_remote_download(char **filename, git_remote *remote);
GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats);
/**
* Check whether the remote is connected
@@ -175,6 +176,9 @@ GIT_EXTERN(void) git_remote_disconnect(git_remote *remote);
/**
* Free the memory associated with a remote
*
* This also disconnects from the remote, if the connection
* has not been closed yet (using git_remote_disconnect).
*
* @param remote the remote to free
*/
GIT_EXTERN(void) git_remote_free(git_remote *remote);
@@ -182,12 +186,10 @@ GIT_EXTERN(void) git_remote_free(git_remote *remote);
/**
* Update the tips to the new state
*
* Make sure that you only call this once you've successfully indexed
* or expanded the packfile.
*
* @param remote the remote to update
* @param cb callback to run on each ref update. 'a' is the old value, 'b' is then new value
*/
GIT_EXTERN(int) git_remote_update_tips(git_remote *remote);
GIT_EXTERN(int) git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, const git_oid *a, const git_oid *b));
/**
* Return whether a string is a valid remote URL
+14
View File
@@ -70,6 +70,20 @@ GIT_EXTERN(int) git_repository_discover(
int across_fs,
const char *ceiling_dirs);
enum {
GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0),
GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1),
};
/**
* Find and open a repository with extended controls.
*/
GIT_EXTERN(int) git_repository_open_ext(
git_repository **repo,
const char *start_path,
uint32_t flags,
const char *ceiling_dirs);
/**
* Free a previously allocated repository
*
+22
View File
@@ -163,6 +163,28 @@ GIT_EXTERN(int) git_revwalk_hide_glob(git_revwalk *walk, const char *glob);
*/
GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk);
/**
* Push the OID pointed to by a reference
*
* The reference must point to a commit.
*
* @param walk the walker being used for the traversal
* @param refname the referece to push
* @return GIT_SUCCESS or an error code
*/
GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname);
/**
* Hide the OID pointed to by a reference
*
* The reference must point to a commit.
*
* @param walk the walker being used for the traversal
* @param refname the referece to hide
* @return GIT_SUCCESS or an error code
*/
GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname);
/**
* Get the next commit from the revision walk.
*
+73
View File
@@ -46,6 +46,79 @@ GIT_BEGIN_DECL
*/
GIT_EXTERN(int) git_status_foreach(git_repository *repo, int (*callback)(const char *, unsigned int, void *), void *payload);
/**
* Select the files on which to report status.
*
* - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This is the
* rough equivalent of `git status --porcelain` where each file
* will receive a callback indicating its status in the index and
* in the workdir.
* - GIT_STATUS_SHOW_INDEX_ONLY will only make callbacks for index
* side of status. The status of the index contents relative to
* the HEAD will be given.
* - GIT_STATUS_SHOW_WORKDIR_ONLY will only make callbacks for the
* workdir side of status, reporting the status of workdir content
* relative to the index.
* - GIT_STATUS_SHOW_INDEX_THEN_WORKDIR behaves like index-only
* followed by workdir-only, causing two callbacks to be issued
* per file (first index then workdir). This is slightly more
* efficient than making separate calls. This makes it easier to
* emulate the output of a plain `git status`.
*/
typedef enum {
GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0,
GIT_STATUS_SHOW_INDEX_ONLY = 1,
GIT_STATUS_SHOW_WORKDIR_ONLY = 2,
GIT_STATUS_SHOW_INDEX_THEN_WORKDIR = 3,
} git_status_show_t;
/**
* Flags to control status callbacks
*
* - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should
* be made on untracked files. These will only be made if the
* workdir files are included in the status "show" option.
* - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should
* get callbacks. Again, these callbacks will only be made if
* the workdir files are included in the status "show" option.
* Right now, there is no option to include all files in
* directories that are ignored completely.
* - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback
* should be made even on unmodified files.
* - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories
* which appear to be submodules should just be skipped over.
* - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the
* contents of untracked directories should be included in the
* status. Normally if an entire directory is new, then just
* the top-level directory will be included (with a trailing
* slash on the entry name). Given this flag, the directory
* itself will not be included, but all the files in it will.
*/
#define GIT_STATUS_OPT_INCLUDE_UNTRACKED (1 << 0)
#define GIT_STATUS_OPT_INCLUDE_IGNORED (1 << 1)
#define GIT_STATUS_OPT_INCLUDE_UNMODIFIED (1 << 2)
#define GIT_STATUS_OPT_EXCLUDE_SUBMODULES (1 << 3)
#define GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS (1 << 4)
/**
* Options to control how callbacks will be made by
* `git_status_foreach_ext()`.
*/
typedef struct {
git_status_show_t show;
unsigned int flags;
git_strarray pathspec;
} git_status_options;
/**
* Gather file status information and run callbacks as requested.
*/
GIT_EXTERN(int) git_status_foreach_ext(
git_repository *repo,
git_status_options *opts,
int (*callback)(const char *, unsigned int, void *),
void *payload);
/**
* Get file status for a single file
*
+103
View File
@@ -0,0 +1,103 @@
/*
* Copyright (C) 2012 the libgit2 contributors
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_git_submodule_h__
#define INCLUDE_git_submodule_h__
#include "common.h"
#include "types.h"
#include "oid.h"
/**
* @file git2/submodule.h
* @brief Git submodule management utilities
* @defgroup git_submodule Git submodule management routines
* @ingroup Git
* @{
*/
GIT_BEGIN_DECL
typedef enum {
GIT_SUBMODULE_UPDATE_CHECKOUT = 0,
GIT_SUBMODULE_UPDATE_REBASE = 1,
GIT_SUBMODULE_UPDATE_MERGE = 2
} git_submodule_update_t;
typedef enum {
GIT_SUBMODULE_IGNORE_ALL = 0, /* never dirty */
GIT_SUBMODULE_IGNORE_DIRTY = 1, /* only dirty if HEAD moved */
GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /* dirty if tracked files change */
GIT_SUBMODULE_IGNORE_NONE = 3 /* any change or untracked == dirty */
} git_submodule_ignore_t;
/**
* Description of submodule
*
* This record describes a submodule found in a repository. There
* should be an entry for every submodule found in the HEAD and for
* every submodule described in .gitmodules. The fields are as follows:
*
* - `name` is the name of the submodule from .gitmodules.
* - `path` is the path to the submodule from the repo working directory.
* It is almost always the same as `name`.
* - `url` is the url for the submodule.
* - `oid` is the HEAD SHA1 for the submodule.
* - `update` is a value from above - see gitmodules(5) update.
* - `ignore` is a value from above - see gitmodules(5) ignore.
* - `fetch_recurse` is 0 or 1 - see gitmodules(5) fetchRecurseSubmodules.
* - `refcount` is for internal use.
*
* If the submodule has been added to .gitmodules but not yet git added,
* then the `oid` will be zero. If the submodule has been deleted, but
* the delete has not been committed yet, then the `oid` will be set, but
* the `url` will be NULL.
*/
typedef struct {
char *name;
char *path;
char *url;
git_oid oid; /* sha1 of submodule HEAD ref or zero if not committed */
git_submodule_update_t update;
git_submodule_ignore_t ignore;
int fetch_recurse;
int refcount;
} git_submodule;
/**
* Iterate over all submodules of a repository.
*
* @param repo The repository
* @param callback Function to be called with the name of each submodule.
* Return a non-zero value to terminate the iteration.
* @param payload Extra data to pass to callback
* @return 0 on success, -1 on error, or non-zero return value of callback
*/
GIT_EXTERN(int) git_submodule_foreach(
git_repository *repo,
int (*callback)(const char *name, void *payload),
void *payload);
/**
* Lookup submodule information by name or path.
*
* Given either the submodule name or path (they are ususally the same),
* this returns a structure describing the submodule. If the submodule
* does not exist, this will return GIT_ENOTFOUND and set the submodule
* pointer to NULL.
*
* @param submodule Pointer to submodule description object pointer..
* @param repo The repository.
* @param name The name of the submodule. Trailing slashes will be ignored.
* @return 0 on success, GIT_ENOTFOUND if submodule does not exist, -1 on error
*/
GIT_EXTERN(int) git_submodule_lookup(
git_submodule **submodule,
git_repository *repo,
const char *name);
/** @} */
GIT_END_DECL
#endif
+15
View File
@@ -274,6 +274,21 @@ GIT_EXTERN(int) git_tag_list_match(
const char *pattern,
git_repository *repo);
/**
* Recursively peel a tag until a non tag git_object
* is met
*
* The retrieved `tag_target` object is owned by the repository
* and should be closed with the `git_object_free` method.
*
* @param tag_target Pointer to the peeled git_object
* @param tag The tag to be processed
* @return GIT_SUCCESS or an error code
*/
GIT_EXTERN(int) git_tag_peel(
git_object **tag_target,
git_tag *tag);
/** @} */
GIT_END_DECL
#endif
+5
View File
@@ -160,6 +160,11 @@ typedef enum {
GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED,
} git_rtype;
/** Basic type of any Git branch. */
typedef enum {
GIT_BRANCH_LOCAL = 1,
GIT_BRANCH_REMOTE = 2,
} git_branch_type;
typedef struct git_refspec git_refspec;
typedef struct git_remote git_remote;