summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--attr.c18
-rw-r--r--convert.c49
-rwxr-xr-xt/t0020-crlf.sh24
3 files changed, 84 insertions, 7 deletions
diff --git a/attr.c b/attr.c
index 7435d92..ed4db01 100644
--- a/attr.c
+++ b/attr.c
@@ -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));
+}
diff --git a/convert.c b/convert.c
index 898bfe3..20c744a 100644
--- a/convert.c
+++ b/convert.c
@@ -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 723b29a..600dcd3 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