Re: [PATCH 2/2] Define a few built-in attribute rules.

4 messages, 3 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH 2/2] Define a few built-in attribute rules.

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:43:04

Linus Torvalds [off-list ref] writes:
On Sat, 14 Apr 2007, Junio C Hamano wrote:
quoted
This adds an obviously sane pair of default attribute rules as built-ins.
I'm not sure.
quoted
+	"[attr]binary !diff !crlf",
+	"* diff crlf",
Why would 

	* diff crlf

be "obviously sane"?

In fact, I'd call it obviously insane.

We do *not* want to default crlf to all files. We want the default to be 
"automatic crlf depending on content". 
You do not have to worry.

That's how "crlf" is defined.  Paths you explicitly say !crlf
will _not_ go through the existing core.autocrlf mechanism.

"* crlf" just says, by default everybody is subject to core.autocrlf,
and on sane platforms, core.autocrlf is by default off, hence you will
not get LF <-> CRLF applied.

Re: [PATCH 2/2] Define a few built-in attribute rules.

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: 2016-06-15 22:43:04


On Sat, 14 Apr 2007, Junio C Hamano wrote:
You do not have to worry.
I do.
That's how "crlf" is defined.  Paths you explicitly say !crlf
will _not_ go through the existing core.autocrlf mechanism.
That's broken.

It should be:

 - "crlf": always do crlf.
 - "!crlf": never do crlf.
 - no attrbute: guess.

Why? Because quite frankly, it's quite possible that some file really *is* 
text, even if the content-based guessing doesn't catch it. 

It boils down to a simple truth: if our content-based guessing is so 
perfect that it never makes mistakes, there's no *point* to having a 
'crlf' attribute in the first place!

Here's a simple example:

	echo -e '\007Bell!' > bell

and just because we consider the BEL character to be binary, we'll think 
the file is binary.

Could we add the BEL character? Sure. But that's not the point. The 
*point* is that the whole and only reason for attributes in the first 
place is to _override_ guessing.

The guesses should be good enough that hopefully nobody really will ever 
need attributes. But people do strange things.

			Linus

[PATCH] Fix 'crlf' attribute semantics.

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:43:04

Earlier we said 'crlf lets the path go through core.autocrlf
process while !crlf disables it altogether'.  This fixes the
semantics to:

 - Lack of 'crlf' attribute makes core.autocrlf to apply
   (i.e. we guess based on the contents and if platform
   expresses its desire to have CRLF line endings via
   core.autocrlf, we do so).

 - Setting 'crlf' attribute to true forces CRLF line endings in
   working tree files, even if blob does not look like text
   (e.g. contains NUL or other bytes we consider binary).

 - Setting 'crlf' attribute to false disables conversion.

Signed-off-by: Junio C Hamano <redacted>
---

  Linus Torvalds [off-list ref] writes:

  > Here's a simple example:
  >
  > 	echo -e '\007Bell!' > bell
  >
  > and just because we consider the BEL character to be binary, we'll think 
  > the file is binary.

 You are right.  This replaces my earlier "we could do..." patch.

 convert.c |  122 +++++++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 78 insertions(+), 44 deletions(-)
diff --git a/convert.c b/convert.c
index 20c744a..d0d4b81 100644
--- a/convert.c
+++ b/convert.c
@@ -74,13 +74,13 @@ static int is_binary(unsigned long size, struct text_stat *stats)
 	return 0;
 }
 
