git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: git@vger.kernel.org
Subject: Re: [RFR] gitattributes(5) documentation
Date: Thu, 19 Apr 2007 22:02:08 -0700	[thread overview]
Message-ID: <7virbr4p0v.fsf@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: <alpine.LFD.0.98.0704191835290.9964@woody.linux-foundation.org> (Linus Torvalds's message of "Thu, 19 Apr 2007 18:45:01 -0700 (PDT)")

Linus Torvalds <torvalds@linux-foundation.org> writes:

> This documented behaviour is non-optimal for a few reasons:
>  - it makes it impossible to say "this is text", and have it work on UNIX 
>    platforms ;)
>  - it makes it impossible to have "autocrlf=input", and then correct one 
>    single file that was incorrectly guessed to be binary, and have that 
>    file behave like other files.
>
> So I _think_ the right rules are:
>
>  - unspecified: use autocrlf *and* content detection logic
>  - unset: never do crlf<->lf ("binary")
>  - set: use autocrlf without content detection logic ("text")
>
> with possibly an added rule:
>
>  - set to value: "true" or "input" force that particular setting 
>    *regardless* of autocrlf, ie we'd always get CRLF even on UNIX.

A patch (only compile and testsuite tested but otherwise not
tested) is attached; loses more lines than it adds.

Here is a rewrite of the `crlf` section.

-- >8 --
Checking-out and checking-in
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The attribute `crlf` affects how the contents stored in the
repository are copied to the working tree files when commands
such as `git checkout` and `git merge` run.  It also affects how
git stores the contents you prepare in the working tree in the
repository upon `git add` and `git commit`.

Set::

	Setting the `crlf` attribute on a path is meant to mark
	the path as a "text" file.  'core.autocrlf' conversion
	takes place without guessing the content type by
	inspection.

Unset::

	Unsetting the `crlf` attribute on a path is meant to
	mark the path as a "binary" file.  The path never goes
	through line endings conversion upon checkin/checkout.

Unspecified::

	Unspecified `crlf` attribute tells git to apply the
	`core.autocrlf` conversion when the file content looks
	like text.

Set to string value "input"::

	This is similar to setting the attribute to `true`, but
	also forces git to act as if `core.autocrlf` is set to
	`input` for the path.

Any other value set to `crlf` attribute is ignored and git acts
as if the attribute is left unspecified.


The `core.autocrlf` conversion
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If the configuration variable `core.autocrlf` is false, no
conversion is done.

When `core.autocrlf` is true, it means that the platform wants
CRLF line endings for files in the working tree, and you want to
convert them back to the normal LF line endings when checking
in to the repository.

When `core.autocrlf` is set to "input", line endings are
converted to LF upon checkin, but there is no conversion done
upon checkout.
-- 8< --

 convert.c |   75 +++++++++++++++++++++---------------------------------------
 1 files changed, 26 insertions(+), 49 deletions(-)

diff --git a/convert.c b/convert.c
index a5f60c7..da64253 100644
--- a/convert.c
+++ b/convert.c
@@ -10,6 +10,11 @@
  * translation when the "auto_crlf" option is set.
  */
 
+#define CRLF_GUESS	(-1)
+#define CRLF_BINARY	0
+#define CRLF_TEXT	1
+#define CRLF_INPUT	2
+
 struct text_stat {
 	/* CR, LF and CRLF counts */
 	unsigned cr, lf, crlf;
@@ -74,13 +79,13 @@ static int is_binary(unsigned long size, struct text_stat *stats)
 	return 0;
 }
 
