From a1773f9d89887d299248d15b43953d3fa494a025 Mon Sep 17 00:00:00 2001 From: yorah Date: Mon, 23 Jul 2012 18:16:09 +0200 Subject: [PATCH] Add flag to turn off pathspec testing for diff and status --- include/git2/diff.h | 1 + include/git2/status.h | 3 +++ src/diff.c | 5 ++-- src/status.c | 2 ++ tests-clar/status/worktree.c | 46 ++++++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/include/git2/diff.h b/include/git2/diff.h index edec9957b..85727d969 100644 --- a/include/git2/diff.h +++ b/include/git2/diff.h @@ -46,6 +46,7 @@ enum { GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8), GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9), GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10), + GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11), }; /** diff --git a/include/git2/status.h b/include/git2/status.h index 69b6e47e0..9e7b5de4a 100644 --- a/include/git2/status.h +++ b/include/git2/status.h @@ -96,6 +96,8 @@ typedef enum { * 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. + * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given + * path will be treated as a literal path, and not as a pathspec. */ enum { @@ -104,6 +106,7 @@ enum { GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2), GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1 << 3), GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4), + GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1 << 5), }; /** diff --git a/src/diff.c b/src/diff.c index f08688e38..2b1529d63 100644 --- a/src/diff.c +++ b/src/diff.c @@ -61,9 +61,10 @@ static bool diff_path_matches_pathspec(git_diff_list *diff, const char *path) return true; 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); /* if we didn't match, look for exact dirname prefix match */ diff --git a/src/status.c b/src/status.c index 633082c09..d78237689 100644 --- a/src/status.c +++ b/src/status.c @@ -99,6 +99,8 @@ int git_status_foreach_ext( diffopt.flags = diffopt.flags | GIT_DIFF_INCLUDE_UNMODIFIED; if ((opts->flags & GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS) != 0) 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 */ if (show != GIT_STATUS_SHOW_WORKDIR_ONLY && diff --git a/tests-clar/status/worktree.c b/tests-clar/status/worktree.c index 1bdd8160a..bd57cf2b6 100644 --- a/tests-clar/status/worktree.c +++ b/tests-clar/status/worktree.c @@ -726,3 +726,49 @@ void test_status_worktree__filemode_changes(void) 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); +}