threads / patch / 8201

patchFix crlf attribute handling to match documentation

Subject: [PATCH] Fix crlf attribute handling to match documentation

## tl;dr

4 messages between May 18, 2007 and May 19, 2007. Diffs are folded; open one to read it.

replies: 3people: 2as markdown or json

Andy Parkins· May 18, 2007, 12:33 UTC · lore
gitattributes.txt says, of the crlf attribute:
 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.

That is to say that the crlf attribute does not force the file to have CRLF line endings, instead it removes the autocrlf guesswork and forces the file to be treated as text. Then, whatever line ending is defined by the autocrlf setting is applied.

However, that is not what convert.c was doing. The conversion to CRLF was being skipped in crlf_to_worktree() when the following condition was true:

 action == CRLF_GUESS && auto_crlf <= 0

That is to say conversion took place when not in guess mode (crlf attribute not specified) or core.autocrlf set to true. This was wrong. It meant that the crlf attribute being on for a given file _forced_ CRLF conversion, when actually it should force the file to be treated as text, and converted accordingly. The real test should simply be

 auto_crlf <= 0

That is to say, if core.autocrlf is falsei (or input), conversion from LF to CRLF is never done. When core.autocrlf is true, conversion from LF to CRLF is done only when in CRLF_GUESS (and the guess is "text"), or CRLF_TEXT mode.

Similarly for crlf_to_worktree(), if core.autocrlf is false, no conversion should _ever_ take place. In reality it was only not taking place if core.autocrlf was false _and_ the crlf attribute was unspecified.

Signed-off-by: Andy Parkins <andyparkins@gmail.com>
---
 convert.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
Show changes to convert.c +2 −2
diff --git a/convert.c b/convert.c
index 12abdaf..86d8167 100644
--- a/convert.c
+++ b/convert.c
@@ -86,7 +86,7 @@ static char *crlf_to_git(const char *path, const char *src, unsigned long *sizep
 	unsigned long size, nsize;
 	struct text_stat stats;
 
-	if ((action == CRLF_BINARY) || (action == CRLF_GUESS && !auto_crlf))
+	if ((action == CRLF_BINARY) || !auto_crlf)
 		return NULL;
 
 	size = *sizep;
@@ -154,7 +154,7 @@ static char *crlf_to_worktree(const char *path, const char *src, unsigned long *
 	unsigned char last;
 
 	if ((action == CRLF_BINARY) || (action == CRLF_INPUT) ||
-	    (action == CRLF_GUESS && auto_crlf <= 0))
+	    auto_crlf <= 0)
 		return NULL;
 
 	size = *sizep;
-- 
1.5.2.rc3.51.gd07bc
Junio C Hamano· May 18, 2007, 18:28 UTC · re: Andy Parkins · lore

Re: [PATCH] Fix crlf attribute handling to match documentation

Andy Parkins <andyparkins@gmail.com> writes:
> gitattributes.txt says, of the crlf attribute:
> ...
> However, that is not what convert.c was doing.
Thanks.  I'll take a look later.

Some addition to the existing test t/t0020-crlf.sh to demonstrate this bug and your fix would be appropriate.

Junio C Hamano· May 19, 2007, 00:02 UTC · re: Andy Parkins · lore

Re: [PATCH] Fix crlf attribute handling to match documentation

Andy Parkins <andyparkins@gmail.com> writes:
Show 12 quoted lines
> gitattributes.txt says, of the crlf attribute:
>
>  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.
>
> That is to say that the crlf attribute does not force the file to have
> CRLF line endings, instead it removes the autocrlf guesswork and forces
> the file to be treated as text.  Then, whatever line ending is defined
> by the autocrlf setting is applied.

Thanks; I looked at the patch (although I am still _physically_ at work ;-). I think your code is correct but the explanation is slightly misleading.

Show 5 quoted lines
> However, that is not what convert.c was doing.  The conversion to CRLF
> was being skipped in crlf_to_worktree() when the following condition was
> true:
>
>  action == CRLF_GUESS && auto_crlf <= 0

The check you modified in the first hunk is not the above '<=' comparison but is this:

	(action == CRLF_GUESS && !auto_crlf)

and "core.autocrlf = input" makes "auto_crlf = -1", so when action is not GUESS, or even when action is GUESS, if the config is set to "input", the if() statement you patched in the first hunk should not trigger. The above description is different from what the code was doing.

The logic (in crlf_to_git, which is the input codepath) should be:
	* if action is BINARY, do nothing (obviously -- and the
          code gets this right).
	* if action is GUESS, do nothing if config says false
          (we want 'input' and 'true' to apply the munging after
          guessing).
	* if action is TEXT or INPUT, do not guess but do CRLF
          only on platforms that need it -- which means where
          auto_crlf is -1 (input) or 1 (true).  Otherwise do not
          do the conversion.

The original code gets the third case incorrectly, and your patch fixes it by returning early in that case as well.

The output codepath is the same. Regardless of action (GUESS/TEXT/INPUT), we will not do anything if config says 'false' or 'input', so removing the check with "action == GUESS" is the right thing.

Andy Parkins· May 19, 2007, 09:58 UTC · re: Junio C Hamano · lore

Re: [PATCH] Fix crlf attribute handling to match documentation

On Saturday 2007, May 19, Junio C Hamano wrote:
> The check you modified in the first hunk is not the above '<='
> comparison but is this:

I was talking about the second hunk there though, which I mentioned with "...skipped in crlf_to_worktree()...". In which case the description matches.

Show 7 quoted lines
> 	(action == CRLF_GUESS && !auto_crlf)
>
> and "core.autocrlf = input" makes "auto_crlf = -1", so when
> action is not GUESS, or even when action is GUESS, if the config
> is set to "input", the if() statement you patched in the first
> hunk should not trigger.  The above description is different from
> what the code was doing.
As I say, the description was for the second hunk.

The fault was my last paragraph, "Similarly for crlf_to_worktree(), if core.autocrlf is false, no", which should have said "Similarly for crlf_to_git()". Sorry.

With that small change I think my description was correct. However, it obviously wasn't clear - apologies.

Andy
-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com

← back to recent threads