Commit c0e529f3 by Vicent Marti

Merge branch 'arrbee/examples-log' into development

parents bf3ee3cf 406dd556
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
CC = gcc CC = gcc
CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes -Wno-missing-field-initializers CFLAGS = -g -I../include -I../src -Wall -Wextra -Wmissing-prototypes -Wno-missing-field-initializers
LFLAGS = -L../build -lgit2 -lz LFLAGS = -L../build -lgit2 -lz
APPS = general showindex diff rev-list cat-file status APPS = general showindex diff rev-list cat-file status log rev-parse
all: $(APPS) all: $(APPS)
......
This diff is collapsed. Click to expand it.
#include <stdio.h>
#include <git2.h>
#include <stdlib.h>
#include <string.h>
static void check(int error, const char *message, const char *arg)
{
if (!error)
return;
if (arg)
fprintf(stderr, "%s %s (%d)\n", message, arg, error);
else
fprintf(stderr, "%s(%d)\n", message, error);
exit(1);
}
static void usage(const char *message, const char *arg)
{
if (message && arg)
fprintf(stderr, "%s: %s\n", message, arg);
else if (message)
fprintf(stderr, "%s\n", message);
fprintf(stderr, "usage: rev-parse [ --option ] <args>...\n");
exit(1);
}
struct parse_state {
git_repository *repo;
const char *repodir;
int not;
};
static int parse_revision(struct parse_state *ps, const char *revstr)
{
git_revspec rs;
char str[GIT_OID_HEXSZ + 1];
if (!ps->repo) {
if (!ps->repodir)
ps->repodir = ".";
check(git_repository_open_ext(&ps->repo, ps->repodir, 0, NULL),
"Could not open repository from", ps->repodir);
}
check(git_revparse(&rs, ps->repo, revstr), "Could not parse", revstr);
if ((rs.flags & GIT_REVPARSE_SINGLE) != 0) {
git_oid_tostr(str, sizeof(str), git_object_id(rs.from));
printf("%s\n", str);
git_object_free(rs.from);
}
else if ((rs.flags & GIT_REVPARSE_RANGE) != 0) {
git_oid_tostr(str, sizeof(str), git_object_id(rs.to));
printf("%s\n", str);
git_object_free(rs.to);
if ((rs.flags & GIT_REVPARSE_MERGE_BASE) != 0) {
git_oid base;
check(git_merge_base(&base, ps->repo,
git_object_id(rs.from), git_object_id(rs.to)),
"Could not find merge base", revstr);
git_oid_tostr(str, sizeof(str), &base);
printf("%s\n", str);
}
git_oid_tostr(str, sizeof(str), git_object_id(rs.from));
printf("^%s\n", str);
git_object_free(rs.from);
}
else {
check(0, "Invalid results from git_revparse", revstr);
}
return 0;
}
int main(int argc, char *argv[])
{
int i;
char *a;
struct parse_state ps;
git_threads_init();
memset(&ps, 0, sizeof(ps));
for (i = 1; i < argc; ++i) {
a = argv[i];
if (a[0] != '-') {
if (parse_revision(&ps, a) != 0)
break;
} else if (!strcmp(a, "--not"))
ps.not = !ps.not;
else if (!strncmp(a, "--git-dir=", strlen("--git-dir=")))
ps.repodir = a + strlen("--git-dir=");
else
usage("Cannot handle argument", a);
}
git_repository_free(ps.repo);
git_threads_shutdown();
return 0;
}
...@@ -56,5 +56,6 @@ ...@@ -56,5 +56,6 @@
#include "git2/message.h" #include "git2/message.h"
#include "git2/pack.h" #include "git2/pack.h"
#include "git2/stash.h" #include "git2/stash.h"
#include "git2/pathspec.h"
#endif #endif
...@@ -130,6 +130,14 @@ GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit) ...@@ -130,6 +130,14 @@ GIT_EXTERN(const git_signature *) git_commit_committer(const git_commit *commit)
GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit); GIT_EXTERN(const git_signature *) git_commit_author(const git_commit *commit);
/** /**
* Get the full raw text of the commit header.
*
* @param commit a previously loaded commit
* @return the header text of the commit
*/
GIT_EXTERN(const char *) git_commit_raw_header(const git_commit *commit);
/**
* Get the tree pointed to by a commit. * Get the tree pointed to by a commit.
* *
* @param tree_out pointer where to store the tree object * @param tree_out pointer where to store the tree object
......
...@@ -798,6 +798,14 @@ GIT_EXTERN(size_t) git_diff_num_deltas_of_type( ...@@ -798,6 +798,14 @@ GIT_EXTERN(size_t) git_diff_num_deltas_of_type(
git_delta_t type); git_delta_t type);
/** /**
* Check if deltas are sorted case sensitively or insensitively.
*
* @param diff Diff list to check
* @return 0 if case sensitive, 1 if case is ignored
*/
GIT_EXTERN(int) git_diff_is_sorted_icase(const git_diff_list *diff);
/**
* Return the diff delta and patch for an entry in the diff list. * Return the diff delta and patch for an entry in the diff list.
* *
* The `git_diff_patch` is a newly created object contains the text diffs * The `git_diff_patch` is a newly created object contains the text diffs
......
...@@ -138,6 +138,14 @@ typedef enum { ...@@ -138,6 +138,14 @@ typedef enum {
GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2), GIT_INDEX_ADD_CHECK_PATHSPEC = (1u << 2),
} git_index_add_option_t; } git_index_add_option_t;
/**
* Match any index stage.
*
* Some index APIs take a stage to match; pass this value to match
* any entry matching the path regardless of stage.
*/
#define GIT_INDEX_STAGE_ANY -1
/** @name Index File Functions /** @name Index File Functions
* *
* These functions work on the index file itself. * These functions work on the index file itself.
......
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* 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_pathspec_h__
#define INCLUDE_git_pathspec_h__
#include "common.h"
#include "types.h"
#include "strarray.h"
#include "diff.h"
/**
* Compiled pathspec
*/
typedef struct git_pathspec git_pathspec;
/**
* List of filenames matching a pathspec
*/
typedef struct git_pathspec_match_list git_pathspec_match_list;
/**
* Options controlling how pathspec match should be executed
*
* - GIT_PATHSPEC_IGNORE_CASE forces match to ignore case; otherwise
* match will use native case sensitivity of platform filesystem
* - GIT_PATHSPEC_USE_CASE forces case sensitive match; otherwise
* match will use native case sensitivity of platform filesystem
* - GIT_PATHSPEC_NO_GLOB disables glob patterns and just uses simple
* string comparison for matching
* - GIT_PATHSPEC_NO_MATCH_ERROR means the match functions return error
* code GIT_ENOTFOUND if no matches are found; otherwise no matches is
* still success (return 0) but `git_pathspec_match_list_entrycount`
* will indicate 0 matches.
* - GIT_PATHSPEC_FIND_FAILURES means that the `git_pathspec_match_list`
* should track which patterns matched which files so that at the end of
* the match we can identify patterns that did not match any files.
* - GIT_PATHSPEC_FAILURES_ONLY means that the `git_pathspec_match_list`
* does not need to keep the actual matching filenames. Use this to
* just test if there were any matches at all or in combination with
* GIT_PATHSPEC_FIND_FAILURES to validate a pathspec.
*/
typedef enum {
GIT_PATHSPEC_DEFAULT = 0,
GIT_PATHSPEC_IGNORE_CASE = (1u << 0),
GIT_PATHSPEC_USE_CASE = (1u << 1),
GIT_PATHSPEC_NO_GLOB = (1u << 2),
GIT_PATHSPEC_NO_MATCH_ERROR = (1u << 3),
GIT_PATHSPEC_FIND_FAILURES = (1u << 4),
GIT_PATHSPEC_FAILURES_ONLY = (1u << 5),
} git_pathspec_flag_t;
/**
* Compile a pathspec
*
* @param out Output of the compiled pathspec
* @param pathspec A git_strarray of the paths to match
* @return 0 on success, <0 on failure
*/
GIT_EXTERN(int) git_pathspec_new(
git_pathspec **out, const git_strarray *pathspec);
/**
* Free a pathspec
*
* @param ps The compiled pathspec
*/
GIT_EXTERN(void) git_pathspec_free(git_pathspec *ps);
/**
* Try to match a path against a pathspec
*
* Unlike most of the other pathspec matching functions, this will not
* fall back on the native case-sensitivity for your platform. You must
* explicitly pass flags to control case sensitivity or else this will
* fall back on being case sensitive.
*
* @param ps The compiled pathspec
* @param flags Combination of git_pathspec_flag_t options to control match
* @param path The pathname to attempt to match
* @return 1 is path matches spec, 0 if it does not
*/
GIT_EXTERN(int) git_pathspec_matches_path(
const git_pathspec *ps, uint32_t flags, const char *path);
/**
* Match a pathspec against the working directory of a repository.
*
* This matches the pathspec against the current files in the working
* directory of the repository. It is an error to invoke this on a bare
* repo. This handles git ignores (i.e. ignored files will not be
* considered to match the `pathspec` unless the file is tracked in the
* index).
*
* If `out` is not NULL, this returns a `git_patchspec_match_list`. That
* contains the list of all matched filenames (unless you pass the
* `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
* pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
* flag). You must call `git_pathspec_match_list_free()` on this object.
*
* @param out Output list of matches; pass NULL to just get return value
* @param repo The repository in which to match; bare repo is an error
* @param flags Combination of git_pathspec_flag_t options to control match
* @param ps Pathspec to be matched
* @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
* the GIT_PATHSPEC_NO_MATCH_ERROR flag was given
*/
GIT_EXTERN(int) git_pathspec_match_workdir(
git_pathspec_match_list **out,
git_repository *repo,
uint32_t flags,
git_pathspec *ps);
/**
* Match a pathspec against entries in an index.
*
* This matches the pathspec against the files in the repository index.
*
* NOTE: At the moment, the case sensitivity of this match is controlled
* by the current case-sensitivity of the index object itself and the
* USE_CASE and IGNORE_CASE flags will have no effect. This behavior will
* be corrected in a future release.
*
* If `out` is not NULL, this returns a `git_patchspec_match_list`. That
* contains the list of all matched filenames (unless you pass the
* `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
* pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
* flag). You must call `git_pathspec_match_list_free()` on this object.
*
* @param out Output list of matches; pass NULL to just get return value
* @param index The index to match against
* @param flags Combination of git_pathspec_flag_t options to control match
* @param ps Pathspec to be matched
* @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
* the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
*/
GIT_EXTERN(int) git_pathspec_match_index(
git_pathspec_match_list **out,
git_index *index,
uint32_t flags,
git_pathspec *ps);
/**
* Match a pathspec against files in a tree.
*
* This matches the pathspec against the files in the given tree.
*
* If `out` is not NULL, this returns a `git_patchspec_match_list`. That
* contains the list of all matched filenames (unless you pass the
* `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
* pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
* flag). You must call `git_pathspec_match_list_free()` on this object.
*
* @param out Output list of matches; pass NULL to just get return value
* @param tree The root-level tree to match against
* @param flags Combination of git_pathspec_flag_t options to control match
* @param ps Pathspec to be matched
* @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
* the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
*/
GIT_EXTERN(int) git_pathspec_match_tree(
git_pathspec_match_list **out,
git_tree *tree,
uint32_t flags,
git_pathspec *ps);
/**
* Match a pathspec against files in a diff list.
*
* This matches the pathspec against the files in the given diff list.
*
* If `out` is not NULL, this returns a `git_patchspec_match_list`. That
* contains the list of all matched filenames (unless you pass the
* `GIT_PATHSPEC_FAILURES_ONLY` flag) and may also contain the list of
* pathspecs with no match (if you used the `GIT_PATHSPEC_FIND_FAILURES`
* flag). You must call `git_pathspec_match_list_free()` on this object.
*
* @param out Output list of matches; pass NULL to just get return value
* @param diff A generated diff list
* @param flags Combination of git_pathspec_flag_t options to control match
* @param ps Pathspec to be matched
* @return 0 on success, -1 on error, GIT_ENOTFOUND if no matches and
* the GIT_PATHSPEC_NO_MATCH_ERROR flag is used
*/
GIT_EXTERN(int) git_pathspec_match_diff(
git_pathspec_match_list **out,
git_diff_list *diff,
uint32_t flags,
git_pathspec *ps);
/**
* Free memory associates with a git_pathspec_match_list
*
* @param m The git_pathspec_match_list to be freed
*/
GIT_EXTERN(void) git_pathspec_match_list_free(git_pathspec_match_list *m);
/**
* Get the number of items in a match list.
*
* @param m The git_pathspec_match_list object
* @return Number of items in match list
*/
GIT_EXTERN(size_t) git_pathspec_match_list_entrycount(
const git_pathspec_match_list *m);
/**
* Get a matching filename by position.
*
* This routine cannot be used if the match list was generated by
* `git_pathspec_match_diff`. If so, it will always return NULL.
*
* @param m The git_pathspec_match_list object
* @param pos The index into the list
* @return The filename of the match
*/
GIT_EXTERN(const char *) git_pathspec_match_list_entry(
const git_pathspec_match_list *m, size_t pos);
/**
* Get a matching diff delta by position.
*
* This routine can only be used if the match list was generated by
* `git_pathspec_match_diff`. Otherwise it will always return NULL.
*
* @param m The git_pathspec_match_list object
* @param pos The index into the list
* @return The filename of the match
*/
GIT_EXTERN(const git_diff_delta *) git_pathspec_match_list_diff_entry(
const git_pathspec_match_list *m, size_t pos);
/**
* Get the number of pathspec items that did not match.
*
* This will be zero unless you passed GIT_PATHSPEC_FIND_FAILURES when
* generating the git_pathspec_match_list.
*
* @param m The git_pathspec_match_list object
* @return Number of items in original pathspec that had no matches
*/
GIT_EXTERN(size_t) git_pathspec_match_list_failed_entrycount(
const git_pathspec_match_list *m);
/**
* Get an original pathspec string that had no matches.
*
* This will be return NULL for positions out of range.
*
* @param m The git_pathspec_match_list object
* @param pos The index into the failed items
* @return The pathspec pattern that didn't match anything
*/
GIT_EXTERN(const char *) git_pathspec_match_list_failed_entry(
const git_pathspec_match_list *m, size_t pos);
#endif
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
#define git_array_init(a) \ #define git_array_init(a) \
do { (a).size = (a).asize = 0; (a).ptr = NULL; } while (0) do { (a).size = (a).asize = 0; (a).ptr = NULL; } while (0)
#define git_array_init_to_size(a, desired) \
do { (a).size = 0; (a).asize = desired; (a).ptr = git__calloc(desired, sizeof(*(a).ptr)); } while (0)
#define git_array_clear(a) \ #define git_array_clear(a) \
do { git__free((a).ptr); git_array_init(a); } while (0) do { git__free((a).ptr); git_array_init(a); } while (0)
...@@ -63,4 +66,6 @@ GIT_INLINE(void *) git_array_grow(git_array_generic_t *a, size_t item_size) ...@@ -63,4 +66,6 @@ GIT_INLINE(void *) git_array_grow(git_array_generic_t *a, size_t item_size)
#define git_array_size(a) (a).size #define git_array_size(a) (a).size
#define git_array_valid_index(a, i) ((i) < (a).size)
#endif #endif
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* 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_bitvec_h__
#define INCLUDE_bitvec_h__
#include "util.h"
/*
* This is a silly little fixed length bit vector type that will store
* vectors of 64 bits or less directly in the structure and allocate
* memory for vectors longer than 64 bits. You can use the two versions
* transparently through the API and avoid heap allocation completely when
* using a short bit vector as a result.
*/
typedef struct {
size_t length;
union {
uint64_t *words;
uint64_t bits;
} u;
} git_bitvec;
GIT_INLINE(int) git_bitvec_init(git_bitvec *bv, size_t capacity)
{
memset(bv, 0x0, sizeof(*bv));
if (capacity >= 64) {
bv->length = (capacity / 64) + 1;
bv->u.words = git__calloc(bv->length, sizeof(uint64_t));
if (!bv->u.words)
return -1;
}
return 0;
}
#define GIT_BITVEC_MASK(BIT) ((uint64_t)1 << (BIT % 64))
#define GIT_BITVEC_WORD(BV, BIT) (BV->length ? &BV->u.words[BIT / 64] : &BV->u.bits)
GIT_INLINE(void) git_bitvec_set(git_bitvec *bv, size_t bit, bool on)
{
uint64_t *word = GIT_BITVEC_WORD(bv, bit);
uint64_t mask = GIT_BITVEC_MASK(bit);
if (on)
*word |= mask;
else
*word &= ~mask;
}
GIT_INLINE(bool) git_bitvec_get(git_bitvec *bv, size_t bit)
{
uint64_t *word = GIT_BITVEC_WORD(bv, bit);
return (*word & GIT_BITVEC_MASK(bit)) != 0;
}
GIT_INLINE(void) git_bitvec_clear(git_bitvec *bv)
{
if (!bv->length)
bv->u.bits = 0;
else
memset(bv->u.words, 0x0, bv->length * sizeof(uint64_t));
}
GIT_INLINE(void) git_bitvec_free(git_bitvec *bv)
{
if (bv->length)
git__free(bv->u.words);
}
#endif
...@@ -246,10 +246,10 @@ static int checkout_action_wd_only( ...@@ -246,10 +246,10 @@ static int checkout_action_wd_only(
bool remove = false; bool remove = false;
git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE; git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE;
if (!git_pathspec_match_path( if (!git_pathspec__match(
pathspec, wd->path, pathspec, wd->path,
(data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0, (data->strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH) != 0,
git_iterator_ignore_case(workdir), NULL)) git_iterator_ignore_case(workdir), NULL, NULL))
return 0; return 0;
/* check if item is tracked in the index but not in the checkout diff */ /* check if item is tracked in the index but not in the checkout diff */
...@@ -607,7 +607,7 @@ static int checkout_get_actions( ...@@ -607,7 +607,7 @@ static int checkout_get_actions(
uint32_t *actions = NULL; uint32_t *actions = NULL;
if (data->opts.paths.count > 0 && if (data->opts.paths.count > 0 &&
git_pathspec_init(&pathspec, &data->opts.paths, &pathpool) < 0) git_pathspec__vinit(&pathspec, &data->opts.paths, &pathpool) < 0)
return -1; return -1;
if ((error = git_iterator_current(&wditem, workdir)) < 0 && if ((error = git_iterator_current(&wditem, workdir)) < 0 &&
...@@ -659,7 +659,7 @@ static int checkout_get_actions( ...@@ -659,7 +659,7 @@ static int checkout_get_actions(
goto fail; goto fail;
} }
git_pathspec_free(&pathspec); git_pathspec__vfree(&pathspec);
git_pool_clear(&pathpool); git_pool_clear(&pathpool);
return 0; return 0;
...@@ -670,7 +670,7 @@ fail: ...@@ -670,7 +670,7 @@ fail:
*actions_ptr = NULL; *actions_ptr = NULL;
git__free(actions); git__free(actions);
git_pathspec_free(&pathspec); git_pathspec__vfree(&pathspec);
git_pool_clear(&pathpool); git_pool_clear(&pathpool);
return error; return error;
......
...@@ -19,30 +19,19 @@ ...@@ -19,30 +19,19 @@
#include <stdarg.h> #include <stdarg.h>
static void clear_parents(git_commit *commit)
{
size_t i;
for (i = 0; i < commit->parent_ids.length; ++i) {
git_oid *parent = git_vector_get(&commit->parent_ids, i);
git__free(parent);
}
git_vector_clear(&commit->parent_ids);
}
void git_commit__free(void *_commit) void git_commit__free(void *_commit)
{ {
git_commit *commit = _commit; git_commit *commit = _commit;
clear_parents(commit); git_array_clear(commit->parent_ids);
git_vector_free(&commit->parent_ids);
git_signature_free(commit->author); git_signature_free(commit->author);
git_signature_free(commit->committer); git_signature_free(commit->committer);
git__free(commit->raw_header);
git__free(commit->message); git__free(commit->message);
git__free(commit->message_encoding); git__free(commit->message_encoding);
git__free(commit); git__free(commit);
} }
...@@ -171,12 +160,34 @@ int git_commit_create( ...@@ -171,12 +160,34 @@ int git_commit_create(
int git_commit__parse(void *_commit, git_odb_object *odb_obj) int git_commit__parse(void *_commit, git_odb_object *odb_obj)
{ {
git_commit *commit = _commit; git_commit *commit = _commit;
const char *buffer = git_odb_object_data(odb_obj); const char *buffer_start = git_odb_object_data(odb_obj), *buffer;
const char *buffer_end = buffer + git_odb_object_size(odb_obj); const char *buffer_end = buffer_start + git_odb_object_size(odb_obj);
git_oid parent_id; git_oid parent_id;
size_t parent_count = 0, header_len;
if (git_vector_init(&commit->parent_ids, 4, NULL) < 0) /* find end-of-header (counting parents as we go) */
return -1; for (buffer = buffer_start; buffer < buffer_end; ++buffer) {
if (!strncmp("\n\n", buffer, 2)) {
++buffer;
break;
}
if (!strncmp("\nparent ", buffer, strlen("\nparent ")))
++parent_count;
}
header_len = buffer - buffer_start;
commit->raw_header = git__strndup(buffer_start, header_len);
GITERR_CHECK_ALLOC(commit->raw_header);
/* point "buffer" to header data */
buffer = commit->raw_header;
buffer_end = commit->raw_header + header_len;
if (parent_count < 1)
parent_count = 1;
git_array_init_to_size(commit->parent_ids, parent_count);
GITERR_CHECK_ARRAY(commit->parent_ids);
if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0) if (git_oid__parse(&commit->tree_id, &buffer, buffer_end, "tree ") < 0)
goto bad_buffer; goto bad_buffer;
...@@ -186,13 +197,10 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj) ...@@ -186,13 +197,10 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
*/ */
while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) { while (git_oid__parse(&parent_id, &buffer, buffer_end, "parent ") == 0) {
git_oid *new_id = git__malloc(sizeof(git_oid)); git_oid *new_id = git_array_alloc(commit->parent_ids);
GITERR_CHECK_ALLOC(new_id); GITERR_CHECK_ALLOC(new_id);
git_oid_cpy(new_id, &parent_id); git_oid_cpy(new_id, &parent_id);
if (git_vector_insert(&commit->parent_ids, new_id) < 0)
return -1;
} }
commit->author = git__malloc(sizeof(git_signature)); commit->author = git__malloc(sizeof(git_signature));
...@@ -208,8 +216,8 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj) ...@@ -208,8 +216,8 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0) if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0)
return -1; return -1;
/* Parse add'l header entries until blank line found */ /* Parse add'l header entries */
while (buffer < buffer_end && *buffer != '\n') { while (buffer < buffer_end) {
const char *eoln = buffer; const char *eoln = buffer;
while (eoln < buffer_end && *eoln != '\n') while (eoln < buffer_end && *eoln != '\n')
++eoln; ++eoln;
...@@ -223,15 +231,18 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj) ...@@ -223,15 +231,18 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
if (eoln < buffer_end && *eoln == '\n') if (eoln < buffer_end && *eoln == '\n')
++eoln; ++eoln;
buffer = eoln; buffer = eoln;
} }
/* buffer is now at the end of the header, double-check and move forward into the message */ /* point "buffer" to data after header */
if (buffer < buffer_end && *buffer == '\n') buffer = git_odb_object_data(odb_obj);
buffer++; buffer_end = buffer + git_odb_object_size(odb_obj);
buffer += header_len;
if (*buffer == '\n')
++buffer;
/* parse commit message */ /* extract commit message */
if (buffer <= buffer_end) { if (buffer <= buffer_end) {
commit->message = git__strndup(buffer, buffer_end - buffer); commit->message = git__strndup(buffer, buffer_end - buffer);
GITERR_CHECK_ALLOC(commit->message); GITERR_CHECK_ALLOC(commit->message);
...@@ -255,9 +266,10 @@ GIT_COMMIT_GETTER(const git_signature *, author, commit->author) ...@@ -255,9 +266,10 @@ GIT_COMMIT_GETTER(const git_signature *, author, commit->author)
GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer) GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer)
GIT_COMMIT_GETTER(const char *, message, commit->message) GIT_COMMIT_GETTER(const char *, message, commit->message)
GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding) GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding)
GIT_COMMIT_GETTER(const char *, raw_header, commit->raw_header)
GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time) GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time)
GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset) GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset)
GIT_COMMIT_GETTER(unsigned int, parentcount, (unsigned int)commit->parent_ids.length) GIT_COMMIT_GETTER(unsigned int, parentcount, (unsigned int)git_array_size(commit->parent_ids))
GIT_COMMIT_GETTER(const git_oid *, tree_id, &commit->tree_id); GIT_COMMIT_GETTER(const git_oid *, tree_id, &commit->tree_id);
int git_commit_tree(git_tree **tree_out, const git_commit *commit) int git_commit_tree(git_tree **tree_out, const git_commit *commit)
...@@ -271,7 +283,7 @@ const git_oid *git_commit_parent_id( ...@@ -271,7 +283,7 @@ const git_oid *git_commit_parent_id(
{ {
assert(commit); assert(commit);
return git_vector_get(&commit->parent_ids, n); return git_array_get(commit->parent_ids, n);
} }
int git_commit_parent( int git_commit_parent(
......
...@@ -10,14 +10,14 @@ ...@@ -10,14 +10,14 @@
#include "git2/commit.h" #include "git2/commit.h"
#include "tree.h" #include "tree.h"
#include "repository.h" #include "repository.h"
#include "vector.h" #include "array.h"
#include <time.h> #include <time.h>
struct git_commit { struct git_commit {
git_object object; git_object object;
git_vector parent_ids; git_array_t(git_oid) parent_ids;
git_oid tree_id; git_oid tree_id;
git_signature *author; git_signature *author;
...@@ -25,6 +25,7 @@ struct git_commit { ...@@ -25,6 +25,7 @@ struct git_commit {
char *message_encoding; char *message_encoding;
char *message; char *message;
char *raw_header;
}; };
void git_commit__free(void *commit); void git_commit__free(void *commit);
......
...@@ -81,11 +81,11 @@ static int diff_delta__from_one( ...@@ -81,11 +81,11 @@ static int diff_delta__from_one(
DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_SUBMODULES)) DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_SUBMODULES))
return 0; return 0;
if (!git_pathspec_match_path( if (!git_pathspec__match(
&diff->pathspec, entry->path, &diff->pathspec, entry->path,
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH), DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH),
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE), DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE),
&matched_pathspec)) &matched_pathspec, NULL))
return 0; return 0;
delta = diff_delta__alloc(diff, status, entry->path); delta = diff_delta__alloc(diff, status, entry->path);
...@@ -247,6 +247,11 @@ GIT_INLINE(const char *) diff_delta__path(const git_diff_delta *delta) ...@@ -247,6 +247,11 @@ GIT_INLINE(const char *) diff_delta__path(const git_diff_delta *delta)
return str; return str;
} }
const char *git_diff_delta__path(const git_diff_delta *delta)
{
return diff_delta__path(delta);
}
int git_diff_delta__cmp(const void *a, const void *b) int git_diff_delta__cmp(const void *a, const void *b)
{ {
const git_diff_delta *da = a, *db = b; const git_diff_delta *da = a, *db = b;
...@@ -387,7 +392,7 @@ static int diff_list_apply_options( ...@@ -387,7 +392,7 @@ static int diff_list_apply_options(
DIFF_FLAG_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE, icase); DIFF_FLAG_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE, icase);
/* initialize pathspec from options */ /* initialize pathspec from options */
if (git_pathspec_init(&diff->pathspec, &opts->pathspec, pool) < 0) if (git_pathspec__vinit(&diff->pathspec, &opts->pathspec, pool) < 0)
return -1; return -1;
} }
...@@ -473,7 +478,7 @@ static void diff_list_free(git_diff_list *diff) ...@@ -473,7 +478,7 @@ static void diff_list_free(git_diff_list *diff)
} }
git_vector_free(&diff->deltas); git_vector_free(&diff->deltas);
git_pathspec_free(&diff->pathspec); git_pathspec__vfree(&diff->pathspec);
git_pool_clear(&diff->pool); git_pool_clear(&diff->pool);
git__memzero(diff, sizeof(*diff)); git__memzero(diff, sizeof(*diff));
...@@ -634,11 +639,11 @@ static int maybe_modified( ...@@ -634,11 +639,11 @@ static int maybe_modified(
bool new_is_workdir = (info->new_iter->type == GIT_ITERATOR_TYPE_WORKDIR); bool new_is_workdir = (info->new_iter->type == GIT_ITERATOR_TYPE_WORKDIR);
const char *matched_pathspec; const char *matched_pathspec;
if (!git_pathspec_match_path( if (!git_pathspec__match(
&diff->pathspec, oitem->path, &diff->pathspec, oitem->path,
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH), DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH),
DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE), DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE),
&matched_pathspec)) &matched_pathspec, NULL))
return 0; return 0;
memset(&noid, 0, sizeof(noid)); memset(&noid, 0, sizeof(noid));
...@@ -1235,6 +1240,11 @@ size_t git_diff_num_deltas_of_type(git_diff_list *diff, git_delta_t type) ...@@ -1235,6 +1240,11 @@ size_t git_diff_num_deltas_of_type(git_diff_list *diff, git_delta_t type)
return count; return count;
} }
int git_diff_is_sorted_icase(const git_diff_list *diff)
{
return (diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0;
}
int git_diff__paired_foreach( int git_diff__paired_foreach(
git_diff_list *head2idx, git_diff_list *head2idx,
git_diff_list *idx2wd, git_diff_list *idx2wd,
......
...@@ -76,6 +76,8 @@ extern void git_diff_list_addref(git_diff_list *diff); ...@@ -76,6 +76,8 @@ extern void git_diff_list_addref(git_diff_list *diff);
extern int git_diff_delta__cmp(const void *a, const void *b); extern int git_diff_delta__cmp(const void *a, const void *b);
extern int git_diff_delta__casecmp(const void *a, const void *b); extern int git_diff_delta__casecmp(const void *a, const void *b);
extern const char *git_diff_delta__path(const git_diff_delta *delta);
extern bool git_diff_delta__should_skip( extern bool git_diff_delta__should_skip(
const git_diff_options *opts, const git_diff_delta *delta); const git_diff_options *opts, const git_diff_delta *delta);
......
...@@ -101,8 +101,6 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size) ...@@ -101,8 +101,6 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
static bool is_index_extended(git_index *index); static bool is_index_extended(git_index *index);
static int write_index(git_index *index, git_filebuf *file); static int write_index(git_index *index, git_filebuf *file);
static int index_find(size_t *at_pos, git_index *index, const char *path, int stage);
static void index_entry_free(git_index_entry *entry); static void index_entry_free(git_index_entry *entry);
static void index_entry_reuc_free(git_index_reuc_entry *reuc); static void index_entry_reuc_free(git_index_reuc_entry *reuc);
...@@ -114,7 +112,7 @@ static int index_srch(const void *key, const void *array_member) ...@@ -114,7 +112,7 @@ static int index_srch(const void *key, const void *array_member)
ret = strcmp(srch_key->path, entry->path); ret = strcmp(srch_key->path, entry->path);
if (ret == 0) if (ret == 0 && srch_key->stage != GIT_INDEX_STAGE_ANY)
ret = srch_key->stage - GIT_IDXENTRY_STAGE(entry); ret = srch_key->stage - GIT_IDXENTRY_STAGE(entry);
return ret; return ret;
...@@ -128,7 +126,7 @@ static int index_isrch(const void *key, const void *array_member) ...@@ -128,7 +126,7 @@ static int index_isrch(const void *key, const void *array_member)
ret = strcasecmp(srch_key->path, entry->path); ret = strcasecmp(srch_key->path, entry->path);
if (ret == 0) if (ret == 0 && srch_key->stage != GIT_INDEX_STAGE_ANY)
ret = srch_key->stage - GIT_IDXENTRY_STAGE(entry); ret = srch_key->stage - GIT_IDXENTRY_STAGE(entry);
return ret; return ret;
...@@ -562,7 +560,7 @@ const git_index_entry *git_index_get_bypath( ...@@ -562,7 +560,7 @@ const git_index_entry *git_index_get_bypath(
git_vector_sort(&index->entries); git_vector_sort(&index->entries);
if (index_find(&pos, index, path, stage) < 0) { if (git_index__find(&pos, index, path, stage) < 0) {
giterr_set(GITERR_INDEX, "Index does not contain %s", path); giterr_set(GITERR_INDEX, "Index does not contain %s", path);
return NULL; return NULL;
} }
...@@ -719,7 +717,8 @@ static int index_insert(git_index *index, git_index_entry *entry, int replace) ...@@ -719,7 +717,8 @@ static int index_insert(git_index *index, git_index_entry *entry, int replace)
entry->flags |= GIT_IDXENTRY_NAMEMASK; entry->flags |= GIT_IDXENTRY_NAMEMASK;
/* look if an entry with this path already exists */ /* look if an entry with this path already exists */
if (!index_find(&position, index, entry->path, GIT_IDXENTRY_STAGE(entry))) { if (!git_index__find(
&position, index, entry->path, GIT_IDXENTRY_STAGE(entry))) {
existing = (git_index_entry **)&index->entries.contents[position]; existing = (git_index_entry **)&index->entries.contents[position];
/* update filemode to existing values if stat is not trusted */ /* update filemode to existing values if stat is not trusted */
...@@ -831,7 +830,7 @@ int git_index_remove(git_index *index, const char *path, int stage) ...@@ -831,7 +830,7 @@ int git_index_remove(git_index *index, const char *path, int stage)
git_vector_sort(&index->entries); git_vector_sort(&index->entries);
if (index_find(&position, index, path, stage) < 0) { if (git_index__find(&position, index, path, stage) < 0) {
giterr_set(GITERR_INDEX, "Index does not contain %s at stage %d", giterr_set(GITERR_INDEX, "Index does not contain %s at stage %d",
path, stage); path, stage);
return GIT_ENOTFOUND; return GIT_ENOTFOUND;
...@@ -887,7 +886,8 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage) ...@@ -887,7 +886,8 @@ int git_index_remove_directory(git_index *index, const char *dir, int stage)
return error; return error;
} }
static int index_find(size_t *at_pos, git_index *index, const char *path, int stage) int git_index__find(
size_t *at_pos, git_index *index, const char *path, int stage)
{ {
struct entry_srch_key srch_key; struct entry_srch_key srch_key;
...@@ -896,7 +896,8 @@ static int index_find(size_t *at_pos, git_index *index, const char *path, int st ...@@ -896,7 +896,8 @@ static int index_find(size_t *at_pos, git_index *index, const char *path, int st
srch_key.path = path; srch_key.path = path;
srch_key.stage = stage; srch_key.stage = stage;
return git_vector_bsearch2(at_pos, &index->entries, index->entries_search, &srch_key); return git_vector_bsearch2(
at_pos, &index->entries, index->entries_search, &srch_key);
} }
int git_index_find(size_t *at_pos, git_index *index, const char *path) int git_index_find(size_t *at_pos, git_index *index, const char *path)
...@@ -2053,7 +2054,7 @@ int git_index_add_all( ...@@ -2053,7 +2054,7 @@ int git_index_add_all(
git_iterator *wditer = NULL; git_iterator *wditer = NULL;
const git_index_entry *wd = NULL; const git_index_entry *wd = NULL;
git_index_entry *entry; git_index_entry *entry;
git_pathspec_context ps; git_pathspec ps;
const char *match; const char *match;
size_t existing; size_t existing;
bool no_fnmatch = (flags & GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH) != 0; bool no_fnmatch = (flags & GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH) != 0;
...@@ -2074,7 +2075,7 @@ int git_index_add_all( ...@@ -2074,7 +2075,7 @@ int git_index_add_all(
if (git_repository__cvar(&ignorecase, repo, GIT_CVAR_IGNORECASE) < 0) if (git_repository__cvar(&ignorecase, repo, GIT_CVAR_IGNORECASE) < 0)
return -1; return -1;
if ((error = git_pathspec_context_init(&ps, paths)) < 0) if ((error = git_pathspec__init(&ps, paths)) < 0)
return error; return error;
/* optionally check that pathspec doesn't mention any ignored files */ /* optionally check that pathspec doesn't mention any ignored files */
...@@ -2091,14 +2092,14 @@ int git_index_add_all( ...@@ -2091,14 +2092,14 @@ int git_index_add_all(
while (!(error = git_iterator_advance(&wd, wditer))) { while (!(error = git_iterator_advance(&wd, wditer))) {
/* check if path actually matches */ /* check if path actually matches */
if (!git_pathspec_match_path( if (!git_pathspec__match(
&ps.pathspec, wd->path, no_fnmatch, ignorecase, &match)) &ps.pathspec, wd->path, no_fnmatch, ignorecase, &match, NULL))
continue; continue;
/* skip ignored items that are not already in the index */ /* skip ignored items that are not already in the index */
if ((flags & GIT_INDEX_ADD_FORCE) == 0 && if ((flags & GIT_INDEX_ADD_FORCE) == 0 &&
git_iterator_current_is_ignored(wditer) && git_iterator_current_is_ignored(wditer) &&
index_find(&existing, index, wd->path, 0) < 0) git_index__find(&existing, index, wd->path, 0) < 0)
continue; continue;
/* issue notification callback if requested */ /* issue notification callback if requested */
...@@ -2148,7 +2149,7 @@ int git_index_add_all( ...@@ -2148,7 +2149,7 @@ int git_index_add_all(
cleanup: cleanup:
git_iterator_free(wditer); git_iterator_free(wditer);
git_pathspec_context_free(&ps); git_pathspec__clear(&ps);
return error; return error;
} }
...@@ -2168,13 +2169,13 @@ static int index_apply_to_all( ...@@ -2168,13 +2169,13 @@ static int index_apply_to_all(
{ {
int error = 0; int error = 0;
size_t i; size_t i;
git_pathspec_context ps; git_pathspec ps;
const char *match; const char *match;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
assert(index); assert(index);
if ((error = git_pathspec_context_init(&ps, paths)) < 0) if ((error = git_pathspec__init(&ps, paths)) < 0)
return error; return error;
git_vector_sort(&index->entries); git_vector_sort(&index->entries);
...@@ -2183,8 +2184,9 @@ static int index_apply_to_all( ...@@ -2183,8 +2184,9 @@ static int index_apply_to_all(
git_index_entry *entry = git_vector_get(&index->entries, i); git_index_entry *entry = git_vector_get(&index->entries, i);
/* check if path actually matches */ /* check if path actually matches */
if (!git_pathspec_match_path( if (!git_pathspec__match(
&ps.pathspec, entry->path, false, index->ignore_case, &match)) &ps.pathspec, entry->path, false, index->ignore_case,
&match, NULL))
continue; continue;
/* issue notification callback if requested */ /* issue notification callback if requested */
...@@ -2231,7 +2233,7 @@ static int index_apply_to_all( ...@@ -2231,7 +2233,7 @@ static int index_apply_to_all(
} }
git_buf_free(&path); git_buf_free(&path);
git_pathspec_context_free(&ps); git_pathspec__clear(&ps);
return error; return error;
} }
......
...@@ -47,13 +47,17 @@ struct git_index_conflict_iterator { ...@@ -47,13 +47,17 @@ struct git_index_conflict_iterator {
size_t cur; size_t cur;
}; };
extern void git_index_entry__init_from_stat(git_index_entry *entry, struct stat *st); extern void git_index_entry__init_from_stat(
git_index_entry *entry, struct stat *st);
extern size_t git_index__prefix_position(git_index *index, const char *path); extern size_t git_index__prefix_position(git_index *index, const char *path);
extern int git_index_entry__cmp(const void *a, const void *b); extern int git_index_entry__cmp(const void *a, const void *b);
extern int git_index_entry__cmp_icase(const void *a, const void *b); extern int git_index_entry__cmp_icase(const void *a, const void *b);
extern int git_index__find(
size_t *at_pos, git_index *index, const char *path, int stage);
extern void git_index__set_ignore_case(git_index *index, bool ignore_case); extern void git_index__set_ignore_case(git_index *index, bool ignore_case);
#endif #endif
...@@ -8,9 +8,35 @@ ...@@ -8,9 +8,35 @@
#define INCLUDE_pathspec_h__ #define INCLUDE_pathspec_h__
#include "common.h" #include "common.h"
#include <git2/pathspec.h>
#include "buffer.h" #include "buffer.h"
#include "vector.h" #include "vector.h"
#include "pool.h" #include "pool.h"
#include "array.h"
/* public compiled pathspec */
struct git_pathspec {
git_refcount rc;
char *prefix;
git_vector pathspec;
git_pool pool;
};
enum {
PATHSPEC_DATATYPE_STRINGS = 0,
PATHSPEC_DATATYPE_DIFF = 1,
};
typedef git_array_t(char *) git_pathspec_string_array_t;
/* public interface to pathspec matching */
struct git_pathspec_match_list {
git_pathspec *pathspec;
git_array_t(void *) matches;
git_pathspec_string_array_t failures;
git_pool pool;
int datatype;
};
/* what is the common non-wildcard prefix for all items in the pathspec */ /* what is the common non-wildcard prefix for all items in the pathspec */
extern char *git_pathspec_prefix(const git_strarray *pathspec); extern char *git_pathspec_prefix(const git_strarray *pathspec);
...@@ -19,36 +45,31 @@ extern char *git_pathspec_prefix(const git_strarray *pathspec); ...@@ -19,36 +45,31 @@ extern char *git_pathspec_prefix(const git_strarray *pathspec);
extern bool git_pathspec_is_empty(const git_strarray *pathspec); extern bool git_pathspec_is_empty(const git_strarray *pathspec);
/* build a vector of fnmatch patterns to evaluate efficiently */ /* build a vector of fnmatch patterns to evaluate efficiently */
extern int git_pathspec_init( extern int git_pathspec__vinit(
git_vector *vspec, const git_strarray *strspec, git_pool *strpool); git_vector *vspec, const git_strarray *strspec, git_pool *strpool);
/* free data from the pathspec vector */ /* free data from the pathspec vector */
extern void git_pathspec_free(git_vector *vspec); extern void git_pathspec__vfree(git_vector *vspec);
#define GIT_PATHSPEC_NOMATCH ((size_t)-1)
/* /*
* Match a path against the vectorized pathspec. * Match a path against the vectorized pathspec.
* The matched pathspec is passed back into the `matched_pathspec` parameter, * The matched pathspec is passed back into the `matched_pathspec` parameter,
* unless it is passed as NULL by the caller. * unless it is passed as NULL by the caller.
*/ */
extern bool git_pathspec_match_path( extern bool git_pathspec__match(
git_vector *vspec, const git_vector *vspec,
const char *path, const char *path,
bool disable_fnmatch, bool disable_fnmatch,
bool casefold, bool casefold,
const char **matched_pathspec); const char **matched_pathspec,
size_t *matched_at);
/* easy pathspec setup */ /* easy pathspec setup */
typedef struct { extern int git_pathspec__init(git_pathspec *ps, const git_strarray *paths);
char *prefix;
git_vector pathspec;
git_pool pool;
} git_pathspec_context;
extern int git_pathspec_context_init(
git_pathspec_context *ctxt, const git_strarray *paths);
extern void git_pathspec_context_free( extern void git_pathspec__clear(git_pathspec *ps);
git_pathspec_context *ctxt);
#endif #endif
#include "clar_libgit2.h"
#include "bitvec.h"
#if 0
static void print_bitvec(git_bitvec *bv)
{
int b;
if (!bv->length) {
for (b = 63; b >= 0; --b)
fprintf(stderr, "%d", (bv->u.bits & (1ul << b)) ? 1 : 0);
} else {
for (b = bv->length * 8; b >= 0; --b)
fprintf(stderr, "%d", (bv->u.ptr[b >> 3] & (b & 0x0ff)) ? 1 : 0);
}
fprintf(stderr, "\n");
}
#endif
static void set_some_bits(git_bitvec *bv, size_t length)
{
size_t i;
for (i = 0; i < length; ++i) {
if (i % 3 == 0 || i % 7 == 0)
git_bitvec_set(bv, i, true);
}
}
static void check_some_bits(git_bitvec *bv, size_t length)
{
size_t i;
for (i = 0; i < length; ++i)
cl_assert_equal_b(i % 3 == 0 || i % 7 == 0, git_bitvec_get(bv, i));
}
void test_core_bitvec__0(void)
{
git_bitvec bv;
cl_git_pass(git_bitvec_init(&bv, 32));
set_some_bits(&bv, 16);
check_some_bits(&bv, 16);
git_bitvec_clear(&bv);
set_some_bits(&bv, 32);
check_some_bits(&bv, 32);
git_bitvec_clear(&bv);
set_some_bits(&bv, 64);
check_some_bits(&bv, 64);
git_bitvec_free(&bv);
cl_git_pass(git_bitvec_init(&bv, 128));
set_some_bits(&bv, 32);
check_some_bits(&bv, 32);
set_some_bits(&bv, 128);
check_some_bits(&bv, 128);
git_bitvec_free(&bv);
cl_git_pass(git_bitvec_init(&bv, 4000));
set_some_bits(&bv, 4000);
check_some_bits(&bv, 4000);
git_bitvec_free(&bv);
}
#include "clar_libgit2.h"
#include "diff_helpers.h"
static git_repository *g_repo = NULL;
void test_diff_pathspec__initialize(void)
{
g_repo = cl_git_sandbox_init("status");
}
void test_diff_pathspec__cleanup(void)
{
cl_git_sandbox_cleanup();
}
void test_diff_pathspec__0(void)
{
const char *a_commit = "26a125ee"; /* the current HEAD */
const char *b_commit = "0017bd4a"; /* the start */
git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
git_strarray paths = { NULL, 1 };
char *path;
git_pathspec *ps;
git_pathspec_match_list *matches;
cl_assert(a);
cl_assert(b);
path = "*_file";
paths.strings = &path;
cl_git_pass(git_pathspec_new(&ps, &paths));
cl_git_pass(git_pathspec_match_tree(&matches, a, GIT_PATHSPEC_DEFAULT, ps));
cl_assert_equal_i(7, git_pathspec_match_list_entrycount(matches));
cl_assert_equal_s("current_file", git_pathspec_match_list_entry(matches,0));
cl_assert(git_pathspec_match_list_diff_entry(matches,0) == NULL);
git_pathspec_match_list_free(matches);
cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, NULL, a, &opts));
cl_git_pass(git_pathspec_match_diff(
&matches, diff, GIT_PATHSPEC_DEFAULT, ps));
cl_assert_equal_i(7, git_pathspec_match_list_entrycount(matches));
cl_assert(git_pathspec_match_list_diff_entry(matches, 0) != NULL);
cl_assert(git_pathspec_match_list_entry(matches, 0) == NULL);
cl_assert_equal_s("current_file",
git_pathspec_match_list_diff_entry(matches,0)->new_file.path);
cl_assert_equal_i(GIT_DELTA_ADDED,
git_pathspec_match_list_diff_entry(matches,0)->status);
git_pathspec_match_list_free(matches);
git_diff_list_free(diff);
diff = NULL;
cl_git_pass(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
cl_git_pass(git_pathspec_match_diff(
&matches, diff, GIT_PATHSPEC_DEFAULT, ps));
cl_assert_equal_i(3, git_pathspec_match_list_entrycount(matches));
cl_assert(git_pathspec_match_list_diff_entry(matches, 0) != NULL);
cl_assert(git_pathspec_match_list_entry(matches, 0) == NULL);
cl_assert_equal_s("subdir/current_file",
git_pathspec_match_list_diff_entry(matches,0)->new_file.path);
cl_assert_equal_i(GIT_DELTA_DELETED,
git_pathspec_match_list_diff_entry(matches,0)->status);
git_pathspec_match_list_free(matches);
git_diff_list_free(diff);
diff = NULL;
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, a, &opts));
cl_git_pass(git_pathspec_match_diff(
&matches, diff, GIT_PATHSPEC_DEFAULT, ps));
cl_assert_equal_i(4, git_pathspec_match_list_entrycount(matches));
cl_assert(git_pathspec_match_list_diff_entry(matches, 0) != NULL);
cl_assert(git_pathspec_match_list_entry(matches, 0) == NULL);
cl_assert_equal_s("modified_file",
git_pathspec_match_list_diff_entry(matches,0)->new_file.path);
cl_assert_equal_i(GIT_DELTA_MODIFIED,
git_pathspec_match_list_diff_entry(matches,0)->status);
git_pathspec_match_list_free(matches);
git_diff_list_free(diff);
diff = NULL;
git_tree_free(a);
git_tree_free(b);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment