Commit a1773f9d by yorah

Add flag to turn off pathspec testing for diff and status

parent ffbc689c
...@@ -46,6 +46,7 @@ enum { ...@@ -46,6 +46,7 @@ enum {
GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8), GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8),
GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9), GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9),
GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10), GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10),
GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11),
}; };
/** /**
......
...@@ -96,6 +96,8 @@ typedef enum { ...@@ -96,6 +96,8 @@ typedef enum {
* the top-level directory will be included (with a trailing * the top-level directory will be included (with a trailing
* slash on the entry name). Given this flag, the directory * slash on the entry name). Given this flag, the directory
* itself will not be included, but all the files in it will. * itself will not be included, but all the files in it will.
* - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given
* path will be treated as a literal path, and not as a pathspec.
*/ */
enum { enum {
...@@ -104,6 +106,7 @@ enum { ...@@ -104,6 +106,7 @@ enum {
GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2), GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2),
GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1 << 3), GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1 << 3),
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4), GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4),
GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1 << 5),
}; };
/** /**
......
...@@ -61,9 +61,10 @@ static bool diff_path_matches_pathspec(git_diff_list *diff, const char *path) ...@@ -61,9 +61,10 @@ static bool diff_path_matches_pathspec(git_diff_list *diff, const char *path)
return true; return true;
git_vector_foreach(&diff->pathspec, i, match) { git_vector_foreach(&diff->pathspec, i, match) {
int result = strcmp(match->pattern, path); int result = strcmp(match->pattern, path) ? FNM_NOMATCH : 0;
if (result != 0) if (((diff->opts.flags & GIT_DIFF_DISABLE_PATHSPEC_MATCH) == 0) &&
result == FNM_NOMATCH)
result = p_fnmatch(match->pattern, path, 0); result = p_fnmatch(match->pattern, path, 0);
/* if we didn't match, look for exact dirname prefix match */ /* if we didn't match, look for exact dirname prefix match */
......
...@@ -99,6 +99,8 @@ int git_status_foreach_ext( ...@@ -99,6 +99,8 @@ int git_status_foreach_ext(
diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNMODIFIED; diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNMODIFIED;
if ((opts->flags & GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS) != 0) if ((opts->flags & GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS) != 0)
diffopt.flags = diffopt.flags | GIT_DIFF_RECURSE_UNTRACKED_DIRS; diffopt.flags = diffopt.flags | GIT_DIFF_RECURSE_UNTRACKED_DIRS;
if ((opts->flags & GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH) != 0)
diffopt.flags = diffopt.flags | GIT_DIFF_DISABLE_PATHSPEC_MATCH;
/* TODO: support EXCLUDE_SUBMODULES flag */ /* TODO: support EXCLUDE_SUBMODULES flag */
if (show != GIT_STATUS_SHOW_WORKDIR_ONLY && if (show != GIT_STATUS_SHOW_WORKDIR_ONLY &&
......
...@@ -726,3 +726,49 @@ void test_status_worktree__filemode_changes(void) ...@@ -726,3 +726,49 @@ void test_status_worktree__filemode_changes(void)
git_config_free(cfg); git_config_free(cfg);
} }
int cb_status__expected_path(const char *p, unsigned int s, void *payload)
{
const char *expected_path = (const char *)payload;
GIT_UNUSED(s);
if (payload == NULL)
cl_fail("Unexpected path");
cl_assert_equal_s(expected_path, p);
return 0;
}
void test_status_worktree__disable_pathspec_match(void)
{
git_repository *repo;
git_status_options opts;
char *file_with_bracket = "LICENSE[1].md",
*imaginary_file_with_bracket = "LICENSE[1-2].md";
cl_git_pass(git_repository_init(&repo, "pathspec", 0));
cl_git_mkfile("pathspec/LICENSE[1].md", "screaming bracket\n");
cl_git_mkfile("pathspec/LICENSE1.md", "no bracket\n");
memset(&opts, 0, sizeof(opts));
opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH;
opts.pathspec.count = 1;
opts.pathspec.strings = &file_with_bracket;
cl_git_pass(
git_status_foreach_ext(repo, &opts, cb_status__expected_path,
file_with_bracket)
);
/* Test passing a pathspec matching files in the workdir. */
/* Must not match because pathspecs are disabled. */
opts.pathspec.strings = &imaginary_file_with_bracket;
cl_git_pass(
git_status_foreach_ext(repo, &opts, cb_status__expected_path, NULL)
);
git_repository_free(repo);
}
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