]> git.proxmox.com Git - libgit2.git/blob - tests/status/worktree_init.c
9d5cfa5a320b5cc54c2b5d42b76480d136560230
[libgit2.git] / tests / status / worktree_init.c
1 #include "clar_libgit2.h"
2 #include "git2/sys/repository.h"
3
4 #include "fileops.h"
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));
43 cl_git_pass(git_index_add_bypath(index, "testfile.txt"));
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;
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));
176 cl_git_pass(git_index_add_bypath(index, FILE_WITH_BRACKET));
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
194 cl_git_fail_with(git_status_file(&status_flags, repo, "LICENSE\\[1\\].md"), GIT_ENOTFOUND);
195
196 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
197 cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
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));
253 cl_git_pass(git_index_add_bypath(index, FILE_WITH_SPACE));
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;
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
323 /* Ensure that repo has core.autocrlf=true */
324 cl_repo_set_bool(repo, "core.autocrlf", true);
325
326 cl_git_mkfile("getting_started/testfile.txt", "content\r\n"); /* Content with CRLF */
327
328 cl_git_pass(git_repository_index(&index, repo));
329 cl_git_pass(git_index_add_bypath(index, "testfile.txt"));
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
335 git_index_free(index);
336 git_repository_free(repo);
337 }
338