mirror of
https://git.proxmox.com/git/libgit2
synced 2025-10-14 15:29:14 +00:00
Merge pull request #3422 from ethomson/workdir_diff
diff: examine pathlist on non-files
This commit is contained in:
commit
dc5b678fda
25
src/diff.c
25
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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user