diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2015-09-12 22:49:23 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2015-09-12 22:49:23 +0200 |
commit | dc5b678fda918386f01630d2bc928edb546ac4f2 (patch) | |
tree | d06b61174453c1167615a2c12ac1254d6e90b0c4 | |
parent | 049dbf42f50a7d04db5ab99577455b8933e3d532 (diff) | |
parent | 8ab4d0e1e16bf42e4617a40a13d67385fc8fa40c (diff) | |
download | libgit2-dc5b678fda918386f01630d2bc928edb546ac4f2.tar.gz |
Merge pull request #3422 from ethomson/workdir_diff
diff: examine pathlist on non-files
-rw-r--r-- | src/diff.c | 25 | ||||
-rw-r--r-- | tests/diff/workdir.c | 43 |
2 files changed, 60 insertions, 8 deletions
diff --git a/src/diff.c b/src/diff.c index 32c1d4aa5..d97dcd9d2 100644 --- a/src/diff.c +++ b/src/diff.c @@ -75,18 +75,27 @@ static int diff_insert_delta( } static bool diff_pathspec_match( - const char **matched_pathspec, git_diff *diff, const char *path) + const char **matched_pathspec, + git_diff *diff, + const git_index_entry *entry) { - /* The iterator has filtered out paths for us, so the fact that we're - * seeing this patch means that it must match the given path list. + bool disable_pathspec_match = + DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH); + + /* If we're disabling fnmatch, then the iterator has already applied + * the filters to the files for us and we don't have to do anything. + * However, this only applies to *files* - the iterator will include + * directories that we need to recurse into when not autoexpanding, + * so we still need to apply the pathspec match to directories. */ - if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_DISABLE_PATHSPEC_MATCH)) { - *matched_pathspec = path; + if ((S_ISLNK(entry->mode) || S_ISREG(entry->mode)) && + disable_pathspec_match) { + *matched_pathspec = entry->path; return true; } return git_pathspec__match( - &diff->pathspec, path, false, + &diff->pathspec, entry->path, disable_pathspec_match, DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE), matched_pathspec, NULL); } @@ -127,7 +136,7 @@ static int diff_delta__from_one( DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNREADABLE)) return 0; - if (!diff_pathspec_match(&matched_pathspec, diff, entry->path)) + if (!diff_pathspec_match(&matched_pathspec, diff, entry)) return 0; delta = diff_delta__alloc(diff, status, entry->path); @@ -768,7 +777,7 @@ static int maybe_modified( const char *matched_pathspec; int error = 0; - if (!diff_pathspec_match(&matched_pathspec, diff, oitem->path)) + if (!diff_pathspec_match(&matched_pathspec, diff, oitem)) return 0; memset(&noid, 0, sizeof(noid)); diff --git a/tests/diff/workdir.c b/tests/diff/workdir.c index e87769170..89f9483a6 100644 --- a/tests/diff/workdir.c +++ b/tests/diff/workdir.c @@ -2054,3 +2054,46 @@ void test_diff_workdir__only_writes_index_when_necessary(void) git_index_free(index); } +void test_diff_workdir__to_index_pathlist(void) +{ + git_index *index; + git_diff *diff; + git_diff_options opts = GIT_DIFF_OPTIONS_INIT; + git_vector pathlist = GIT_VECTOR_INIT; + + git_vector_insert(&pathlist, "foobar/asdf"); + git_vector_insert(&pathlist, "subdir/asdf"); + git_vector_insert(&pathlist, "ignored/asdf"); + + g_repo = cl_git_sandbox_init("status"); + + cl_git_mkfile("status/.gitignore", ".gitignore\n" "ignored/\n"); + + cl_must_pass(p_mkdir("status/foobar", 0777)); + cl_git_mkfile("status/foobar/one", "one\n"); + + cl_must_pass(p_mkdir("status/ignored", 0777)); + cl_git_mkfile("status/ignored/one", "one\n"); + cl_git_mkfile("status/ignored/two", "two\n"); + cl_git_mkfile("status/ignored/three", "three\n"); + + cl_git_pass(git_repository_index(&index, g_repo)); + + opts.flags = GIT_DIFF_INCLUDE_IGNORED; + opts.pathspec.strings = pathlist.contents; + opts.pathspec.count = pathlist.length; + + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, &opts)); + cl_assert_equal_i(0, git_diff_num_deltas(diff)); + git_diff_free(diff); + + opts.flags |= GIT_DIFF_DISABLE_PATHSPEC_MATCH; + + cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, &opts)); + cl_assert_equal_i(0, git_diff_num_deltas(diff)); + git_diff_free(diff); + + git_index_free(index); + git_vector_free(&pathlist); +} + |