mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 22:39:38 +00:00
Move pathspec code in separate files
Diff uses a `git_strarray` of path specs to represent a subset of all files to be processed. It is useful to be able to reuse this filtering in other places outside diff, so I've moved it into a standalone set of utilities.
This commit is contained in:
parent
220d5a6c35
commit
2e3d4b96c0
172
src/diff.c
172
src/diff.c
@ -10,76 +10,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "attr_file.h"
|
#include "attr_file.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
#include "pathspec.h"
|
||||||
static char *diff_prefix_from_pathspec(const git_strarray *pathspec)
|
|
||||||
{
|
|
||||||
git_buf prefix = GIT_BUF_INIT;
|
|
||||||
const char *scan;
|
|
||||||
|
|
||||||
if (git_buf_common_prefix(&prefix, pathspec) < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* diff prefix will only be leading non-wildcards */
|
|
||||||
for (scan = prefix.ptr; *scan; ++scan) {
|
|
||||||
if (git__iswildcard(*scan) &&
|
|
||||||
(scan == prefix.ptr || (*(scan - 1) != '\\')))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
git_buf_truncate(&prefix, scan - prefix.ptr);
|
|
||||||
|
|
||||||
if (prefix.size <= 0) {
|
|
||||||
git_buf_free(&prefix);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
git_buf_unescape(&prefix);
|
|
||||||
|
|
||||||
return git_buf_detach(&prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool diff_pathspec_is_interesting(const git_strarray *pathspec)
|
|
||||||
{
|
|
||||||
const char *str;
|
|
||||||
|
|
||||||
if (pathspec == NULL || pathspec->count == 0)
|
|
||||||
return false;
|
|
||||||
if (pathspec->count > 1)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
str = pathspec->strings[0];
|
|
||||||
if (!str || !str[0] || (!str[1] && (str[0] == '*' || str[0] == '.')))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool diff_path_matches_pathspec(git_diff_list *diff, const char *path)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
git_attr_fnmatch *match;
|
|
||||||
|
|
||||||
if (!diff->pathspec.length)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
git_vector_foreach(&diff->pathspec, i, match) {
|
|
||||||
int result = strcmp(match->pattern, path) ? FNM_NOMATCH : 0;
|
|
||||||
|
|
||||||
if (((diff->opts.flags & GIT_DIFF_DISABLE_PATHSPEC_MATCH) == 0) &&
|
|
||||||
result == FNM_NOMATCH)
|
|
||||||
result = p_fnmatch(match->pattern, path, 0);
|
|
||||||
|
|
||||||
/* if we didn't match, look for exact dirname prefix match */
|
|
||||||
if (result == FNM_NOMATCH &&
|
|
||||||
(match->flags & GIT_ATTR_FNMATCH_HASWILD) == 0 &&
|
|
||||||
strncmp(path, match->pattern, match->length) == 0 &&
|
|
||||||
path[match->length] == '/')
|
|
||||||
result = 0;
|
|
||||||
|
|
||||||
if (result == 0)
|
|
||||||
return (match->flags & GIT_ATTR_FNMATCH_NEGATIVE) ? false : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static git_diff_delta *diff_delta__alloc(
|
static git_diff_delta *diff_delta__alloc(
|
||||||
git_diff_list *diff,
|
git_diff_list *diff,
|
||||||
@ -125,7 +56,10 @@ static int diff_delta__from_one(
|
|||||||
(diff->opts.flags & GIT_DIFF_INCLUDE_UNTRACKED) == 0)
|
(diff->opts.flags & GIT_DIFF_INCLUDE_UNTRACKED) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!diff_path_matches_pathspec(diff, entry->path))
|
if (!git_pathspec_match_path(
|
||||||
|
&diff->pathspec, entry->path,
|
||||||
|
(diff->opts.flags & GIT_DIFF_DISABLE_PATHSPEC_MATCH) != 0,
|
||||||
|
(diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
delta = diff_delta__alloc(diff, status, entry->path);
|
delta = diff_delta__alloc(diff, status, entry->path);
|
||||||
@ -295,7 +229,6 @@ static git_diff_list *git_diff_list_alloc(
|
|||||||
git_repository *repo, const git_diff_options *opts)
|
git_repository *repo, const git_diff_options *opts)
|
||||||
{
|
{
|
||||||
git_config *cfg;
|
git_config *cfg;
|
||||||
size_t i;
|
|
||||||
git_diff_list *diff = git__calloc(1, sizeof(git_diff_list));
|
git_diff_list *diff = git__calloc(1, sizeof(git_diff_list));
|
||||||
if (diff == NULL)
|
if (diff == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -333,7 +266,10 @@ static git_diff_list *git_diff_list_alloc(
|
|||||||
return diff;
|
return diff;
|
||||||
|
|
||||||
memcpy(&diff->opts, opts, sizeof(git_diff_options));
|
memcpy(&diff->opts, opts, sizeof(git_diff_options));
|
||||||
memset(&diff->opts.pathspec, 0, sizeof(diff->opts.pathspec));
|
|
||||||
|
/* pathspec init will do nothing for empty pathspec */
|
||||||
|
if (git_pathspec_init(&diff->pathspec, &opts->pathspec, &diff->pool) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
/* TODO: handle config diff.mnemonicprefix, diff.noprefix */
|
/* TODO: handle config diff.mnemonicprefix, diff.noprefix */
|
||||||
|
|
||||||
@ -355,35 +291,6 @@ static git_diff_list *git_diff_list_alloc(
|
|||||||
if (diff->opts.flags & GIT_DIFF_INCLUDE_TYPECHANGE_TREES)
|
if (diff->opts.flags & GIT_DIFF_INCLUDE_TYPECHANGE_TREES)
|
||||||
diff->opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
|
diff->opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;
|
||||||
|
|
||||||
/* only copy pathspec if it is "interesting" so we can test
|
|
||||||
* diff->pathspec.length > 0 to know if it is worth calling
|
|
||||||
* fnmatch as we iterate.
|
|
||||||
*/
|
|
||||||
if (!diff_pathspec_is_interesting(&opts->pathspec))
|
|
||||||
return diff;
|
|
||||||
|
|
||||||
if (git_vector_init(
|
|
||||||
&diff->pathspec, (unsigned int)opts->pathspec.count, NULL) < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
for (i = 0; i < opts->pathspec.count; ++i) {
|
|
||||||
int ret;
|
|
||||||
const char *pattern = opts->pathspec.strings[i];
|
|
||||||
git_attr_fnmatch *match = git__calloc(1, sizeof(git_attr_fnmatch));
|
|
||||||
if (!match)
|
|
||||||
goto fail;
|
|
||||||
match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
|
|
||||||
ret = git_attr_fnmatch__parse(match, &diff->pool, NULL, &pattern);
|
|
||||||
if (ret == GIT_ENOTFOUND) {
|
|
||||||
git__free(match);
|
|
||||||
continue;
|
|
||||||
} else if (ret < 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (git_vector_insert(&diff->pathspec, match) < 0)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return diff;
|
return diff;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -394,7 +301,6 @@ fail:
|
|||||||
static void diff_list_free(git_diff_list *diff)
|
static void diff_list_free(git_diff_list *diff)
|
||||||
{
|
{
|
||||||
git_diff_delta *delta;
|
git_diff_delta *delta;
|
||||||
git_attr_fnmatch *match;
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
git_vector_foreach(&diff->deltas, i, delta) {
|
git_vector_foreach(&diff->deltas, i, delta) {
|
||||||
@ -403,12 +309,7 @@ static void diff_list_free(git_diff_list *diff)
|
|||||||
}
|
}
|
||||||
git_vector_free(&diff->deltas);
|
git_vector_free(&diff->deltas);
|
||||||
|
|
||||||
git_vector_foreach(&diff->pathspec, i, match) {
|
git_pathspec_free(&diff->pathspec);
|
||||||
git__free(match);
|
|
||||||
diff->pathspec.contents[i] = NULL;
|
|
||||||
}
|
|
||||||
git_vector_free(&diff->pathspec);
|
|
||||||
|
|
||||||
git_pool_clear(&diff->pool);
|
git_pool_clear(&diff->pool);
|
||||||
git__free(diff);
|
git__free(diff);
|
||||||
}
|
}
|
||||||
@ -499,7 +400,10 @@ static int maybe_modified(
|
|||||||
|
|
||||||
GIT_UNUSED(old_iter);
|
GIT_UNUSED(old_iter);
|
||||||
|
|
||||||
if (!diff_path_matches_pathspec(diff, oitem->path))
|
if (!git_pathspec_match_path(
|
||||||
|
&diff->pathspec, oitem->path,
|
||||||
|
(diff->opts.flags & GIT_DIFF_DISABLE_PATHSPEC_MATCH) != 0,
|
||||||
|
(diff->opts.flags & GIT_DIFF_DELTAS_ARE_ICASE) != 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* on platforms with no symlinks, preserve mode of existing symlinks */
|
/* on platforms with no symlinks, preserve mode of existing symlinks */
|
||||||
@ -842,15 +746,15 @@ int git_diff_tree_to_tree(
|
|||||||
git_diff_list **diff)
|
git_diff_list **diff)
|
||||||
{
|
{
|
||||||
git_iterator *a = NULL, *b = NULL;
|
git_iterator *a = NULL, *b = NULL;
|
||||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL;
|
||||||
|
|
||||||
assert(repo && old_tree && new_tree && diff);
|
assert(repo && old_tree && new_tree && diff);
|
||||||
|
|
||||||
if (git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix) < 0 ||
|
if (git_iterator_for_tree_range(&a, repo, old_tree, pfx, pfx) < 0 ||
|
||||||
git_iterator_for_tree_range(&b, repo, new_tree, prefix, prefix) < 0)
|
git_iterator_for_tree_range(&b, repo, new_tree, pfx, pfx) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
git__free(prefix);
|
git__free(pfx);
|
||||||
|
|
||||||
return diff_from_iterators(repo, opts, a, b, diff);
|
return diff_from_iterators(repo, opts, a, b, diff);
|
||||||
}
|
}
|
||||||
@ -862,20 +766,20 @@ int git_diff_index_to_tree(
|
|||||||
git_diff_list **diff)
|
git_diff_list **diff)
|
||||||
{
|
{
|
||||||
git_iterator *a = NULL, *b = NULL;
|
git_iterator *a = NULL, *b = NULL;
|
||||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL;
|
||||||
|
|
||||||
assert(repo && diff);
|
assert(repo && diff);
|
||||||
|
|
||||||
if (git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix) < 0 ||
|
if (git_iterator_for_tree_range(&a, repo, old_tree, pfx, pfx) < 0 ||
|
||||||
git_iterator_for_index_range(&b, repo, prefix, prefix) < 0)
|
git_iterator_for_index_range(&b, repo, pfx, pfx) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
git__free(prefix);
|
git__free(pfx);
|
||||||
|
|
||||||
return diff_from_iterators(repo, opts, a, b, diff);
|
return diff_from_iterators(repo, opts, a, b, diff);
|
||||||
|
|
||||||
on_error:
|
on_error:
|
||||||
git__free(prefix);
|
git__free(pfx);
|
||||||
git_iterator_free(a);
|
git_iterator_free(a);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -885,23 +789,22 @@ int git_diff_workdir_to_index(
|
|||||||
const git_diff_options *opts,
|
const git_diff_options *opts,
|
||||||
git_diff_list **diff)
|
git_diff_list **diff)
|
||||||
{
|
{
|
||||||
git_iterator *a = NULL, *b = NULL;
|
|
||||||
int error;
|
int error;
|
||||||
|
git_iterator *a = NULL, *b = NULL;
|
||||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL;
|
||||||
|
|
||||||
assert(repo && diff);
|
assert(repo && diff);
|
||||||
|
|
||||||
if ((error = git_iterator_for_index_range(&a, repo, prefix, prefix)) < 0 ||
|
if ((error = git_iterator_for_index_range(&a, repo, pfx, pfx)) < 0 ||
|
||||||
(error = git_iterator_for_workdir_range(&b, repo, prefix, prefix)) < 0)
|
(error = git_iterator_for_workdir_range(&b, repo, pfx, pfx)) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
git__free(prefix);
|
git__free(pfx);
|
||||||
|
|
||||||
return diff_from_iterators(repo, opts, a, b, diff);
|
return diff_from_iterators(repo, opts, a, b, diff);
|
||||||
|
|
||||||
on_error:
|
on_error:
|
||||||
git__free(prefix);
|
git__free(pfx);
|
||||||
git_iterator_free(a);
|
git_iterator_free(a);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -910,26 +813,25 @@ on_error:
|
|||||||
int git_diff_workdir_to_tree(
|
int git_diff_workdir_to_tree(
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
const git_diff_options *opts,
|
const git_diff_options *opts,
|
||||||
git_tree *old_tree,
|
git_tree *tree,
|
||||||
git_diff_list **diff)
|
git_diff_list **diff)
|
||||||
{
|
{
|
||||||
git_iterator *a = NULL, *b = NULL;
|
|
||||||
int error;
|
int error;
|
||||||
|
git_iterator *a = NULL, *b = NULL;
|
||||||
|
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL;
|
||||||
|
|
||||||
char *prefix = opts ? diff_prefix_from_pathspec(&opts->pathspec) : NULL;
|
assert(repo && tree && diff);
|
||||||
|
|
||||||
assert(repo && old_tree && diff);
|
if ((error = git_iterator_for_tree_range(&a, repo, tree, pfx, pfx)) < 0 ||
|
||||||
|
(error = git_iterator_for_workdir_range(&b, repo, pfx, pfx)) < 0)
|
||||||
if ((error = git_iterator_for_tree_range(&a, repo, old_tree, prefix, prefix)) < 0 ||
|
|
||||||
(error = git_iterator_for_workdir_range(&b, repo, prefix, prefix)) < 0)
|
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
git__free(prefix);
|
git__free(pfx);
|
||||||
|
|
||||||
return diff_from_iterators(repo, opts, a, b, diff);
|
return diff_from_iterators(repo, opts, a, b, diff);
|
||||||
|
|
||||||
on_error:
|
on_error:
|
||||||
git__free(prefix);
|
git__free(pfx);
|
||||||
git_iterator_free(a);
|
git_iterator_free(a);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
151
src/pathspec.c
Normal file
151
src/pathspec.c
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pathspec.h"
|
||||||
|
#include "attr_file.h"
|
||||||
|
|
||||||
|
/* what is the common non-wildcard prefix for all items in the pathspec */
|
||||||
|
char *git_pathspec_prefix(const git_strarray *pathspec)
|
||||||
|
{
|
||||||
|
git_buf prefix = GIT_BUF_INIT;
|
||||||
|
const char *scan;
|
||||||
|
|
||||||
|
if (!pathspec || !pathspec->count ||
|
||||||
|
git_buf_common_prefix(&prefix, pathspec) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* diff prefix will only be leading non-wildcards */
|
||||||
|
for (scan = prefix.ptr; *scan; ++scan) {
|
||||||
|
if (git__iswildcard(*scan) &&
|
||||||
|
(scan == prefix.ptr || (*(scan - 1) != '\\')))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
git_buf_truncate(&prefix, scan - prefix.ptr);
|
||||||
|
|
||||||
|
if (prefix.size <= 0) {
|
||||||
|
git_buf_free(&prefix);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_buf_unescape(&prefix);
|
||||||
|
|
||||||
|
return git_buf_detach(&prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* is there anything in the spec that needs to be filtered on */
|
||||||
|
bool git_pathspec_is_interesting(const git_strarray *pathspec)
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
|
||||||
|
if (pathspec == NULL || pathspec->count == 0)
|
||||||
|
return false;
|
||||||
|
if (pathspec->count > 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
str = pathspec->strings[0];
|
||||||
|
if (!str || !str[0] || (!str[1] && (str[0] == '*' || str[0] == '.')))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build a vector of fnmatch patterns to evaluate efficiently */
|
||||||
|
int git_pathspec_init(
|
||||||
|
git_vector *vspec, const git_strarray *strspec, git_pool *strpool)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
memset(vspec, 0, sizeof(*vspec));
|
||||||
|
|
||||||
|
if (!git_pathspec_is_interesting(strspec))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (git_vector_init(vspec, strspec->count, NULL) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < strspec->count; ++i) {
|
||||||
|
int ret;
|
||||||
|
const char *pattern = strspec->strings[i];
|
||||||
|
git_attr_fnmatch *match = git__calloc(1, sizeof(git_attr_fnmatch));
|
||||||
|
if (!match)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
|
||||||
|
|
||||||
|
ret = git_attr_fnmatch__parse(match, strpool, NULL, &pattern);
|
||||||
|
if (ret == GIT_ENOTFOUND) {
|
||||||
|
git__free(match);
|
||||||
|
continue;
|
||||||
|
} else if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (git_vector_insert(vspec, match) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free data from the pathspec vector */
|
||||||
|
void git_pathspec_free(git_vector *vspec)
|
||||||
|
{
|
||||||
|
git_attr_fnmatch *match;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
git_vector_foreach(vspec, i, match) {
|
||||||
|
git__free(match);
|
||||||
|
vspec->contents[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_vector_free(vspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* match a path against the vectorized pathspec */
|
||||||
|
bool git_pathspec_match_path(
|
||||||
|
git_vector *vspec, const char *path, bool disable_fnmatch, bool casefold)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
git_attr_fnmatch *match;
|
||||||
|
int fnmatch_flags = 0;
|
||||||
|
int (*use_strcmp)(const char *, const char *);
|
||||||
|
int (*use_strncmp)(const char *, const char *, size_t);
|
||||||
|
|
||||||
|
if (!vspec || !vspec->length)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (disable_fnmatch)
|
||||||
|
fnmatch_flags = -1;
|
||||||
|
else if (casefold)
|
||||||
|
fnmatch_flags = FNM_CASEFOLD;
|
||||||
|
|
||||||
|
if (casefold) {
|
||||||
|
use_strcmp = strcasecmp;
|
||||||
|
use_strncmp = strncasecmp;
|
||||||
|
} else {
|
||||||
|
use_strcmp = strcmp;
|
||||||
|
use_strncmp = strncmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_vector_foreach(vspec, i, match) {
|
||||||
|
int result = use_strcmp(match->pattern, path) ? FNM_NOMATCH : 0;
|
||||||
|
|
||||||
|
if (fnmatch_flags >= 0 && result == FNM_NOMATCH)
|
||||||
|
result = p_fnmatch(match->pattern, path, fnmatch_flags);
|
||||||
|
|
||||||
|
/* if we didn't match, look for exact dirname prefix match */
|
||||||
|
if (result == FNM_NOMATCH &&
|
||||||
|
(match->flags & GIT_ATTR_FNMATCH_HASWILD) == 0 &&
|
||||||
|
use_strncmp(path, match->pattern, match->length) == 0 &&
|
||||||
|
path[match->length] == '/')
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
if (result == 0)
|
||||||
|
return (match->flags & GIT_ATTR_FNMATCH_NEGATIVE) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
32
src/pathspec.h
Normal file
32
src/pathspec.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011-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_pathspec_h__
|
||||||
|
#define INCLUDE_pathspec_h__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "vector.h"
|
||||||
|
#include "pool.h"
|
||||||
|
|
||||||
|
/* what is the common non-wildcard prefix for all items in the pathspec */
|
||||||
|
extern char *git_pathspec_prefix(const git_strarray *pathspec);
|
||||||
|
|
||||||
|
/* is there anything in the spec that needs to be filtered on */
|
||||||
|
extern bool git_pathspec_is_interesting(const git_strarray *pathspec);
|
||||||
|
|
||||||
|
/* build a vector of fnmatch patterns to evaluate efficiently */
|
||||||
|
extern int git_pathspec_init(
|
||||||
|
git_vector *vspec, const git_strarray *strspec, git_pool *strpool);
|
||||||
|
|
||||||
|
/* free data from the pathspec vector */
|
||||||
|
extern void git_pathspec_free(git_vector *vspec);
|
||||||
|
|
||||||
|
/* match a path against the vectorized pathspec */
|
||||||
|
extern bool git_pathspec_match_path(
|
||||||
|
git_vector *vspec, const char *path, bool disable_fnmatch, bool casefold);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user