mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-02 22:54:15 +00:00
diff: better document GIT_DIFF_PATHSPEC_DISABLE
Document that `GIT_DIFF_PATHSPEC_DISABLE` is not necessarily about explicit path matching, but also includes matching of directory names. Enforce this in a test.
This commit is contained in:
parent
6c9352bf30
commit
3273ab3f0b
@ -130,7 +130,9 @@ typedef enum {
|
||||
GIT_DIFF_INCLUDE_CASECHANGE = (1u << 11),
|
||||
|
||||
/** If the pathspec is set in the diff options, this flags means to
|
||||
* apply it as an exact match instead of as an fnmatch pattern.
|
||||
* use exact prefix matches instead of an fnmatch pattern. Each
|
||||
* path in the list must either be a full filename or a subdirectory
|
||||
* prefix.
|
||||
*/
|
||||
GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1u << 12),
|
||||
|
||||
|
@ -444,6 +444,216 @@ void test_diff_workdir__to_index_with_pathspec(void)
|
||||
git_diff_free(diff);
|
||||
}
|
||||
|
||||
void test_diff_workdir__to_index_with_pathlist_disabling_fnmatch(void)
|
||||
{
|
||||
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
|
||||
git_diff *diff = NULL;
|
||||
diff_expects exp;
|
||||
char *pathspec = NULL;
|
||||
int use_iterator;
|
||||
|
||||
g_repo = cl_git_sandbox_init("status");
|
||||
|
||||
opts.context_lines = 3;
|
||||
opts.interhunk_lines = 1;
|
||||
opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED |
|
||||
GIT_DIFF_DISABLE_PATHSPEC_MATCH;
|
||||
opts.pathspec.strings = &pathspec;
|
||||
opts.pathspec.count = 0;
|
||||
|
||||
/* ensure that an empty pathspec list is ignored */
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||
|
||||
for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
if (use_iterator)
|
||||
cl_git_pass(diff_foreach_via_iterator(
|
||||
diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
else
|
||||
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
|
||||
cl_assert_equal_i(13, exp.files);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
}
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
/* ensure that a single NULL pathspec is filtered out (like when using
|
||||
* fnmatch filtering)
|
||||
*/
|
||||
opts.pathspec.strings = &pathspec;
|
||||
opts.pathspec.count = 1;
|
||||
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||
|
||||
for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
if (use_iterator)
|
||||
cl_git_pass(diff_foreach_via_iterator(
|
||||
diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
else
|
||||
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
|
||||
cl_assert_equal_i(13, exp.files);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
}
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
pathspec = "modified_file";
|
||||
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||
|
||||
for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
if (use_iterator)
|
||||
cl_git_pass(diff_foreach_via_iterator(
|
||||
diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
else
|
||||
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
|
||||
cl_assert_equal_i(1, exp.files);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
}
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
/* ensure that subdirs can be specified */
|
||||
pathspec = "subdir";
|
||||
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||
|
||||
for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
if (use_iterator)
|
||||
cl_git_pass(diff_foreach_via_iterator(
|
||||
diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
else
|
||||
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
|
||||
cl_assert_equal_i(3, exp.files);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
}
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
/* ensure that subdirs can be specified with a trailing slash */
|
||||
pathspec = "subdir/";
|
||||
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||
|
||||
for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
if (use_iterator)
|
||||
cl_git_pass(diff_foreach_via_iterator(
|
||||
diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
else
|
||||
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
|
||||
cl_assert_equal_i(3, exp.files);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
}
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
/* ensure that fnmatching is completely disabled */
|
||||
pathspec = "subdir/*";
|
||||
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||
|
||||
for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
if (use_iterator)
|
||||
cl_git_pass(diff_foreach_via_iterator(
|
||||
diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
else
|
||||
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
|
||||
cl_assert_equal_i(0, exp.files);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
}
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
/* ensure that the prefix matching isn't completely braindead */
|
||||
pathspec = "subdi";
|
||||
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||
|
||||
for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
if (use_iterator)
|
||||
cl_git_pass(diff_foreach_via_iterator(
|
||||
diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
else
|
||||
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
|
||||
cl_assert_equal_i(0, exp.files);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
}
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
/* ensure that fnmatching isn't working at all */
|
||||
pathspec = "*_deleted";
|
||||
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||
|
||||
for (use_iterator = 0; use_iterator <= 1; use_iterator++) {
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
if (use_iterator)
|
||||
cl_git_pass(diff_foreach_via_iterator(
|
||||
diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
else
|
||||
cl_git_pass(git_diff_foreach(diff, diff_file_cb, NULL, NULL, NULL, &exp));
|
||||
|
||||
cl_assert_equal_i(0, exp.files);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(0, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
}
|
||||
|
||||
git_diff_free(diff);
|
||||
}
|
||||
|
||||
void test_diff_workdir__filemode_changes(void)
|
||||
{
|
||||
git_diff *diff = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user