Reputation: 4484
I am handling a C++/C repository, for both Windows and Linux environments. In fact, the editor on Windows and Linux can accept textfile with either CR/LF or LF ending (even mixed mode). The problem is that, the user may create new .cpp, .h files with their native line ending format (CR/LF, or just LF). What is the best settings for .gitattributes?
To describe the problem is detail, I have an assumption, and want to meet the following requirements:
The Assumption: I don't care if a checkout gets CR/LF or LF ending style, since modern editors can handle both, either on Windows or Un*x.
Requirement 1. If two versions of files differs only in their line endings styles, the system (meaning git client, git database, etc..) shall regard them as the same version. Thus git diff should show no difference, git merge won't need to do anything... etc..
Requirement 2. The files in the working directory shall be kept as is. Even some of the files may be in DOS-style, and some of the files in Unix-style. (For example, on Windows, some files are edited by VIM under cygwin, which has Unix-style, and some uses native windows editor, which results in DOS-style). i.e. In the working directory, the files' ending style shall not be changed due to any git transaction (commit, merge, etc ...) [Oh, I can accept when a merge occurs, files may be changed.]
In addition, I found this bug? in git: (see the following transactions)
bash (master) $ git status
# On branch master nothing to commit (working directory clean)
bash (master) $ file a.c
a.c: C source, ASCII text, with CRLF line terminators
bash (master) $ dos2unix a.c
dos2unix: converting file a.c to Unix format ...
bash (master) $ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: a.c
# no changes added to commit (use "git add" and/or "git commit -a")
bash (master) $ git add a.c
bash (master) $ git status
# On branch master
nothing to commit (working directory clean)
As you can see in the transaction, when the line ending style changes, git status
does not realize that the changes are merely the line endings, and reports the modification of a.c
. Though after git add a.c
, the status was corrected. My .gitattributes force all .c and .h to use lf
only:
bash (master) $ cat .gitattributes
* text=auto
*.c text eol=lf
*.C text eol=lf
*.cpp text eol=lf
*.CPP text eol=lf
*.h text eol=lf
*.H text eol=lf
*.hpp text eol=lf
*.HPP text eol=lf
*.pro text eol=crlf
Could anyone show me how to avoid it, or is it a bug? (or just an as-is behavior, not a bug, since asking git status
to sense the line end changes requires a diff
which is costly?)?
I have read this link, yet it does not answer me if the files in working directories will be changed or not. And I have searched many links and found some suggestions for a pure system like Linux or Windows, but can anyone have suggestions for a combined system, like Windows + Cygwin on a same system?
Upvotes: 1
Views: 390
Reputation: 1182
Trying to answer only this part of the question:
git diff
should show no difference for files differing only in line-ending style...
diff
command has a --strip-trailing-cr
option that ignores LF vs CRLF distinctionsgit allows an external diff command. So we make a difficr
(diff-ignore-cr) command thus:
$ cat difficr
#! /bin/sh
diff --strip-trailing-cr "$2" "$5"
The $2
and $5
are because those are the actual file args.
See the GIT_EXTERNAL_DIFF in the main git
man-page.
And setup git config:
$ git config --global diff.external "/path/to/difficr"
Now you should find that git diff
s ignore LF vs CRLF distinctions.
[At least my experiments show it to do so]
Upvotes: 2