]> git.proxmox.com Git - libgit2.git/blob - tests/status/worktree_init.c
Merge pull request #2696 from libgit2/cmn/empty-objects
[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 int error;
131
132 #define FILE_WITH_BRACKET "LICENSE[1].md"
133 #define FILE_WITHOUT_BRACKET "LICENSE1.md"
134
135 cl_set_cleanup(&cleanup_new_repo, "with_bracket");
136
137 cl_git_pass(git_repository_init(&repo, "with_bracket", 0));
138 cl_git_mkfile("with_bracket/" FILE_WITH_BRACKET, "I have a bracket in my name\n");
139
140 /* file is new to working directory */
141
142 memset(&result, 0, sizeof(result));
143 cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
144 cl_assert_equal_i(1, result.count);
145 cl_assert(result.status == GIT_STATUS_WT_NEW);
146
147 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
148 cl_assert(status_flags == GIT_STATUS_WT_NEW);
149
150 /* ignore the file */
151
152 cl_git_rewritefile("with_bracket/.gitignore", "*.md\n.gitignore\n");
153
154 memset(&result, 0, sizeof(result));
155 cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
156 cl_assert_equal_i(2, result.count);
157 cl_assert(result.status == GIT_STATUS_IGNORED);
158
159 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
160 cl_assert(status_flags == GIT_STATUS_IGNORED);
161
162 /* don't ignore the file */
163
164 cl_git_rewritefile("with_bracket/.gitignore", ".gitignore\n");
165
166 memset(&result, 0, sizeof(result));
167 cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
168 cl_assert_equal_i(2, result.count);
169 cl_assert(result.status == GIT_STATUS_WT_NEW);
170
171 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
172 cl_assert(status_flags == GIT_STATUS_WT_NEW);
173
174 /* add the file to the index */
175
176 cl_git_pass(git_repository_index(&index, repo));
177 cl_git_pass(git_index_add_bypath(index, FILE_WITH_BRACKET));
178 cl_git_pass(git_index_write(index));
179
180 memset(&result, 0, sizeof(result));
181 cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
182 cl_assert_equal_i(2, result.count);
183 cl_assert(result.status == GIT_STATUS_INDEX_NEW);
184
185 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
186 cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
187
188 /* Create file without bracket */
189
190 cl_git_mkfile("with_bracket/" FILE_WITHOUT_BRACKET, "I have no bracket in my name!\n");
191
192 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITHOUT_BRACKET));
193 cl_assert(status_flags == GIT_STATUS_WT_NEW);
194
195 cl_git_pass(git_status_file(&status_flags, repo, "LICENSE\\[1\\].md"));
196 cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
197
198 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_BRACKET));
199
200 git_index_free(index);
201 git_repository_free(repo);
202 }
203
204 void test_status_worktree_init__space_in_filename(void)
205 {
206 git_repository *repo;
207 git_index *index;
208 status_entry_single result;
209 unsigned int status_flags;
210
211 #define FILE_WITH_SPACE "LICENSE - copy.md"
212
213 cl_set_cleanup(&cleanup_new_repo, "with_space");
214 cl_git_pass(git_repository_init(&repo, "with_space", 0));
215 cl_git_mkfile("with_space/" FILE_WITH_SPACE, "I have a space in my name\n");
216
217 /* file is new to working directory */
218
219 memset(&result, 0, sizeof(result));
220 cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
221 cl_assert_equal_i(1, result.count);
222 cl_assert(result.status == GIT_STATUS_WT_NEW);
223
224 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
225 cl_assert(status_flags == GIT_STATUS_WT_NEW);
226
227 /* ignore the file */
228
229 cl_git_rewritefile("with_space/.gitignore", "*.md\n.gitignore\n");
230
231 memset(&result, 0, sizeof(result));
232 cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
233 cl_assert_equal_i(2, result.count);
234 cl_assert(result.status == GIT_STATUS_IGNORED);
235
236 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
237 cl_assert(status_flags == GIT_STATUS_IGNORED);
238
239 /* don't ignore the file */
240
241 cl_git_rewritefile("with_space/.gitignore", ".gitignore\n");
242
243 memset(&result, 0, sizeof(result));
244 cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
245 cl_assert_equal_i(2, result.count);
246 cl_assert(result.status == GIT_STATUS_WT_NEW);
247
248 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
249 cl_assert(status_flags == GIT_STATUS_WT_NEW);
250
251 /* add the file to the index */
252
253 cl_git_pass(git_repository_index(&index, repo));
254 cl_git_pass(git_index_add_bypath(index, FILE_WITH_SPACE));
255 cl_git_pass(git_index_write(index));
256
257 memset(&result, 0, sizeof(result));
258 cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
259 cl_assert_equal_i(2, result.count);
260 cl_assert(result.status == GIT_STATUS_INDEX_NEW);
261
262 cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
263 cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
264
265 git_index_free(index);
266 git_repository_free(repo);
267 }
268
269 static int cb_status__expected_path(const char *p, unsigned int s, void *payload)
270 {
271 const char *expected_path = (const char *)payload;
272
273 GIT_UNUSED(s);
274
275 if (payload == NULL)
276 cl_fail("Unexpected path");
277
278 cl_assert_equal_s(expected_path, p);
279
280 return 0;
281 }
282
283 void test_status_worktree_init__disable_pathspec_match(void)
284 {
285 git_repository *repo;
286 git_status_options opts = GIT_STATUS_OPTIONS_INIT;
287 char *file_with_bracket = "LICENSE[1].md",
288 *imaginary_file_with_bracket = "LICENSE[1-2].md";
289
290 cl_set_cleanup(&cleanup_new_repo, "pathspec");
291 cl_git_pass(git_repository_init(&repo, "pathspec", 0));
292 cl_git_mkfile("pathspec/LICENSE[1].md", "screaming bracket\n");
293 cl_git_mkfile("pathspec/LICENSE1.md", "no bracket\n");
294
295 opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
296 GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH;
297 opts.pathspec.count = 1;
298 opts.pathspec.strings = &file_with_bracket;
299
300 cl_git_pass(
301 git_status_foreach_ext(repo, &opts, cb_status__expected_path,
302 file_with_bracket)
303 );
304
305 /* Test passing a pathspec matching files in the workdir. */
306 /* Must not match because pathspecs are disabled. */
307 opts.pathspec.strings = &imaginary_file_with_bracket;
308 cl_git_pass(
309 git_status_foreach_ext(repo, &opts, cb_status__expected_path, NULL)
310 );
311
312 git_repository_free(repo);
313 }
314
315 void test_status_worktree_init__new_staged_file_must_handle_crlf(void)
316 {
317 git_repository *repo;
318 git_index *index;
319 unsigned int status;
320
321 cl_set_cleanup(&cleanup_new_repo, "getting_started");
322 cl_git_pass(git_repository_init(&repo, "getting_started", 0));
323
324 /* Ensure that repo has core.autocrlf=true */
325 cl_repo_set_bool(repo, "core.autocrlf", true);
326
327 cl_git_mkfile("getting_started/testfile.txt", "content\r\n"); /* Content with CRLF */
328
329 cl_git_pass(git_repository_index(&index, repo));
330 cl_git_pass(git_index_add_bypath(index, "testfile.txt"));
331 cl_git_pass(git_index_write(index));
332
333 cl_git_pass(git_status_file(&status, repo, "testfile.txt"));
334 cl_assert_equal_i(GIT_STATUS_INDEX_NEW, status);
335
336 git_index_free(index);
337 git_repository_free(repo);
338 }
339