Re: mingw, windows, crlf/lf, and git

Previous thread: Re: [PATCH] Add note about needing to do 'git checkout -f master'. by Junio C Hamano on Tuesday, February 13, 2007 - 11:06 am. (1 message)

Next thread: How do I get git-format-patch to ignore changes that remove spaces from the end of the line? by Timur Tabi on Tuesday, February 13, 2007 - 2:59 pm. (6 messages)
From: Mark Levedahl
Date: Tuesday, February 13, 2007 - 12:36 pm

Cygwin != Windows, Cygwin is a POSIX emulation layer with the explicit goal
of providing user tools behaving exactly as they do under Linux, and this
includes line ending style.

So, the Cygwin ports of various Linux tools are not expected to satisfy
users who want native Win32 behavior. This is where the mingw port of git
fits in. Yes, under Cygwin git can track files with \r\n endings, but: 
1) Those projects are not portable to non-windows platforms, and 
2) As you noted, git will have trouble with rebase, merge, etc. as there is
an assumption of \n endings throughout.

A proper win32 port will accept any of \n, \r\n as valid line endings (add
\r to support Mac pre-OSX if anyone cares, I still occasionally see such
files), treat any of them as semantically equal, and enforce the user's
chosen style (\n or \r\n) on output. cvsnt and svn under Windows do this
today, serving up "text" files from the same repository with \n endings or
\r\n endings depending upon the client, and is what we need a win32 git to
do as well.

Mark

-

From: Linus Torvalds
Date: Tuesday, February 13, 2007 - 1:32 pm

The patch I sent out does that, except right now the "autocrlf" flag is 
just a pure boolean.

I could easily make it take a ternary value:
 - off (normal UNIX semantics - never change anything)
 - on (turn CRLF->LF on input, turn LF->CRLF on output)
 - input-only (turn CRLF->LF on input, leave LF alone on output)

that would be just a couple of extra lines (almost all of them in the 
config file parsing logic).

[ The "output-only" case is obviously possible, but insane. It would turn 
  a LF-only file into CRLF on output, and then not turn it back on input, 
  so doing any "git commit -a" would basically turn every single lines 
  into CRLF, which you do NOT want. 

  So hopefully that explains the three - not four - cases ]

And the patch already leaves files that the user doesn't touch alone (ie 
if you check something out with CRLF turned off, and then turn it on in 
the config, nobody will care - the checked-out copy will have LF-only even 
if explicitly re-checking it out would turn it into CRLF, but that's fine.

It would be interesting to hear if the patch works for the MinGW people in 
particular. People using git with a Cygnus environment are probably used 
to try to keep files with just LF, since they are really trying to do a 
UNIX environment on top of Windows. But I suspect that WinGW people are 
more likely to use native Windows tools for things, and then perhaps just 
a smattering of UNIXy tools..

			Linus
-

From: Mark Levedahl
Date: Tuesday, February 13, 2007 - 6:42 pm

Wow, this is an incredible response: I expected I was going to be 
studying git internals for a while to get to this point. Thank you!

The ternary value is definitely useful. As noted elsewhere, most tools 
on windows are very happy with \n ending, few honor those line endings 
when files are modified, and fewer still allow the user to specify use 
of \n for new files. However, cygwin tools in particular are not 
tolerant of crlf, so for that environment it makes sense to banish crlf 
and the input-only option is most likely the best default setting there.

Mark

-

From: Linus Torvalds
Date: Tuesday, February 13, 2007 - 7:16 pm

Here's a UNTESTED patch on top of the patch I already sent, which allows 
you to do

	[core]
		AutoCRLF = input

and it should do only the CRLF->LF translation (ie it simplifies CRLF only 
when reading working tree files, but when checking out files, it leaves 
the LF alone, and doesn't turn it into a CRLF).

And by "untested" I mean that it looks ok and seems to compile, but I 
really didn't do anything else.

		Linus
---
diff --git a/config.c b/config.c
index ffe0212..e8ae919 100644
--- a/config.c
+++ b/config.c
@@ -325,6 +325,10 @@ int git_default_config(const char *var, const char *value)
 	}
 
 	if (!strcmp(var, "core.autocrlf")) {
+		if (value && !strcasecmp(value, "input")) {
+			auto_crlf = -1;
+			return 0;
+		}
 		auto_crlf = git_config_bool(var, value);
 		return 0;
 	}
diff --git a/convert.c b/convert.c
index c04b6c2..b5a47c2 100644
--- a/convert.c
+++ b/convert.c
@@ -133,7 +133,7 @@ int convert_to_working_tree(const char *path, char **bufp, unsigned long *sizep)
 	 * based on filename patterns. Right now we just do the
 	 * stupid auto-CRLF one.
 	 */
-	if (!auto_crlf)
+	if (auto_crlf <= 0)
 		return 0;
 
 	size = *sizep;
diff --git a/environment.c b/environment.c
index 2fa0960..570e32a 100644
--- a/environment.c
+++ b/environment.c
@@ -28,7 +28,7 @@ size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
 size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
 int pager_in_use;
 int pager_use_color = 1;
-int auto_crlf = 0;
+int auto_crlf = 0;	/* 1: both ways, -1: only when adding git objects */
 
 static const char *git_dir;
 static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
-

From: Robin Rosenberg
Date: Tuesday, February 13, 2007 - 2:58 pm

Line ending style is selectable in cygwin, both on a global level and path level (cygwin 
mounts). If you use CVS for windows development using CRLF works well and
is the only option if you want to use the same working are with both native CVS clients
like TortoiseCVS and the cygwin client. I use the CRLF style by default and LF only
for selected directories. The only annoying thing I see is that files transformed by patch end 

Even if there is a native port, I'm inclined to want to use the cygwin version 
anyway because of the nice shell and scripting capabilities and large selection of packages
that match what I'm used to in Linux. Git under cygwin should do CRLF transformations 
according to the same rules that apply to text files in cygwin.

-- robin
-

From: Mark Levedahl
Date: Tuesday, February 13, 2007 - 6:18 pm

The cygwin project is explicitly trying to bury the "text" mount option 
and drive towards binary (= \n line endings) only. They once had a rule 
that all cygwin programs fully grok \r\n, but that ethic disappeared a 
couple of years ago, it was just too hard. The cygwin git port itself 
will not operate on a text mount, it requires a binary mount, so crlf 
translations are simply not available with git under cygwin.

Mark

-

Previous thread: Re: [PATCH] Add note about needing to do 'git checkout -f master'. by Junio C Hamano on Tuesday, February 13, 2007 - 11:06 am. (1 message)

Next thread: How do I get git-format-patch to ignore changes that remove spaces from the end of the line? by Timur Tabi on Tuesday, February 13, 2007 - 2:59 pm. (6 messages)