diff options
-rw-r--r-- | attr.c | 18 | ||||
-rw-r--r-- | convert.c | 49 | ||||
-rwxr-xr-x | t/t0020-crlf.sh | 24 |
3 files changed, 84 insertions, 7 deletions
@@ -378,3 +378,21 @@ int git_checkattr(const char *path, int num, struct git_attr_check *check) rem = fill(path, pathlen, stk, check, num, rem); return 0; } + +static void setup_binary_check(struct git_attr_check *check) +{ + static struct git_attr *attr_binary; + + if (!attr_binary) + attr_binary = git_attr("binary", 6); + check->attr = attr_binary; +} + +int git_path_is_binary(const char *path) +{ + struct git_attr_check attr_binary_check; + + setup_binary_check(&attr_binary_check); + return (!git_checkattr(path, 1, &attr_binary_check) && + (0 < attr_binary_check.isset)); +} @@ -1,4 +1,6 @@ #include "cache.h" +#include "attr.h" + /* * convert.c - convert a file when checking it out and checking it in. * @@ -72,17 +74,12 @@ static int is_binary(unsigned long size, struct text_stat *stats) return 0; } -int convert_to_git(const char *path, char **bufp, unsigned long *sizep) +static int autocrlf_to_git(const char *path, char **bufp, unsigned long *sizep) { char *buffer, *nbuf; unsigned long size, nsize; struct text_stat stats; - /* - * FIXME! Other pluggable conversions should go here, - * based on filename patterns. Right now we just do the - * stupid auto-CRLF one. - */ if (!auto_crlf) return 0; @@ -128,7 +125,7 @@ int convert_to_git(const char *path, char **bufp, unsigned long *sizep) return 1; } -int convert_to_working_tree(const char *path, char **bufp, unsigned long *sizep) +static int autocrlf_to_working_tree(const char *path, char **bufp, unsigned long *sizep) { char *buffer, *nbuf; unsigned long size, nsize; @@ -184,3 +181,41 @@ int convert_to_working_tree(const char *path, char **bufp, unsigned long *sizep) return 1; } + +static void setup_crlf_check(struct git_attr_check *check) +{ + static struct git_attr *attr_crlf; + + if (!attr_crlf) + attr_crlf = git_attr("crlf", 4); + check->attr = attr_crlf; +} + +static int git_path_is_binary(const char *path) +{ + struct git_attr_check attr_crlf_check; + + setup_crlf_check(&attr_crlf_check); + + /* + * If crlf is not mentioned, default to autocrlf; + * disable autocrlf only when crlf attribute is explicitly + * unset. + */ + return (!git_checkattr(path, 1, &attr_crlf_check) && + (0 == attr_crlf_check.isset)); +} + +int convert_to_git(const char *path, char **bufp, unsigned long *sizep) +{ + if (git_path_is_binary(path)) + return 0; + return autocrlf_to_git(path, bufp, sizep); +} + +int convert_to_working_tree(const char *path, char **bufp, unsigned long *sizep) +{ + if (git_path_is_binary(path)) + return 0; + return autocrlf_to_working_tree(path, bufp, sizep); +} diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 723b29ad17..600dcd30a0 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -214,4 +214,28 @@ test_expect_success 'apply patch --index (autocrlf=true)' ' } ' +test_expect_success '.gitattributes says two is binary' ' + + echo "two !crlf" >.gitattributes && + rm -f tmp one dir/two && + git repo-config core.autocrlf true && + git read-tree --reset -u HEAD && + + if remove_cr dir/two >/dev/null + then + echo "Huh?" + false + else + : happy + fi && + + if remove_cr one >/dev/null + then + : happy + else + echo "Huh?" + false + fi +' + test_done |