-static int autocrlf_to_git(const char *path, char **bufp, unsigned long *sizep)
+static int crlf_to_git(const char *path, char **bufp, unsigned long *sizep, int guess)
 {
 	char *buffer, *nbuf;
 	unsigned long size, nsize;
 	struct text_stat stats;
 
-	if (!auto_crlf)
+	if (guess && !auto_crlf)
 		return 0;
 
 	size = *sizep;
@@ -94,19 +94,21 @@ static int autocrlf_to_git(const char *path, char **bufp, unsigned long *sizep)
 	if (!stats.cr)
 		return 0;
 
-	/*
-	 * We're currently not going to even try to convert stuff
-	 * that has bare CR characters. Does anybody do that crazy
-	 * stuff?
-	 */
-	if (stats.cr != stats.crlf)
-		return 0;
-
-	/*
-	 * And add some heuristics for binary vs text, of course...
-	 */
-	if (is_binary(size, &stats))
-		return 0;
+	if (guess) {
+		/*
+		 * We're currently not going to even try to convert stuff
+		 * that has bare CR characters. Does anybody do that crazy
+		 * stuff?
+		 */
+		if (stats.cr != stats.crlf)
+			return 0;
+
+		/*
+		 * And add some heuristics for binary vs text, of course...
+		 */
+		if (is_binary(size, &stats))
+			return 0;
+	}
 
 	/*
 	 * Ok, allocate a new buffer, fill it in, and return true
@@ -116,28 +118,42 @@ static int autocrlf_to_git(const char *path, char **bufp, unsigned long *sizep)
 	nbuf = xmalloc(nsize);
 	*bufp = nbuf;
 	*sizep = nsize;
-	do {
-		unsigned char c = *buffer++;
-		if (c != '\r')
-			*nbuf++ = c;
-	} while (--size);
+
+	if (guess) {
+		do {
+			unsigned char c = *buffer++;
+			if (c != '\r')
+				*nbuf++ = c;
+		} while (--size);
+	} else {
+		do {
+			unsigned char c = *buffer++;
+			if (! (c == '\r' && (1 < size && *buffer == '\n')))
+				*nbuf++ = c;
+		} while (--size);
+	}
 
 	return 1;
 }
 
-static int autocrlf_to_working_tree(const char *path, char **bufp, unsigned long *sizep)
+static int autocrlf_to_git(const char *path, char **bufp, unsigned long *sizep)
+{
+	return crlf_to_git(path, bufp, sizep, 1);
+}
+
+static int forcecrlf_to_git(const char *path, char **bufp, unsigned long *sizep)
+{
+	return crlf_to_git(path, bufp, sizep, 0);
+}
+
+static int crlf_to_working_tree(const char *path, char **bufp, unsigned long *sizep, int guess)
 {
 	char *buffer, *nbuf;
 	unsigned long size, nsize;
 	struct text_stat stats;
 	unsigned char last;
 
-	/*
-	 * FIXME! Other pluggable conversions should go here,
-	 * based on filename patterns. Right now we just do the
-	 * stupid auto-CRLF one.
-	 */
-	if (auto_crlf <= 0)
+	if (guess && auto_crlf <= 0)
 		return 0;
 
 	size = *sizep;
@@ -155,12 +171,14 @@ static int autocrlf_to_working_tree(const char *path, char **bufp, unsigned long
 	if (stats.lf == stats.crlf)
 		return 0;
 
-	/* If we have any bare CR characters, we're not going to touch it */
-	if (stats.cr != stats.crlf)
-		return 0;
+	if (guess) {
+		/* If we have any bare CR characters, we're not going to touch it */
+		if (stats.cr != stats.crlf)
+			return 0;
 
-	if (is_binary(size, &stats))
-		return 0;
+		if (is_binary(size, &stats))
+			return 0;
+	}
 
 	/*
 	 * Ok, allocate a new buffer, fill it in, and return true
@@ -182,6 +200,16 @@ static int autocrlf_to_working_tree(const char *path, char **bufp, unsigned long
 	return 1;
 }
 
+static int autocrlf_to_working_tree(const char *path, char **bufp, unsigned long *sizep)
+{
+	return crlf_to_working_tree(path, bufp, sizep, 1);
+}
+
+static int forcecrlf_to_working_tree(const char *path, char **bufp, unsigned long *sizep)
+{
+	return crlf_to_working_tree(path, bufp, sizep, 0);
+}
+
 static void setup_crlf_check(struct git_attr_check *check)
 {
 	static struct git_attr *attr_crlf;
@@ -191,31 +219,37 @@ static void setup_crlf_check(struct git_attr_check *check)
 	check->attr = attr_crlf;
 }
 
-static int git_path_is_binary(const char *path)
+static int git_path_check_crlf(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));
+	if (git_checkattr(path, 1, &attr_crlf_check))
+		return -1;
+	return attr_crlf_check.isset;
 }
 
 int convert_to_git(const char *path, char **bufp, unsigned long *sizep)
 {
-	if (git_path_is_binary(path))
+	switch (git_path_check_crlf(path)) {
+	case 0:
 		return 0;
-	return autocrlf_to_git(path, bufp, sizep);
+	case 1:
+		return forcecrlf_to_git(path, bufp, sizep);
+	default:
+		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))
+	switch (git_path_check_crlf(path)) {
+	case 0:
 		return 0;
-	return autocrlf_to_working_tree(path, bufp, sizep);
+	case 1:
+		return forcecrlf_to_working_tree(path, bufp, sizep);
+	default:
+		return autocrlf_to_working_tree(path, bufp, sizep);
+	}
 }
-- 
1.5.1.1.815.g3e763

Re: [PATCH] Fix 'crlf' attribute semantics.

From: Tom Prince <hidden>
Date: 2016-06-15 22:43:04

On Sun, Apr 15, 2007 at 04:10:56PM -0700, Junio C Hamano wrote:
Earlier we said 'crlf lets the path go through core.autocrlf
process while !crlf disables it altogether'.  This fixes the
semantics to:
This change means there is no way to enable the automatic heuristics for a
specific pattern once it has been disable for a more generic pattern. Would it
make sense to make the attributes more than simply boolean?

  Tom
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help