-static int crlf_to_git(const char *path, char **bufp, unsigned long *sizep, int guess)
+static int crlf_to_git(const char *path, char **bufp, unsigned long *sizep, int action)
 {
 	char *buffer, *nbuf;
 	unsigned long size, nsize;
 	struct text_stat stats;
 
-	if (guess && !auto_crlf)
+	if ((action == CRLF_BINARY) || (action == CRLF_GUESS && !auto_crlf))
 		return 0;
 
 	size = *sizep;
@@ -94,7 +99,7 @@ static int crlf_to_git(const char *path, char **bufp, unsigned long *sizep, int
 	if (!stats.cr)
 		return 0;
 
-	if (guess) {
+	if (action == CRLF_GUESS) {
 		/*
 		 * We're currently not going to even try to convert stuff
 		 * that has bare CR characters. Does anybody do that crazy
@@ -119,7 +124,12 @@ static int crlf_to_git(const char *path, char **bufp, unsigned long *sizep, int
 	*bufp = nbuf;
 	*sizep = nsize;
 
-	if (guess) {
+	if (action == CRLF_GUESS) {
+		/*
+		 * If we guessed, we already know we rejected a file with
+		 * lone CR, and we can strip a CR without looking at what
+		 * follow it.
+		 */
 		do {
 			unsigned char c = *buffer++;
 			if (c != '\r')
@@ -136,24 +146,15 @@ static int crlf_to_git(const char *path, char **bufp, unsigned long *sizep, int
 	return 1;
 }
 
-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)
+static int crlf_to_worktree(const char *path, char **bufp, unsigned long *sizep, int action)
 {
 	char *buffer, *nbuf;
 	unsigned long size, nsize;
 	struct text_stat stats;
 	unsigned char last;
 
-	if (guess && auto_crlf <= 0)
+	if ((action == CRLF_BINARY) || (action == CRLF_INPUT) ||
+	    (action == CRLF_GUESS && auto_crlf <= 0))
 		return 0;
 
 	size = *sizep;
@@ -171,7 +172,7 @@ static int crlf_to_working_tree(const char *path, char **bufp, unsigned long *si
 	if (stats.lf == stats.crlf)
 		return 0;
 
-	if (guess) {
+	if (action == CRLF_GUESS) {
 		/* If we have any bare CR characters, we're not going to touch it */
 		if (stats.cr != stats.crlf)
 			return 0;
@@ -200,16 +201,6 @@ static int crlf_to_working_tree(const char *path, char **bufp, unsigned long *si
 	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;
@@ -228,38 +219,24 @@ static int git_path_check_crlf(const char *path)
 	if (!git_checkattr(path, 1, &attr_crlf_check)) {
 		const char *value = attr_crlf_check.value;
 		if (ATTR_TRUE(value))
-			return 1;
+			return CRLF_TEXT;
 		else if (ATTR_FALSE(value))
-			return 0;
+			return CRLF_BINARY;
 		else if (ATTR_UNSET(value))
 			;
-		else
-			die("unknown value %s given to 'crlf' attribute",
-			    (char *)value);
+		else if (!strcmp(value, "input"))
+			return CRLF_INPUT;
+		/* fallthru */
 	}
-	return -1;
+	return CRLF_GUESS;
 }
 
 int convert_to_git(const char *path, char **bufp, unsigned long *sizep)
 {
-	switch (git_path_check_crlf(path)) {
-	case 0:
-		return 0;
-	case 1:
-		return forcecrlf_to_git(path, bufp, sizep);
-	default:
-		return autocrlf_to_git(path, bufp, sizep);
-	}
+	return crlf_to_git(path, bufp, sizep, git_path_check_crlf(path));
 }
 
 int convert_to_working_tree(const char *path, char **bufp, unsigned long *sizep)
 {
-	switch (git_path_check_crlf(path)) {
-	case 0:
-		return 0;
-	case 1:
-		return forcecrlf_to_working_tree(path, bufp, sizep);
-	default:
-		return autocrlf_to_working_tree(path, bufp, sizep);
-	}
+	return crlf_to_worktree(path, bufp, sizep, git_path_check_crlf(path));
 }

  reply	other threads:[~2007-04-20  5:02 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-09  8:17 What's cooking in git.git (topics) Junio C Hamano
2007-04-16  1:53 ` Junio C Hamano
2007-04-19  0:04   ` Junio C Hamano
     [not found]     ` <7vslav4yv6.fsf_ -_@assigned-by-dhcp.cox.net>
2007-04-19  0:23     ` Alex Riesen
2007-04-19  2:39     ` Nicolas Pitre
2007-04-19 10:07     ` Martin Waitz
2007-04-20 11:14       ` Junio C Hamano
2007-04-20 11:58         ` Alex Riesen
2007-04-20 19:31         ` Sam Ravnborg
2007-04-21  6:09           ` Martin Waitz
2007-04-21  7:11             ` Linus Torvalds
2007-04-20  1:29     ` [RFR] gitattributes(5) documentation Junio C Hamano
2007-04-20  1:45       ` Linus Torvalds
2007-04-20  5:02         ` Junio C Hamano [this message]
2007-04-22  0:51           ` David Lang
2007-04-22  7:02             ` Junio C Hamano
2007-04-22  9:33               ` David Lang
2007-04-20  1:57       ` Nicolas Pitre
2007-04-22  6:24     ` What's cooking in git.git (topics) Junio C Hamano
2007-04-23  7:04       ` Junio C Hamano
2007-04-23 16:16         ` Nicolas Pitre
2007-04-23 17:07         ` Alex Riesen
2007-04-23 17:15           ` Junio C Hamano
2007-04-23 21:16             ` Alex Riesen
2007-04-23 21:51               ` Junio C Hamano
2007-04-24 15:58                 ` Alex Riesen
2007-04-24 16:04                   ` Johannes Schindelin
2007-04-24 16:14                     ` Alex Riesen
2007-04-24 16:44                       ` Johannes Schindelin
2007-04-24 21:41                   ` Junio C Hamano
2007-04-25  8:11                     ` Alex Riesen
2007-04-23 17:25           ` Johannes Schindelin
2007-04-27  8:24         ` Junio C Hamano
2007-04-29 18:33           ` Junio C Hamano
2007-04-29 18:45             ` Linus Torvalds
2007-04-30 23:20               ` Junio C Hamano
2007-05-06  8:53             ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7virbr4p0v.fsf@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).