1 #include "clar_libgit2.h"
2 #include "../filter/crlf.h"
4 #include "git2/checkout.h"
5 #include "repository.h"
8 #define FILE_CONTENTS_LF "one\ntwo\nthree\nfour\n"
9 #define FILE_CONTENTS_CRLF "one\r\ntwo\r\nthree\r\nfour\r\n"
11 #define FILE_OID_LF "f384549cbeb481e437091320de6d1f2e15e11b4a"
12 #define FILE_OID_CRLF "7fbf4d847b191141d80f30c8ab03d2ad4cd543a9"
14 static git_repository
*g_repo
;
15 static git_index
*g_index
;
17 static git_buf expected_fixture
= GIT_BUF_INIT
;
19 void test_index_crlf__initialize(void)
21 g_repo
= cl_git_sandbox_init_new("crlf");
22 cl_git_pass(git_repository_index(&g_index
, g_repo
));
25 void test_index_crlf__cleanup(void)
27 git_index_free(g_index
);
28 cl_git_sandbox_cleanup();
30 if (expected_fixture
.size
) {
31 cl_fixture_cleanup(expected_fixture
.ptr
);
32 git_buf_dispose(&expected_fixture
);
45 static int add_and_check_file(void *payload
, git_buf
*actual_path
)
47 git_buf expected_path
= GIT_BUF_INIT
;
48 git_buf expected_path_fail
= GIT_BUF_INIT
;
49 git_buf expected_contents
= GIT_BUF_INIT
;
50 struct compare_data
*cd
= payload
;
52 const git_index_entry
*entry
;
56 basename
= git_path_basename(actual_path
->ptr
);
58 if (!strcmp(basename
, ".git") || !strcmp(basename
, ".gitattributes")) {
63 cl_git_pass(git_buf_joinpath(&expected_path
, cd
->dirname
, basename
));
65 cl_git_pass(git_buf_puts(&expected_path_fail
, expected_path
.ptr
));
66 cl_git_pass(git_buf_puts(&expected_path_fail
, ".fail"));
68 if (git_path_isfile(expected_path
.ptr
)) {
69 cl_git_pass(git_index_add_bypath(g_index
, basename
));
71 cl_assert(entry
= git_index_get_bypath(g_index
, basename
, 0));
72 cl_git_pass(git_blob_lookup(&blob
, g_repo
, &entry
->id
));
74 cl_git_pass(git_futils_readbuffer(&expected_contents
, expected_path
.ptr
));
76 if (strcmp(expected_contents
.ptr
, git_blob_rawcontent(blob
)) != 0)
80 } else if (git_path_isfile(expected_path_fail
.ptr
)) {
81 cl_git_pass(git_futils_readbuffer(&expected_contents
, expected_path_fail
.ptr
));
82 git_buf_rtrim(&expected_contents
);
84 if (git_index_add_bypath(g_index
, basename
) == 0 ||
85 git_error_last()->klass
!= GIT_ERROR_FILTER
||
86 strcmp(expected_contents
.ptr
, git_error_last()->message
) != 0)
89 cl_fail("unexpected index failure");
96 git_buf details
= GIT_BUF_INIT
;
97 git_buf_printf(&details
, "filename=%s, system=%s, autocrlf=%s, safecrlf=%s, attrs={%s}",
98 basename
, cd
->systype
, cd
->autocrlf
, cd
->safecrlf
, cd
->attrs
);
99 clar__fail(__FILE__
, __LINE__
,
100 "index contents did not match expected", details
.ptr
, 0);
101 git_buf_dispose(&details
);
105 git_buf_dispose(&expected_contents
);
106 git_buf_dispose(&expected_path
);
107 git_buf_dispose(&expected_path_fail
);
111 static const char *system_type(void)
113 if (GIT_EOL_NATIVE
== GIT_EOL_CRLF
)
119 static void test_add_index(const char *safecrlf
, const char *autocrlf
, const char *attrs
)
121 git_buf attrbuf
= GIT_BUF_INIT
;
122 git_buf expected_dirname
= GIT_BUF_INIT
;
123 git_buf sandboxname
= GIT_BUF_INIT
;
124 git_buf reponame
= GIT_BUF_INIT
;
125 struct compare_data compare_data
= { system_type(), NULL
, safecrlf
, autocrlf
, attrs
};
128 git_buf_puts(&reponame
, "crlf");
130 git_buf_puts(&sandboxname
, "autocrlf_");
131 git_buf_puts(&sandboxname
, autocrlf
);
133 git_buf_puts(&sandboxname
, ",safecrlf_");
134 git_buf_puts(&sandboxname
, safecrlf
);
137 git_buf_puts(&sandboxname
, ",");
139 for (c
= attrs
; *c
; c
++) {
141 git_buf_putc(&sandboxname
, ',');
143 git_buf_putc(&sandboxname
, '_');
145 git_buf_putc(&sandboxname
, *c
);
148 git_buf_printf(&attrbuf
, "* %s\n", attrs
);
149 cl_git_mkfile("crlf/.gitattributes", attrbuf
.ptr
);
152 cl_repo_set_string(g_repo
, "core.safecrlf", safecrlf
);
153 cl_repo_set_string(g_repo
, "core.autocrlf", autocrlf
);
155 cl_git_pass(git_index_clear(g_index
));
157 git_buf_joinpath(&expected_dirname
, "crlf_data", system_type());
158 git_buf_puts(&expected_dirname
, "_to_odb");
160 git_buf_joinpath(&expected_fixture
, expected_dirname
.ptr
, sandboxname
.ptr
);
161 cl_fixture_sandbox(expected_fixture
.ptr
);
163 compare_data
.dirname
= sandboxname
.ptr
;
164 cl_git_pass(git_path_direach(&reponame
, 0, add_and_check_file
, &compare_data
));
166 cl_fixture_cleanup(expected_fixture
.ptr
);
167 git_buf_dispose(&expected_fixture
);
169 git_buf_dispose(&attrbuf
);
170 git_buf_dispose(&expected_fixture
);
171 git_buf_dispose(&expected_dirname
);
172 git_buf_dispose(&sandboxname
);
173 git_buf_dispose(&reponame
);
176 static void set_up_workingdir(const char *name
)
178 git_vector contents
= GIT_VECTOR_INIT
;
182 git_path_dirload(&contents
, name
, 0, 0);
183 git_vector_foreach(&contents
, i
, fn
) {
184 char *basename
= git_path_basename(fn
);
185 bool skip
= strncasecmp(basename
, ".git", 4) == 0 && strlen(basename
) == 4;
193 git_vector_free_deep(&contents
);
195 /* copy input files */
196 git_path_dirload(&contents
, cl_fixture("crlf"), 0, 0);
197 git_vector_foreach(&contents
, i
, fn
) {
198 char *basename
= git_path_basename(fn
);
199 git_buf dest_filename
= GIT_BUF_INIT
;
201 if (strcmp(basename
, ".gitted") &&
202 strcmp(basename
, ".gitattributes")) {
203 git_buf_joinpath(&dest_filename
, name
, basename
);
204 cl_git_pass(git_futils_cp(fn
, dest_filename
.ptr
, 0644));
208 git_buf_dispose(&dest_filename
);
210 git_vector_free_deep(&contents
);
213 void test_index_crlf__matches_core_git(void)
215 const char *safecrlf
[] = { "true", "false", "warn", NULL
};
216 const char *autocrlf
[] = { "true", "false", "input", NULL
};
217 const char *attrs
[] = { "", "-crlf", "-text", "eol=crlf", "eol=lf",
218 "text", "text eol=crlf", "text eol=lf",
219 "text=auto", "text=auto eol=crlf", "text=auto eol=lf",
221 const char **a
, **b
, **c
;
223 for (a
= safecrlf
; *a
; a
++) {
224 for (b
= autocrlf
; *b
; b
++) {
225 for (c
= attrs
; *c
; c
++) {
226 set_up_workingdir("crlf");
227 test_add_index(*a
, *b
, *c
);
233 void test_index_crlf__autocrlf_false_no_attrs(void)
235 const git_index_entry
*entry
;
238 cl_repo_set_bool(g_repo
, "core.autocrlf", false);
240 cl_git_mkfile("./crlf/newfile.txt",
241 (GIT_EOL_NATIVE
== GIT_EOL_CRLF
) ? FILE_CONTENTS_CRLF
: FILE_CONTENTS_LF
);
243 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
244 entry
= git_index_get_bypath(g_index
, "newfile.txt", 0);
246 cl_git_pass(git_oid_fromstr(&oid
,
247 (GIT_EOL_NATIVE
== GIT_EOL_CRLF
) ? FILE_OID_CRLF
: FILE_OID_LF
));
248 cl_assert_equal_oid(&oid
, &entry
->id
);
251 void test_index_crlf__autocrlf_true_no_attrs(void)
253 const git_index_entry
*entry
;
256 cl_repo_set_bool(g_repo
, "core.autocrlf", true);
258 cl_git_mkfile("./crlf/newfile.txt",
259 (GIT_EOL_NATIVE
== GIT_EOL_CRLF
) ? FILE_CONTENTS_CRLF
: FILE_CONTENTS_LF
);
261 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
262 entry
= git_index_get_bypath(g_index
, "newfile.txt", 0);
264 cl_git_pass(git_oid_fromstr(&oid
, FILE_OID_LF
));
265 cl_assert_equal_oid(&oid
, &entry
->id
);
268 void test_index_crlf__autocrlf_input_no_attrs(void)
270 const git_index_entry
*entry
;
273 cl_repo_set_string(g_repo
, "core.autocrlf", "input");
275 cl_git_mkfile("./crlf/newfile.txt",
276 (GIT_EOL_NATIVE
== GIT_EOL_CRLF
) ? FILE_CONTENTS_CRLF
: FILE_CONTENTS_LF
);
278 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
279 entry
= git_index_get_bypath(g_index
, "newfile.txt", 0);
281 cl_git_pass(git_oid_fromstr(&oid
, FILE_OID_LF
));
282 cl_assert_equal_oid(&oid
, &entry
->id
);
285 void test_index_crlf__autocrlf_false_text_auto_attr(void)
287 const git_index_entry
*entry
;
290 cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
292 cl_repo_set_bool(g_repo
, "core.autocrlf", false);
294 cl_git_mkfile("./crlf/newfile.txt",
295 (GIT_EOL_NATIVE
== GIT_EOL_CRLF
) ? FILE_CONTENTS_CRLF
: FILE_CONTENTS_LF
);
297 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
298 entry
= git_index_get_bypath(g_index
, "newfile.txt", 0);
300 cl_git_pass(git_oid_fromstr(&oid
, FILE_OID_LF
));
301 cl_assert_equal_oid(&oid
, &entry
->id
);
304 void test_index_crlf__autocrlf_true_text_auto_attr(void)
306 const git_index_entry
*entry
;
309 cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
311 cl_repo_set_bool(g_repo
, "core.autocrlf", false);
313 cl_git_mkfile("./crlf/newfile.txt",
314 (GIT_EOL_NATIVE
== GIT_EOL_CRLF
) ? FILE_CONTENTS_CRLF
: FILE_CONTENTS_LF
);
316 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
317 entry
= git_index_get_bypath(g_index
, "newfile.txt", 0);
319 cl_git_pass(git_oid_fromstr(&oid
, FILE_OID_LF
));
320 cl_assert_equal_oid(&oid
, &entry
->id
);
323 void test_index_crlf__autocrlf_input_text_auto_attr(void)
325 const git_index_entry
*entry
;
328 cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
330 cl_repo_set_string(g_repo
, "core.autocrlf", "input");
332 cl_git_mkfile("./crlf/newfile.txt",
333 (GIT_EOL_NATIVE
== GIT_EOL_CRLF
) ? FILE_CONTENTS_CRLF
: FILE_CONTENTS_LF
);
335 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
336 entry
= git_index_get_bypath(g_index
, "newfile.txt", 0);
338 cl_git_pass(git_oid_fromstr(&oid
, FILE_OID_LF
));
339 cl_assert_equal_oid(&oid
, &entry
->id
);
342 void test_index_crlf__safecrlf_true_autocrlf_input_text_auto_attr(void)
344 const git_index_entry
*entry
;
347 cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n");
349 cl_repo_set_string(g_repo
, "core.autocrlf", "input");
350 cl_repo_set_bool(g_repo
, "core.safecrlf", true);
352 cl_git_mkfile("./crlf/newfile.txt", FILE_CONTENTS_LF
);
354 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
355 entry
= git_index_get_bypath(g_index
, "newfile.txt", 0);
358 cl_git_pass(git_oid_fromstr(&oid
, FILE_OID_LF
));
359 cl_assert_equal_oid(&oid
, &entry
->id
);
361 cl_git_mkfile("./crlf/newfile2.txt", FILE_CONTENTS_CRLF
);
362 cl_git_fail(git_index_add_bypath(g_index
, "newfile2.txt"));
365 void test_index_crlf__safecrlf_true_autocrlf_input_text__no_attr(void)
367 const git_index_entry
*entry
;
370 cl_repo_set_string(g_repo
, "core.autocrlf", "input");
371 cl_repo_set_bool(g_repo
, "core.safecrlf", true);
373 cl_git_mkfile("./crlf/newfile.txt", FILE_CONTENTS_LF
);
375 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
376 entry
= git_index_get_bypath(g_index
, "newfile.txt", 0);
379 cl_git_pass(git_oid_fromstr(&oid
, FILE_OID_LF
));
380 cl_assert_equal_oid(&oid
, &entry
->id
);
382 cl_git_mkfile("./crlf/newfile2.txt", FILE_CONTENTS_CRLF
);
383 cl_git_fail(git_index_add_bypath(g_index
, "newfile2.txt"));
386 void test_index_crlf__safecrlf_true_no_attrs(void)
388 cl_repo_set_bool(g_repo
, "core.autocrlf", true);
389 cl_repo_set_bool(g_repo
, "core.safecrlf", true);
391 cl_git_mkfile("crlf/newfile.txt", ALL_LF_TEXT_RAW
);
392 cl_git_fail(git_index_add_bypath(g_index
, "newfile.txt"));
394 cl_git_mkfile("crlf/newfile.txt", ALL_CRLF_TEXT_RAW
);
395 cl_git_pass(git_index_add_bypath(g_index
, "newfile.txt"));
397 cl_git_mkfile("crlf/newfile.txt", MORE_CRLF_TEXT_RAW
);
398 cl_git_fail(git_index_add_bypath(g_index
, "newfile.txt"));
400 cl_git_mkfile("crlf/newfile.txt", MORE_LF_TEXT_RAW
);
401 cl_git_fail(git_index_add_bypath(g_index
, "newfile.txt"));