git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 2/3] Define 'crlf' attribute.

From
Junio C Hamano <junkio@cox.net>
Date
Apr 13, 2007, 09:01 UTC
Message-ID
<7vps68d4wf.fsf@assigned-by-dhcp.cox.net>

This defines the semantics of 'crlf' attribute as an example. When a path has this attribute unset (i.e. '!crlf'), autocrlf line-end conversion is not applied.

Eventually we would want to let users to build a pipeline of processing to munge blob data to filesystem format (and in the other direction) based on combination of attributes, and at that point the mechanism in convert_to_{git,working_tree}() that looks at 'crlf' attribute needs to be enhanced. Perhaps the existing 'crlf' would become the first step in the input chain, and the last step in the output chain.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 attr.c          |   18 ++++++++++++++++++
 convert.c       |   49 ++++++++++++++++++++++++++++++++++++++++++-------
 t/t0020-crlf.sh |   24 ++++++++++++++++++++++++
 3 files changed, 84 insertions(+), 7 deletions(-)
diff --git a/attr.c b/attr.c
index bdbc4a3..d35ae9e 100644
--- a/attr.c
+++ b/attr.c
@@ -299,3 +299,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
-- 
1.5.1.1.784.g95e2
Next: Johannes Schindelin
Message 1 of 2 in “Define 'crlf' attribute.”
  1. 2/3 Define 'crlf' attribute.Junio C Hamano, Apr 13, 2007
  2. Johannes SchindelinApr 15, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.