diff --git a/src/crlf.c b/src/crlf.c index e1bd5572b..db69cab5c 100644 --- a/src/crlf.c +++ b/src/crlf.c @@ -269,7 +269,9 @@ static int crlf_check( if (ca.crlf_action == GIT_CRLF_BINARY) return GIT_PASSTHROUGH; - if (ca.crlf_action == GIT_CRLF_GUESS) { + if (ca.crlf_action == GIT_CRLF_GUESS || + (ca.crlf_action == GIT_CRLF_AUTO && + git_filter_source_mode(src) == GIT_FILTER_SMUDGE)) { error = git_repository__cvar( &ca.auto_crlf, git_filter_source_repo(src), GIT_CVAR_AUTO_CRLF); if (error < 0) @@ -277,6 +279,10 @@ static int crlf_check( if (ca.auto_crlf == GIT_AUTO_CRLF_FALSE) return GIT_PASSTHROUGH; + + if (ca.auto_crlf == GIT_AUTO_CRLF_INPUT && + git_filter_source_mode(src) == GIT_FILTER_SMUDGE) + return GIT_PASSTHROUGH; } *payload = git__malloc(sizeof(ca)); diff --git a/tests/checkout/crlf.c b/tests/checkout/crlf.c index cba79432f..0d78ee039 100644 --- a/tests/checkout/crlf.c +++ b/tests/checkout/crlf.c @@ -18,19 +18,6 @@ void test_checkout_crlf__cleanup(void) cl_git_sandbox_cleanup(); } -void test_checkout_crlf__detect_crlf_autocrlf_false(void) -{ - git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; - opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; - - cl_repo_set_bool(g_repo, "core.autocrlf", false); - - git_checkout_head(g_repo, &opts); - - check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW); - check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); -} - void test_checkout_crlf__autocrlf_false_index_size_is_unfiltered_size(void) { git_index *index; @@ -100,18 +87,6 @@ void test_checkout_crlf__more_crlf_autocrlf_true(void) check_file_contents("./crlf/more-crlf", MORE_CRLF_TEXT_AS_CRLF); } -void test_checkout_crlf__all_crlf_autocrlf_true(void) -{ - git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; - opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; - - cl_repo_set_bool(g_repo, "core.autocrlf", true); - - git_checkout_head(g_repo, &opts); - - check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); -} - void test_checkout_crlf__autocrlf_true_index_size_is_filtered_size(void) { git_index *index; @@ -229,3 +204,97 @@ void test_checkout_crlf__with_ident(void) git_index_free(index); } + +void test_checkout_crlf__autocrlf_false_no_attrs(void) +{ + git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; + + cl_repo_set_bool(g_repo, "core.autocrlf", false); + + git_checkout_head(g_repo, &opts); + + check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW); + check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); +} + +void test_checkout_crlf__autocrlf_true_no_attrs(void) +{ + git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; + + cl_repo_set_bool(g_repo, "core.autocrlf", true); + + git_checkout_head(g_repo, &opts); + + if (GIT_EOL_NATIVE == GIT_EOL_CRLF) { + check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF); + check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF); + } else { + check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW); + check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); + } +} + +void test_checkout_crlf__autocrlf_input_no_attrs(void) +{ + git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; + + cl_repo_set_string(g_repo, "core.autocrlf", "input"); + + git_checkout_head(g_repo, &opts); + + check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW); + check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); +} + +void test_checkout_crlf__autocrlf_false_text_auto_attr(void) +{ + git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; + + cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n"); + + cl_repo_set_bool(g_repo, "core.autocrlf", false); + + git_checkout_head(g_repo, &opts); + + check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW); + check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); +} + +void test_checkout_crlf__autocrlf_true_text_auto_attr(void) +{ + git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; + + cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n"); + + cl_repo_set_bool(g_repo, "core.autocrlf", true); + + git_checkout_head(g_repo, &opts); + + if (GIT_EOL_NATIVE == GIT_EOL_CRLF) { + check_file_contents("./crlf/all-lf", ALL_LF_TEXT_AS_CRLF); + check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_AS_CRLF); + } else { + check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW); + check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); + } +} + +void test_checkout_crlf__autocrlf_input_text_auto_attr(void) +{ + git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; + opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; + + cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n"); + + cl_repo_set_string(g_repo, "core.autocrlf", "input"); + + git_checkout_head(g_repo, &opts); + + check_file_contents("./crlf/all-lf", ALL_LF_TEXT_RAW); + check_file_contents("./crlf/all-crlf", ALL_CRLF_TEXT_RAW); +} diff --git a/tests/clar_libgit2.c b/tests/clar_libgit2.c index 50762cdb8..9b062ef78 100644 --- a/tests/clar_libgit2.c +++ b/tests/clar_libgit2.c @@ -420,6 +420,14 @@ int cl_repo_get_bool(git_repository *repo, const char *cfg) return val; } +void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value) +{ + git_config *config; + cl_git_pass(git_repository_config(&config, repo)); + cl_git_pass(git_config_set_string(config, cfg, value)); + git_config_free(config); +} + /* this is essentially the code from git__unescape modified slightly */ static size_t strip_cr_from_buf(char *start, size_t len) { @@ -468,6 +476,7 @@ void clar__assert_equal_file( p_snprintf( buf, sizeof(buf), "file content mismatch at byte %d", (int)(total_bytes + pos)); + p_close(fd); clar__fail(file, line, buf, path, 1); } diff --git a/tests/clar_libgit2.h b/tests/clar_libgit2.h index b9ef5627e..915111244 100644 --- a/tests/clar_libgit2.h +++ b/tests/clar_libgit2.h @@ -116,4 +116,6 @@ void cl_repo_commit_from_index( void cl_repo_set_bool(git_repository *repo, const char *cfg, int value); int cl_repo_get_bool(git_repository *repo, const char *cfg); +void cl_repo_set_string(git_repository *repo, const char *cfg, const char *value); + #endif diff --git a/tests/index/crlf.c b/tests/index/crlf.c new file mode 100644 index 000000000..cf69c6226 --- /dev/null +++ b/tests/index/crlf.c @@ -0,0 +1,136 @@ +#include "clar_libgit2.h" +#include "../filter/crlf.h" + +#include "git2/checkout.h" +#include "repository.h" +#include "posix.h" + +#define FILE_CONTENTS_LF "one\ntwo\nthree\nfour\n" +#define FILE_CONTENTS_CRLF "one\r\ntwo\r\nthree\r\nfour\r\n" + +#define FILE_OID_LF "f384549cbeb481e437091320de6d1f2e15e11b4a" +#define FILE_OID_CRLF "7fbf4d847b191141d80f30c8ab03d2ad4cd543a9" + +static git_repository *g_repo; +static git_index *g_index; + +void test_index_crlf__initialize(void) +{ + g_repo = cl_git_sandbox_init("crlf"); + cl_git_pass(git_repository_index(&g_index, g_repo)); +} + +void test_index_crlf__cleanup(void) +{ + git_index_free(g_index); + cl_git_sandbox_cleanup(); +} + +void test_index_crlf__autocrlf_false_no_attrs(void) +{ + const git_index_entry *entry; + git_oid oid; + + cl_repo_set_bool(g_repo, "core.autocrlf", false); + + cl_git_mkfile("./crlf/newfile.txt", + (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF); + + cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); + entry = git_index_get_bypath(g_index, "newfile.txt", 0); + + cl_git_pass(git_oid_fromstr(&oid, + (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_OID_CRLF : FILE_OID_LF)); + cl_assert(git_oid_cmp(&oid, &entry->id) == 0); +} + +void test_index_crlf__autocrlf_true_no_attrs(void) +{ + const git_index_entry *entry; + git_oid oid; + + cl_repo_set_bool(g_repo, "core.autocrlf", true); + + cl_git_mkfile("./crlf/newfile.txt", + (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF); + + cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); + entry = git_index_get_bypath(g_index, "newfile.txt", 0); + + cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_assert(git_oid_cmp(&oid, &entry->id) == 0); +} + +void test_index_crlf__autocrlf_input_no_attrs(void) +{ + const git_index_entry *entry; + git_oid oid; + + cl_repo_set_string(g_repo, "core.autocrlf", "input"); + + cl_git_mkfile("./crlf/newfile.txt", + (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF); + + cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); + entry = git_index_get_bypath(g_index, "newfile.txt", 0); + + cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_assert(git_oid_cmp(&oid, &entry->id) == 0); +} + +void test_index_crlf__autocrlf_false_text_auto_attr(void) +{ + const git_index_entry *entry; + git_oid oid; + + cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n"); + + cl_repo_set_bool(g_repo, "core.autocrlf", false); + + cl_git_mkfile("./crlf/newfile.txt", + (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF); + + cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); + entry = git_index_get_bypath(g_index, "newfile.txt", 0); + + cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_assert(git_oid_cmp(&oid, &entry->id) == 0); +} + +void test_index_crlf__autocrlf_true_text_auto_attr(void) +{ + const git_index_entry *entry; + git_oid oid; + + cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n"); + + cl_repo_set_bool(g_repo, "core.autocrlf", false); + + cl_git_mkfile("./crlf/newfile.txt", + (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF); + + cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); + entry = git_index_get_bypath(g_index, "newfile.txt", 0); + + cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_assert(git_oid_cmp(&oid, &entry->id) == 0); +} + +void test_index_crlf__autocrlf_input_text_auto_attr(void) +{ + const git_index_entry *entry; + git_oid oid; + + cl_git_mkfile("./crlf/.gitattributes", "* text=auto\n"); + + cl_repo_set_string(g_repo, "core.autocrlf", "input"); + + cl_git_mkfile("./crlf/newfile.txt", + (GIT_EOL_NATIVE == GIT_EOL_CRLF) ? FILE_CONTENTS_CRLF : FILE_CONTENTS_LF); + + cl_git_pass(git_index_add_bypath(g_index, "newfile.txt")); + entry = git_index_get_bypath(g_index, "newfile.txt", 0); + + cl_git_pass(git_oid_fromstr(&oid, FILE_OID_LF)); + cl_assert(git_oid_cmp(&oid, &entry->id) == 0); +}