1 #include "clar_libgit2.h"
2 #include "repository.h"
4 #include "diff_helpers.h"
5 #include "../submodule/submodule_helpers.h"
7 static git_repository
*g_repo
= NULL
;
9 void test_diff_submodules__initialize(void)
13 void test_diff_submodules__cleanup(void)
15 cl_git_sandbox_cleanup();
18 #define get_buf_ptr(buf) ((buf)->asize ? (buf)->ptr : NULL)
20 static void check_diff_patches_at_line(
21 git_diff
*diff
, const char **expected
,
22 const char *file
, const char *func
, int line
)
24 const git_diff_delta
*delta
;
25 git_patch
*patch
= NULL
;
26 size_t d
, num_d
= git_diff_num_deltas(diff
);
27 git_buf buf
= GIT_BUF_INIT
;
29 for (d
= 0; d
< num_d
; ++d
, git_patch_free(patch
)) {
30 cl_git_pass(git_patch_from_diff(&patch
, diff
, d
));
31 cl_assert((delta
= git_patch_get_delta(patch
)) != NULL
);
33 if (delta
->status
== GIT_DELTA_UNMODIFIED
) {
34 cl_assert_at_line(expected
[d
] == NULL
, file
, func
, line
);
38 if (expected
[d
] && !strcmp(expected
[d
], "<SKIP>"))
40 if (expected
[d
] && !strcmp(expected
[d
], "<UNTRACKED>")) {
41 cl_assert_at_line(delta
->status
== GIT_DELTA_UNTRACKED
, file
, func
, line
);
44 if (expected
[d
] && !strcmp(expected
[d
], "<END>")) {
45 cl_git_pass(git_patch_to_buf(&buf
, patch
));
46 cl_assert_at_line(!strcmp(expected
[d
], "<END>"), file
, func
, line
);
49 cl_git_pass(git_patch_to_buf(&buf
, patch
));
52 file
, func
, line
, "expected diff did not match actual diff", 1,
53 "%s", expected
[d
], get_buf_ptr(&buf
));
54 git_buf_dispose(&buf
);
57 cl_assert_at_line(expected
[d
] && !strcmp(expected
[d
], "<END>"), file
, func
, line
);
60 #define check_diff_patches(diff, exp) \
61 check_diff_patches_at_line(diff, exp, __FILE__, __func__, __LINE__)
63 void test_diff_submodules__unmodified_submodule(void)
65 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
66 git_diff
*diff
= NULL
;
67 static const char *expected
[] = {
68 "<SKIP>", /* .gitmodules */
71 "diff --git a/modified b/modified\nindex 092bfb9..452216e 100644\n--- a/modified\n+++ b/modified\n@@ -1 +1,2 @@\n-yo\n+changed\n+\n", /* modified */
72 NULL
, /* testrepo.git */
73 NULL
, /* unmodified */
78 g_repo
= setup_fixture_submodules();
80 opts
.flags
= GIT_DIFF_INCLUDE_IGNORED
|
81 GIT_DIFF_INCLUDE_UNTRACKED
|
82 GIT_DIFF_INCLUDE_UNMODIFIED
;
83 opts
.old_prefix
= "a"; opts
.new_prefix
= "b";
85 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
86 check_diff_patches(diff
, expected
);
90 void test_diff_submodules__dirty_submodule(void)
92 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
93 git_diff
*diff
= NULL
;
94 static const char *expected
[] = {
95 "<SKIP>", /* .gitmodules */
98 "diff --git a/modified b/modified\nindex 092bfb9..452216e 100644\n--- a/modified\n+++ b/modified\n@@ -1 +1,2 @@\n-yo\n+changed\n+\n", /* modified */
99 "diff --git a/testrepo b/testrepo\nindex a65fedf..a65fedf 160000\n--- a/testrepo\n+++ b/testrepo\n@@ -1 +1 @@\n-Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750\n+Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750-dirty\n", /* testrepo.git */
100 NULL
, /* unmodified */
101 NULL
, /* untracked */
105 g_repo
= setup_fixture_submodules();
107 cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
108 cl_git_mkfile("submodules/testrepo/all_new.txt", "never seen before");
110 opts
.flags
= GIT_DIFF_INCLUDE_IGNORED
|
111 GIT_DIFF_INCLUDE_UNTRACKED
|
112 GIT_DIFF_INCLUDE_UNMODIFIED
;
113 opts
.old_prefix
= "a"; opts
.new_prefix
= "b";
115 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
116 check_diff_patches(diff
, expected
);
120 void test_diff_submodules__dirty_submodule_2(void)
122 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
123 git_diff
*diff
= NULL
, *diff2
= NULL
;
124 char *smpath
= "testrepo";
125 static const char *expected_none
[] = {
128 static const char *expected_dirty
[] = {
129 "diff --git a/testrepo b/testrepo\nindex a65fedf..a65fedf 160000\n--- a/testrepo\n+++ b/testrepo\n@@ -1 +1 @@\n-Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750\n+Subproject commit a65fedf39aefe402d3bb6e24df4d4f5fe4547750-dirty\n", /* testrepo.git */
133 g_repo
= setup_fixture_submodules();
135 opts
.flags
= GIT_DIFF_INCLUDE_UNTRACKED
|
136 GIT_DIFF_SHOW_UNTRACKED_CONTENT
|
137 GIT_DIFF_RECURSE_UNTRACKED_DIRS
|
138 GIT_DIFF_DISABLE_PATHSPEC_MATCH
;
139 opts
.old_prefix
= "a"; opts
.new_prefix
= "b";
140 opts
.pathspec
.count
= 1;
141 opts
.pathspec
.strings
= &smpath
;
143 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
144 check_diff_patches(diff
, expected_none
);
147 cl_git_rewritefile("submodules/testrepo/README", "heyheyhey");
148 cl_git_mkfile("submodules/testrepo/all_new.txt", "never seen before");
150 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
151 check_diff_patches(diff
, expected_dirty
);
156 cl_git_pass(git_repository_head_tree(&head
, g_repo
));
157 cl_git_pass(git_diff_tree_to_index(&diff2
, g_repo
, head
, NULL
, &opts
));
158 cl_git_pass(git_diff_merge(diff
, diff2
));
159 git_diff_free(diff2
);
162 check_diff_patches(diff
, expected_dirty
);
167 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
168 check_diff_patches(diff
, expected_dirty
);
172 void test_diff_submodules__submod2_index_to_wd(void)
174 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
175 git_diff
*diff
= NULL
;
176 static const char *expected
[] = {
177 "<SKIP>", /* .gitmodules */
178 "<UNTRACKED>", /* not-submodule */
179 "<UNTRACKED>", /* not */
180 "diff --git a/sm_changed_file b/sm_changed_file\nindex 4800958..4800958 160000\n--- a/sm_changed_file\n+++ b/sm_changed_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_file */
181 "diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
182 "<UNTRACKED>", /* sm_changed_head- */
183 "<UNTRACKED>", /* sm_changed_head_ */
184 "diff --git a/sm_changed_index b/sm_changed_index\nindex 4800958..4800958 160000\n--- a/sm_changed_index\n+++ b/sm_changed_index\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_index */
185 "diff --git a/sm_changed_untracked_file b/sm_changed_untracked_file\nindex 4800958..4800958 160000\n--- a/sm_changed_untracked_file\n+++ b/sm_changed_untracked_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_untracked_file */
186 "diff --git a/sm_missing_commits b/sm_missing_commits\nindex 4800958..5e49635 160000\n--- a/sm_missing_commits\n+++ b/sm_missing_commits\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 5e4963595a9774b90524d35a807169049de8ccad\n", /* sm_missing_commits */
190 g_repo
= setup_fixture_submod2();
192 /* bracket existing submodule with similarly named items */
193 cl_git_mkfile("submod2/sm_changed_head-", "hello");
194 cl_git_mkfile("submod2/sm_changed_head_", "hello");
196 opts
.flags
= GIT_DIFF_INCLUDE_UNTRACKED
;
197 opts
.old_prefix
= "a"; opts
.new_prefix
= "b";
199 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
200 check_diff_patches(diff
, expected
);
204 void test_diff_submodules__submod2_head_to_index(void)
206 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
208 git_diff
*diff
= NULL
;
209 static const char *expected
[] = {
210 "<SKIP>", /* .gitmodules */
211 "diff --git a/sm_added_and_uncommited b/sm_added_and_uncommited\nnew file mode 160000\nindex 0000000..4800958\n--- /dev/null\n+++ b/sm_added_and_uncommited\n@@ -0,0 +1 @@\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n", /* sm_added_and_uncommited */
215 g_repo
= setup_fixture_submod2();
217 cl_git_pass(git_repository_head_tree(&head
, g_repo
));
219 opts
.flags
= GIT_DIFF_INCLUDE_UNTRACKED
;
220 opts
.old_prefix
= "a"; opts
.new_prefix
= "b";
222 cl_git_pass(git_diff_tree_to_index(&diff
, g_repo
, head
, NULL
, &opts
));
223 check_diff_patches(diff
, expected
);
229 void test_diff_submodules__invalid_cache(void)
231 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
232 git_diff
*diff
= NULL
;
234 char *smpath
= "sm_changed_head";
235 git_repository
*smrepo
;
237 static const char *expected_baseline
[] = {
238 "diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
241 static const char *expected_unchanged
[] = { "<END>" };
242 static const char *expected_dirty
[] = {
243 "diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247-dirty\n",
246 static const char *expected_moved
[] = {
247 "diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..7002348 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 700234833f6ccc20d744b238612646be071acaae\n",
250 static const char *expected_moved_dirty
[] = {
251 "diff --git a/sm_changed_head b/sm_changed_head\nindex 3d9386c..7002348 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n+Subproject commit 700234833f6ccc20d744b238612646be071acaae-dirty\n",
255 g_repo
= setup_fixture_submod2();
257 opts
.flags
= GIT_DIFF_INCLUDE_UNTRACKED
;
258 opts
.old_prefix
= "a"; opts
.new_prefix
= "b";
259 opts
.pathspec
.count
= 1;
260 opts
.pathspec
.strings
= &smpath
;
263 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
264 check_diff_patches(diff
, expected_baseline
);
267 /* update index with new HEAD */
268 cl_git_pass(git_submodule_lookup(&sm
, g_repo
, smpath
));
269 cl_git_pass(git_submodule_add_to_index(sm
, 1));
271 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
272 check_diff_patches(diff
, expected_unchanged
);
275 /* create untracked file in submodule working directory */
276 cl_git_mkfile("submod2/sm_changed_head/new_around_here", "hello");
277 git_submodule_set_ignore(g_repo
, git_submodule_name(sm
), GIT_SUBMODULE_IGNORE_NONE
);
279 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
280 check_diff_patches(diff
, expected_dirty
);
283 git_submodule_set_ignore(g_repo
, git_submodule_name(sm
), GIT_SUBMODULE_IGNORE_UNTRACKED
);
285 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
286 check_diff_patches(diff
, expected_unchanged
);
289 /* modify tracked file in submodule working directory */
291 "submod2/sm_changed_head/file_to_modify", "\nmore stuff\n");
293 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
294 check_diff_patches(diff
, expected_dirty
);
297 git_submodule_free(sm
);
299 cl_git_pass(git_submodule_lookup(&sm
, g_repo
, smpath
));
301 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
302 check_diff_patches(diff
, expected_dirty
);
305 git_submodule_set_ignore(g_repo
, git_submodule_name(sm
), GIT_SUBMODULE_IGNORE_DIRTY
);
307 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
308 check_diff_patches(diff
, expected_unchanged
);
311 /* add file to index in submodule */
312 cl_git_pass(git_submodule_open(&smrepo
, sm
));
313 cl_git_pass(git_repository_index(&smindex
, smrepo
));
314 cl_git_pass(git_index_add_bypath(smindex
, "file_to_modify"));
316 git_submodule_set_ignore(g_repo
, git_submodule_name(sm
), GIT_SUBMODULE_IGNORE_UNTRACKED
);
318 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
319 check_diff_patches(diff
, expected_dirty
);
322 git_submodule_set_ignore(g_repo
, git_submodule_name(sm
), GIT_SUBMODULE_IGNORE_DIRTY
);
324 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
325 check_diff_patches(diff
, expected_unchanged
);
328 /* commit changed index of submodule */
329 cl_repo_commit_from_index(NULL
, smrepo
, NULL
, 1372350000, "Move it");
331 git_submodule_set_ignore(g_repo
, git_submodule_name(sm
), GIT_SUBMODULE_IGNORE_DIRTY
);
333 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
334 check_diff_patches(diff
, expected_moved
);
337 git_submodule_set_ignore(g_repo
, git_submodule_name(sm
), GIT_SUBMODULE_IGNORE_ALL
);
339 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
340 check_diff_patches(diff
, expected_unchanged
);
343 git_submodule_set_ignore(g_repo
, git_submodule_name(sm
), GIT_SUBMODULE_IGNORE_NONE
);
345 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
346 check_diff_patches(diff
, expected_moved_dirty
);
349 p_unlink("submod2/sm_changed_head/new_around_here");
351 git_submodule_free(sm
);
353 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
354 check_diff_patches(diff
, expected_moved
);
357 git_index_free(smindex
);
358 git_repository_free(smrepo
);
361 void test_diff_submodules__diff_ignore_options(void)
363 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
364 git_diff
*diff
= NULL
;
366 static const char *expected_normal
[] = {
367 "<SKIP>", /* .gitmodules */
368 "<UNTRACKED>", /* not-submodule */
369 "<UNTRACKED>", /* not */
370 "diff --git a/sm_changed_file b/sm_changed_file\nindex 4800958..4800958 160000\n--- a/sm_changed_file\n+++ b/sm_changed_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_file */
371 "diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
372 "diff --git a/sm_changed_index b/sm_changed_index\nindex 4800958..4800958 160000\n--- a/sm_changed_index\n+++ b/sm_changed_index\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_index */
373 "diff --git a/sm_changed_untracked_file b/sm_changed_untracked_file\nindex 4800958..4800958 160000\n--- a/sm_changed_untracked_file\n+++ b/sm_changed_untracked_file\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0-dirty\n", /* sm_changed_untracked_file */
374 "diff --git a/sm_missing_commits b/sm_missing_commits\nindex 4800958..5e49635 160000\n--- a/sm_missing_commits\n+++ b/sm_missing_commits\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 5e4963595a9774b90524d35a807169049de8ccad\n", /* sm_missing_commits */
377 static const char *expected_ignore_all
[] = {
378 "<SKIP>", /* .gitmodules */
379 "<UNTRACKED>", /* not-submodule */
380 "<UNTRACKED>", /* not */
383 static const char *expected_ignore_dirty
[] = {
384 "<SKIP>", /* .gitmodules */
385 "<UNTRACKED>", /* not-submodule */
386 "<UNTRACKED>", /* not */
387 "diff --git a/sm_changed_head b/sm_changed_head\nindex 4800958..3d9386c 160000\n--- a/sm_changed_head\n+++ b/sm_changed_head\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 3d9386c507f6b093471a3e324085657a3c2b4247\n", /* sm_changed_head */
388 "diff --git a/sm_missing_commits b/sm_missing_commits\nindex 4800958..5e49635 160000\n--- a/sm_missing_commits\n+++ b/sm_missing_commits\n@@ -1 +1 @@\n-Subproject commit 480095882d281ed676fe5b863569520e54a7d5c0\n+Subproject commit 5e4963595a9774b90524d35a807169049de8ccad\n", /* sm_missing_commits */
392 g_repo
= setup_fixture_submod2();
394 opts
.flags
= GIT_DIFF_INCLUDE_UNTRACKED
;
395 opts
.old_prefix
= "a"; opts
.new_prefix
= "b";
397 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
398 check_diff_patches(diff
, expected_normal
);
401 opts
.flags
|= GIT_DIFF_IGNORE_SUBMODULES
;
403 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
404 check_diff_patches(diff
, expected_ignore_all
);
407 opts
.flags
&= ~GIT_DIFF_IGNORE_SUBMODULES
;
408 opts
.ignore_submodules
= GIT_SUBMODULE_IGNORE_ALL
;
410 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
411 check_diff_patches(diff
, expected_ignore_all
);
414 opts
.ignore_submodules
= GIT_SUBMODULE_IGNORE_DIRTY
;
416 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
417 check_diff_patches(diff
, expected_ignore_dirty
);
420 opts
.ignore_submodules
= 0;
421 cl_git_pass(git_repository_config(&cfg
, g_repo
));
422 cl_git_pass(git_config_set_bool(cfg
, "diff.ignoreSubmodules", false));
424 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
425 check_diff_patches(diff
, expected_normal
);
428 cl_git_pass(git_config_set_bool(cfg
, "diff.ignoreSubmodules", true));
430 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
431 check_diff_patches(diff
, expected_ignore_all
);
434 cl_git_pass(git_config_set_string(cfg
, "diff.ignoreSubmodules", "none"));
436 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
437 check_diff_patches(diff
, expected_normal
);
440 cl_git_pass(git_config_set_string(cfg
, "diff.ignoreSubmodules", "dirty"));
442 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
443 check_diff_patches(diff
, expected_ignore_dirty
);
446 git_config_free(cfg
);
449 void test_diff_submodules__skips_empty_includes_used(void)
451 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
452 git_diff
*diff
= NULL
;
455 /* A side effect of of Git's handling of untracked directories and
456 * auto-ignoring of ".git" entries is that a newly initialized Git
457 * repo inside another repo will be skipped by diff, but one that
458 * actually has a commit it in will show as an untracked directory.
459 * Let's make sure that works.
462 g_repo
= cl_git_sandbox_init("empty_standard_repo");
464 opts
.flags
|= GIT_DIFF_INCLUDE_IGNORED
| GIT_DIFF_INCLUDE_UNTRACKED
;
466 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
467 memset(&exp
, 0, sizeof(exp
));
468 cl_git_pass(git_diff_foreach(
469 diff
, diff_file_cb
, diff_binary_cb
, diff_hunk_cb
, diff_line_cb
, &exp
));
470 cl_assert_equal_i(0, exp
.files
);
475 cl_git_pass(git_repository_init(&r2
, "empty_standard_repo/subrepo", 0));
476 git_repository_free(r2
);
479 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
480 memset(&exp
, 0, sizeof(exp
));
481 cl_git_pass(git_diff_foreach(
482 diff
, diff_file_cb
, diff_binary_cb
, diff_hunk_cb
, diff_line_cb
, &exp
));
483 cl_assert_equal_i(1, exp
.files
);
484 cl_assert_equal_i(1, exp
.file_status
[GIT_DELTA_IGNORED
]);
487 cl_git_mkfile("empty_standard_repo/subrepo/README.txt", "hello\n");
489 cl_git_pass(git_diff_index_to_workdir(&diff
, g_repo
, NULL
, &opts
));
490 memset(&exp
, 0, sizeof(exp
));
491 cl_git_pass(git_diff_foreach(
492 diff
, diff_file_cb
, diff_binary_cb
, diff_hunk_cb
, diff_line_cb
, &exp
));
493 cl_assert_equal_i(1, exp
.files
);
494 cl_assert_equal_i(1, exp
.file_status
[GIT_DELTA_UNTRACKED
]);
498 static void ensure_submodules_found(
499 git_repository
*repo
,
503 git_diff
*diff
= NULL
;
504 git_diff_options opts
= GIT_DIFF_OPTIONS_INIT
;
505 const git_diff_delta
*delta
;
508 opts
.pathspec
.strings
= (char **)paths
;
509 opts
.pathspec
.count
= cnt
;
511 git_diff_index_to_workdir(&diff
, repo
, NULL
, &opts
);
513 cl_assert_equal_i(cnt
, git_diff_num_deltas(diff
));
515 for (i
= 0; i
< cnt
; i
++) {
516 delta
= git_diff_get_delta(diff
, i
);
518 /* ensure that the given path is returned w/o trailing slashes. */
519 pathlen
= strlen(opts
.pathspec
.strings
[i
]);
521 while (pathlen
&& opts
.pathspec
.strings
[i
][pathlen
- 1] == '/')
524 cl_assert_equal_strn(opts
.pathspec
.strings
[i
], delta
->new_file
.path
, pathlen
);
530 void test_diff_submodules__can_be_identified_by_trailing_slash_in_pathspec(void)
532 const char *one_path_without_slash
[] = { "sm_changed_head" };
533 const char *one_path_with_slash
[] = { "sm_changed_head/" };
534 const char *many_paths_without_slashes
[] = { "sm_changed_head", "sm_changed_index" };
535 const char *many_paths_with_slashes
[] = { "sm_changed_head/", "sm_changed_index/" };
537 g_repo
= setup_fixture_submod2();
539 ensure_submodules_found(g_repo
, one_path_without_slash
, ARRAY_SIZE(one_path_without_slash
));
540 ensure_submodules_found(g_repo
, one_path_with_slash
, ARRAY_SIZE(one_path_with_slash
));
541 ensure_submodules_found(g_repo
, many_paths_without_slashes
, ARRAY_SIZE(many_paths_without_slashes
));
542 ensure_submodules_found(g_repo
, many_paths_with_slashes
, ARRAY_SIZE(many_paths_with_slashes
));