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 -
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 -
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 -
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;
-
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 -
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 -
