]>
Commit | Line | Data |
---|---|---|
54254a0f | 1 | #include "clar_libgit2.h" |
1384b688 RB |
2 | #include "git2/sys/repository.h" |
3 | ||
22a2d3d5 | 4 | #include "futils.h" |
54254a0f VM |
5 | #include "ignore.h" |
6 | #include "status_helpers.h" | |
7 | #include "posix.h" | |
8 | #include "util.h" | |
9 | #include "path.h" | |
10 | ||
11 | static void cleanup_new_repo(void *path) | |
12 | { | |
13 | cl_fixture_cleanup((char *)path); | |
14 | } | |
15 | ||
16 | void test_status_worktree_init__cannot_retrieve_the_status_of_a_bare_repository(void) | |
17 | { | |
18 | git_repository *repo; | |
19 | unsigned int status = 0; | |
20 | ||
21 | cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); | |
22 | cl_assert_equal_i(GIT_EBAREREPO, git_status_file(&status, repo, "dummy")); | |
23 | git_repository_free(repo); | |
24 | } | |
25 | ||
26 | void test_status_worktree_init__first_commit_in_progress(void) | |
27 | { | |
28 | git_repository *repo; | |
29 | git_index *index; | |
30 | status_entry_single result; | |
31 | ||
32 | cl_set_cleanup(&cleanup_new_repo, "getting_started"); | |
33 | ||
34 | cl_git_pass(git_repository_init(&repo, "getting_started", 0)); | |
35 | cl_git_mkfile("getting_started/testfile.txt", "content\n"); | |
36 | ||
37 | memset(&result, 0, sizeof(result)); | |
38 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
39 | cl_assert_equal_i(1, result.count); | |
40 | cl_assert(result.status == GIT_STATUS_WT_NEW); | |
41 | ||
42 | cl_git_pass(git_repository_index(&index, repo)); | |
25743bd7 | 43 | cl_git_pass(git_index_add_bypath(index, "testfile.txt")); |
54254a0f VM |
44 | cl_git_pass(git_index_write(index)); |
45 | ||
46 | memset(&result, 0, sizeof(result)); | |
47 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
48 | cl_assert_equal_i(1, result.count); | |
49 | cl_assert(result.status == GIT_STATUS_INDEX_NEW); | |
50 | ||
51 | git_index_free(index); | |
52 | git_repository_free(repo); | |
53 | } | |
54 | ||
55 | ||
56 | ||
57 | void test_status_worktree_init__status_file_without_index_or_workdir(void) | |
58 | { | |
59 | git_repository *repo; | |
60 | unsigned int status = 0; | |
61 | git_index *index; | |
62 | ||
63 | cl_git_pass(p_mkdir("wd", 0777)); | |
64 | ||
65 | cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); | |
66 | cl_git_pass(git_repository_set_workdir(repo, "wd", false)); | |
67 | ||
68 | cl_git_pass(git_index_open(&index, "empty-index")); | |
69 | cl_assert_equal_i(0, (int)git_index_entrycount(index)); | |
70 | git_repository_set_index(repo, index); | |
71 | ||
72 | cl_git_pass(git_status_file(&status, repo, "branch_file.txt")); | |
73 | ||
74 | cl_assert_equal_i(GIT_STATUS_INDEX_DELETED, status); | |
75 | ||
76 | git_repository_free(repo); | |
77 | git_index_free(index); | |
78 | cl_git_pass(p_rmdir("wd")); | |
79 | } | |
80 | ||
81 | static void fill_index_wth_head_entries(git_repository *repo, git_index *index) | |
82 | { | |
83 | git_oid oid; | |
84 | git_commit *commit; | |
85 | git_tree *tree; | |
86 | ||
87 | cl_git_pass(git_reference_name_to_id(&oid, repo, "HEAD")); | |
88 | cl_git_pass(git_commit_lookup(&commit, repo, &oid)); | |
89 | cl_git_pass(git_commit_tree(&tree, commit)); | |
90 | ||
91 | cl_git_pass(git_index_read_tree(index, tree)); | |
92 | cl_git_pass(git_index_write(index)); | |
93 | ||
94 | git_tree_free(tree); | |
95 | git_commit_free(commit); | |
96 | } | |
97 | ||
98 | void test_status_worktree_init__status_file_with_clean_index_and_empty_workdir(void) | |
99 | { | |
100 | git_repository *repo; | |
101 | unsigned int status = 0; | |
102 | git_index *index; | |
103 | ||
104 | cl_git_pass(p_mkdir("wd", 0777)); | |
105 | ||
106 | cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); | |
107 | cl_git_pass(git_repository_set_workdir(repo, "wd", false)); | |
108 | ||
109 | cl_git_pass(git_index_open(&index, "my-index")); | |
110 | fill_index_wth_head_entries(repo, index); | |
111 | ||
112 | git_repository_set_index(repo, index); | |
113 | ||
114 | cl_git_pass(git_status_file(&status, repo, "branch_file.txt")); | |
115 | ||
116 | cl_assert_equal_i(GIT_STATUS_WT_DELETED, status); | |
117 | ||
118 | git_repository_free(repo); | |
119 | git_index_free(index); | |
120 | cl_git_pass(p_rmdir("wd")); | |
121 | cl_git_pass(p_unlink("my-index")); | |
122 | } | |
123 | ||
124 | void test_status_worktree_init__bracket_in_filename(void) | |
125 | { | |
126 | git_repository *repo; | |
127 | git_index *index; | |
128 | status_entry_single result; | |
129 | unsigned int status_flags; | |
54254a0f VM |
130 | |
131 | #define FILE_WITH_BRACKET "LICENSE[1].md" | |
132 | #define FILE_WITHOUT_BRACKET "LICENSE1.md" | |
133 | ||
134 | cl_set_cleanup(&cleanup_new_repo, "with_bracket"); | |
135 | ||
136 | cl_git_pass(git_repository_init(&repo, "with_bracket", 0)); | |
137 | cl_git_mkfile("with_bracket/" FILE_WITH_BRACKET, "I have a bracket in my name\n"); | |
138 | ||
139 | /* file is new to working directory */ | |
140 | ||
141 | memset(&result, 0, sizeof(result)); | |
142 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
143 | cl_assert_equal_i(1, result.count); | |
144 | cl_assert(result.status == GIT_STATUS_WT_NEW); | |
145 | ||
146 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); | |
147 | cl_assert(status_flags == GIT_STATUS_WT_NEW); | |
148 | ||
149 | /* ignore the file */ | |
150 | ||
151 | cl_git_rewritefile("with_bracket/.gitignore", "*.md\n.gitignore\n"); | |
152 | ||
153 | memset(&result, 0, sizeof(result)); | |
154 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
155 | cl_assert_equal_i(2, result.count); | |
156 | cl_assert(result.status == GIT_STATUS_IGNORED); | |
157 | ||
158 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); | |
159 | cl_assert(status_flags == GIT_STATUS_IGNORED); | |
160 | ||
161 | /* don't ignore the file */ | |
162 | ||
163 | cl_git_rewritefile("with_bracket/.gitignore", ".gitignore\n"); | |
164 | ||
165 | memset(&result, 0, sizeof(result)); | |
166 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
167 | cl_assert_equal_i(2, result.count); | |
168 | cl_assert(result.status == GIT_STATUS_WT_NEW); | |
169 | ||
170 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); | |
171 | cl_assert(status_flags == GIT_STATUS_WT_NEW); | |
172 | ||
173 | /* add the file to the index */ | |
174 | ||
175 | cl_git_pass(git_repository_index(&index, repo)); | |
25743bd7 | 176 | cl_git_pass(git_index_add_bypath(index, FILE_WITH_BRACKET)); |
54254a0f VM |
177 | cl_git_pass(git_index_write(index)); |
178 | ||
179 | memset(&result, 0, sizeof(result)); | |
180 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
181 | cl_assert_equal_i(2, result.count); | |
182 | cl_assert(result.status == GIT_STATUS_INDEX_NEW); | |
183 | ||
184 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); | |
185 | cl_assert(status_flags == GIT_STATUS_INDEX_NEW); | |
186 | ||
187 | /* Create file without bracket */ | |
188 | ||
189 | cl_git_mkfile("with_bracket/" FILE_WITHOUT_BRACKET, "I have no bracket in my name!\n"); | |
190 | ||
191 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITHOUT_BRACKET)); | |
192 | cl_assert(status_flags == GIT_STATUS_WT_NEW); | |
193 | ||
71ef639e | 194 | cl_git_fail_with(git_status_file(&status_flags, repo, "LICENSE\\[1\\].md"), GIT_ENOTFOUND); |
54254a0f | 195 | |
68182085 | 196 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET)); |
71ef639e | 197 | cl_assert(status_flags == GIT_STATUS_INDEX_NEW); |
54254a0f VM |
198 | |
199 | git_index_free(index); | |
200 | git_repository_free(repo); | |
201 | } | |
202 | ||
203 | void test_status_worktree_init__space_in_filename(void) | |
204 | { | |
205 | git_repository *repo; | |
206 | git_index *index; | |
207 | status_entry_single result; | |
208 | unsigned int status_flags; | |
209 | ||
210 | #define FILE_WITH_SPACE "LICENSE - copy.md" | |
211 | ||
212 | cl_set_cleanup(&cleanup_new_repo, "with_space"); | |
213 | cl_git_pass(git_repository_init(&repo, "with_space", 0)); | |
214 | cl_git_mkfile("with_space/" FILE_WITH_SPACE, "I have a space in my name\n"); | |
215 | ||
216 | /* file is new to working directory */ | |
217 | ||
218 | memset(&result, 0, sizeof(result)); | |
219 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
220 | cl_assert_equal_i(1, result.count); | |
221 | cl_assert(result.status == GIT_STATUS_WT_NEW); | |
222 | ||
223 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE)); | |
224 | cl_assert(status_flags == GIT_STATUS_WT_NEW); | |
225 | ||
226 | /* ignore the file */ | |
227 | ||
228 | cl_git_rewritefile("with_space/.gitignore", "*.md\n.gitignore\n"); | |
229 | ||
230 | memset(&result, 0, sizeof(result)); | |
231 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
232 | cl_assert_equal_i(2, result.count); | |
233 | cl_assert(result.status == GIT_STATUS_IGNORED); | |
234 | ||
235 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE)); | |
236 | cl_assert(status_flags == GIT_STATUS_IGNORED); | |
237 | ||
238 | /* don't ignore the file */ | |
239 | ||
240 | cl_git_rewritefile("with_space/.gitignore", ".gitignore\n"); | |
241 | ||
242 | memset(&result, 0, sizeof(result)); | |
243 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
244 | cl_assert_equal_i(2, result.count); | |
245 | cl_assert(result.status == GIT_STATUS_WT_NEW); | |
246 | ||
247 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE)); | |
248 | cl_assert(status_flags == GIT_STATUS_WT_NEW); | |
249 | ||
250 | /* add the file to the index */ | |
251 | ||
252 | cl_git_pass(git_repository_index(&index, repo)); | |
25743bd7 | 253 | cl_git_pass(git_index_add_bypath(index, FILE_WITH_SPACE)); |
54254a0f VM |
254 | cl_git_pass(git_index_write(index)); |
255 | ||
256 | memset(&result, 0, sizeof(result)); | |
257 | cl_git_pass(git_status_foreach(repo, cb_status__single, &result)); | |
258 | cl_assert_equal_i(2, result.count); | |
259 | cl_assert(result.status == GIT_STATUS_INDEX_NEW); | |
260 | ||
261 | cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE)); | |
262 | cl_assert(status_flags == GIT_STATUS_INDEX_NEW); | |
263 | ||
264 | git_index_free(index); | |
265 | git_repository_free(repo); | |
266 | } | |
267 | ||
268 | static int cb_status__expected_path(const char *p, unsigned int s, void *payload) | |
269 | { | |
270 | const char *expected_path = (const char *)payload; | |
271 | ||
272 | GIT_UNUSED(s); | |
273 | ||
274 | if (payload == NULL) | |
275 | cl_fail("Unexpected path"); | |
276 | ||
277 | cl_assert_equal_s(expected_path, p); | |
278 | ||
279 | return 0; | |
280 | } | |
281 | ||
282 | void test_status_worktree_init__disable_pathspec_match(void) | |
283 | { | |
284 | git_repository *repo; | |
285 | git_status_options opts = GIT_STATUS_OPTIONS_INIT; | |
286 | char *file_with_bracket = "LICENSE[1].md", | |
287 | *imaginary_file_with_bracket = "LICENSE[1-2].md"; | |
288 | ||
289 | cl_set_cleanup(&cleanup_new_repo, "pathspec"); | |
290 | cl_git_pass(git_repository_init(&repo, "pathspec", 0)); | |
291 | cl_git_mkfile("pathspec/LICENSE[1].md", "screaming bracket\n"); | |
292 | cl_git_mkfile("pathspec/LICENSE1.md", "no bracket\n"); | |
293 | ||
294 | opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED | | |
295 | GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH; | |
296 | opts.pathspec.count = 1; | |
297 | opts.pathspec.strings = &file_with_bracket; | |
298 | ||
299 | cl_git_pass( | |
300 | git_status_foreach_ext(repo, &opts, cb_status__expected_path, | |
301 | file_with_bracket) | |
302 | ); | |
303 | ||
304 | /* Test passing a pathspec matching files in the workdir. */ | |
305 | /* Must not match because pathspecs are disabled. */ | |
306 | opts.pathspec.strings = &imaginary_file_with_bracket; | |
307 | cl_git_pass( | |
308 | git_status_foreach_ext(repo, &opts, cb_status__expected_path, NULL) | |
309 | ); | |
310 | ||
311 | git_repository_free(repo); | |
312 | } | |
313 | ||
314 | void test_status_worktree_init__new_staged_file_must_handle_crlf(void) | |
315 | { | |
316 | git_repository *repo; | |
317 | git_index *index; | |
54254a0f VM |
318 | unsigned int status; |
319 | ||
320 | cl_set_cleanup(&cleanup_new_repo, "getting_started"); | |
321 | cl_git_pass(git_repository_init(&repo, "getting_started", 0)); | |
322 | ||
1384b688 | 323 | /* Ensure that repo has core.autocrlf=true */ |
1323c6d1 | 324 | cl_repo_set_bool(repo, "core.autocrlf", true); |
54254a0f | 325 | |
1384b688 | 326 | cl_git_mkfile("getting_started/testfile.txt", "content\r\n"); /* Content with CRLF */ |
54254a0f VM |
327 | |
328 | cl_git_pass(git_repository_index(&index, repo)); | |
25743bd7 | 329 | cl_git_pass(git_index_add_bypath(index, "testfile.txt")); |
54254a0f VM |
330 | cl_git_pass(git_index_write(index)); |
331 | ||
332 | cl_git_pass(git_status_file(&status, repo, "testfile.txt")); | |
333 | cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status); | |
334 | ||
54254a0f VM |
335 | git_index_free(index); |
336 | git_repository_free(repo); | |
337 | } | |
338 |