서로 다른 운영 체제 사이에서 줄 끝 변환이 git core.autocrlf와 작동하는 방식
core.autocrlf 설정 작동 방식 에 대한 자식 문서 뿐만 아니라 스택 오버플로에 대한 다양한 질문과 답변을 읽었습니다 .
이것은 내가 읽은 내용을 이해 한 것입니다.
Unix 및 Mac OSX (OSX 이전 버전에서는 CR 사용) 클라이언트는 LF 줄 끝을 사용합니다.
Windows 클라이언트는 CRLF 줄 끝을 사용합니다.
클라이언트에서 core.autocrlf가 true로 설정되면 git 리포지토리는 항상 LF 줄 끝 형식으로 파일을 저장하고 클라이언트에서 파일의 줄 끝은 체크 아웃 / 커밋시 클라이언트 (예 : Windows)에서 앞뒤로 변환됩니다. -LF 줄 끝 (줄 끝 파일이 어떤 형식으로 클라이언트에 있는지에 관계없이 (팀 Clem의 정의에 동의하지 않음-아래 업데이트 참조)
다음은 줄 끝 변환 동작이 확실하지 않은 물음표가있는 core.autocrlf의 '입력'및 '거짓'설정에 대해 동일하게 문서화하는 행렬입니다.
내 질문은 :
- 물음표는 무엇이어야합니까?
- 이 매트릭스가 "물음표"가 아닌가?
컨센서스가 형성된 것처럼 답변에서 물음표를 업데이트합니다.
core.autocrlf 값 참 입력 거짓 -------------------------------------------------- -------- 커밋 | 변환? ? 새로운 | LF로 (LF로 변환 하시겠습니까?) (전환 없음?) 커밋 | 로 변환하다 ? 아니 기존 | LF (LF로 변환?) 변환 결제 | 로 변환하다 ? 아니 기존 | CRLF (전환 없음) 전환
나는 다양한 환경의 장단점에 대한 의견을 실제로 찾고 있지 않습니다. git이 세 가지 설정 각각에서 작동하는 방법을 분명히하는 데이터를 찾고 있습니다.
-
업데이트 04/17/2012 : 주석에서 JJD에 의해 링크 된 Tim Clem의 기사를 읽은 후 위의 표에서 "알 수없는"값의 일부 값을 수정하고 "기존의 체크 아웃 | true로 변경 클라이언트로 전환하는 대신 CRLF로 다음은 그가 다른 곳에서 본 것보다 더 분명한 정의입니다.
core.autocrlf = 거짓
이것이 기본값이지만 대부분의 사람들은이를 즉시 변경하도록 권장합니다. false를 사용하면 Git이 파일의 줄 끝을 엉망으로 만들지 않습니다. LF 또는 CRLF 또는 CR 또는이 세 가지를 임의로 혼합하여 파일을 체크인 할 수 있으며 Git은 신경 쓰지 않습니다. 이로 인해 diff를 읽기 어렵고 병합하기가 더 어려워 질 수 있습니다. 유닉스 / 리눅스 세계에서 일하는 대부분의 사람들은 CRLF 문제가없고 파일이 객체 데이터베이스에 쓰여지거나 작업 디렉토리에 쓰여질 때마다 추가 작업을 수행 할 필요가 없기 때문에이 값을 사용합니다.
core.autocrlf = true
즉, Git은 모든 텍스트 파일을 처리하고 파일을 오브젝트 데이터베이스에 쓸 때 CRLF가 LF로 바뀌고 작업 디렉토리에 쓸 때 모든 LF를 다시 CRLF로 바꿉니다. 작업 디렉토리에 CRLF를 유지하면서 다른 플랫폼에서 저장소를 사용할 수 있으므로 Windows에서 권장되는 설정입니다.
core.autocrlf = 입력
즉, Git은 모든 텍스트 파일을 처리하고 해당 파일을 객체 데이터베이스에 쓸 때 CRLF가 LF로 바뀌어야합니다. 그러나 그 반대는 아닙니다. 오브젝트 데이터베이스에서 파일을 다시 읽고 작업 디렉토리에 파일을 쓰면 여전히 줄 끝을 나타내는 LF가 있습니다. 이 설정은 일반적으로 CRLF가 저장소에 작성되지 않도록 Unix / Linux / OS X에서 사용됩니다. 아이디어는 웹 브라우저에서 코드를 붙여 넣고 실수로 CRLF를 파일 중 하나에 넣은 경우 Git은 객체 데이터베이스에 쓸 때 LF로 대체되었는지 확인하는 것입니다.
Tim의 기사는 훌륭하지만, 내가 생각할 수없는 유일한 것은 저장소가 LF 형식이라고 가정한다는 것입니다. 특히 Windows 전용 프로젝트의 경우 반드시 사실은 아닙니다.
jmlane이 팀의 기사를 가장 많이 투표 한 답변과 비교하면 실제 및 입력 설정에 대한 완벽한 동의와 잘못된 설정에 대한 의견 불일치가 표시됩니다.
core.autocrlf
작동 방식에 대한 최상의 설명은 gitattributes 매뉴얼 페이지의 text
속성 섹션에 있습니다.
이것은 core.autocrlf
현재 (또는 적어도 내가 알고있는 것에서 v1.7.2 이후) 작동 하는 것처럼 보입니다.
core.autocrlf = true
- 문자 만있는 저장소에서 체크 아웃 된 텍스트 파일
LF
은CRLF
작업 트리에서 정규화됩니다 .CRLF
저장소에 포함 된 파일은 건드리지 않습니다 - 단지이 텍스트 파일
LF
저장소의 문자에서 정규화CRLF
에LF
저장소에 때 최선을 다하고 다시.CRLF
저장소에 포함 된 파일은 그대로 커밋됩니다.
- 문자 만있는 저장소에서 체크 아웃 된 텍스트 파일
core.autocrlf = input
- 저장소에서 체크 아웃 된 텍스트 파일은 작업 트리에 원본 EOL 문자를 유지합니다.
- 작업 트리에서
CRLF
문자가 있는 텍스트 파일LF
은 저장소로 다시 커밋 될 때 정규화됩니다 .
core.autocrlf = false
core.eol
작업 트리의 텍스트 파일에서 EOL 문자를 나타냅니다.core.eol = native
기본적으로 이는 Windows EOL이CRLF
있고 * nix EOL이LF
작업 트리에 있음을 의미합니다.- 리포지토리
gitattributes
설정은 리포지토리 커밋에 대한 EOL 문자 정규화를 결정합니다 (기본값은LF
문자에 대한 정규화 ).
나는 최근 에이 문제를 연구했으며 상황이 매우 복잡하다는 것을 알았습니다. 이 core.eol
설정은 git에서 EOL 문자를 처리하는 방법을 분명히하는 데 도움이되었습니다.
혼합 플랫폼 프로젝트에서 EOL 문제는 오랫동안 내 인생을 비참하게 만들었습니다. 이미 다른 혼합 EOLs의 파일이있을 때 문제는 일반적으로 발생하는 이미 의 repo한다. 이것은 다음을 의미합니다.
- 저장소에는 EOL이 다른 파일이있을 수 있습니다.
- REPO에서 일부 파일의 조합 예 혼합 EOL이있을 수 있습니다
CRLF
와LF
같은 파일을.
이 문제가 발생하는 방식은 여기서 문제가 아니지만 발생합니다.
다양한 모드와 그 조합에 대해 Windows에서 일부 변환 테스트를 실행했습니다.
다음은 약간 수정 된 테이블에서 얻은 것입니다.
| Resulting conversion when | Resulting conversion when | committing files with various | checking out FROM repo - | EOLs INTO repo and | with mixed files in it and | core.autocrlf value: | core.autocrlf value: -------------------------------------------------------------------------------- File | true | input | false | true | input | false -------------------------------------------------------------------------------- Windows-CRLF | CRLF -> LF | CRLF -> LF | as-is | as-is | as-is | as-is Unix -LF | as-is | as-is | as-is | LF -> CRLF | as-is | as-is Mac -CR | as-is | as-is | as-is | as-is | as-is | as-is Mixed-CRLF+LF | as-is | as-is | as-is | as-is | as-is | as-is Mixed-CRLF+LF+CR | as-is | as-is | as-is | as-is | as-is | as-is
As you can see, there are 2 cases when conversion happens on commit (3 left columns). In the rest of the cases the files are committed as-is.
Upon checkout (3 right columns), there is only 1 case where conversion happens when:
core.autocrlf
istrue
and- the file in the repo has the
LF
EOL.
Most surprising for me, and I suspect, the cause of many EOL problems is that there is no configuration in which mixed EOL like CRLF
+LF
get normalized.
Note also that "old" Mac EOLs of CR
only also never get converted.
This means that if a badly written EOL conversion script tries to convert a mixed ending file with CRLF
s+LF
s, by just converting LF
s to CRLF
s, then it will leave the file in a mixed mode with "lonely" CR
s wherever a CRLF
was converted to CRCRLF
.
Git will then not convert anything, even in true
mode, and EOL havoc continues. This actually happened to me and messed up my files really badly, since some editors and compilers (e.g. VS2010) don't like Mac EOLs.
I guess the only way to really handle these problems is to occasionally normalize the whole repo by checking out all the files in input
or false
mode, running a proper normalization and re-committing the changed files (if any). On Windows, presumably resume working with core.autocrlf true
.
Things are about to change on the "eol conversion" front, with the upcoming Git 1.7.2:
A new config setting core.eol
is being added/evolved:
This is a replacement for the 'Add "
core.eol
" config variable' commit that's currently inpu
(the last one in my series).
Instead of implying that "core.autocrlf=true
" is a replacement for "* text=auto
", it makes explicit the fact thatautocrlf
is only for users who want to work with CRLFs in their working directory on a repository that doesn't have text file normalization.
When it is enabled, "core.eol" is ignored.Introduce a new configuration variable, "
core.eol
", that allows the user to set which line endings to use for end-of-line-normalized files in the working directory.
It defaults to "native
", which means CRLF on Windows and LF everywhere else. Note that "core.autocrlf
" overridescore.eol
.
This means that:[core] autocrlf = true
puts CRLFs in the working directory even if
core.eol
is set to "lf
".core.eol:
Sets the line ending type to use in the working directory for files that have the
text
property set.
Alternatives are 'lf', 'crlf' and 'native', which uses the platform's native line ending.
The default value isnative
.
Other evolutions are being considered:
For 1.8, I would consider making
core.autocrlf
just turn on normalization and leave the working directory line ending decision to core.eol, but that will break people's setups.
git 2.8 (March 2016) improves the way core.autocrlf
influences the eol:
See commit 817a0c7 (23 Feb 2016), commit 6e336a5, commit df747b8, commit df747b8 (10 Feb 2016), commit df747b8, commit df747b8 (10 Feb 2016), and commit 4b4024f, commit bb211b4, commit 92cce13, commit 320d39c, commit 4b4024f, commit bb211b4, commit 92cce13, commit 320d39c (05 Feb 2016) by Torsten Bögershausen (tboegi
).
(Merged by Junio C Hamano -- gitster
-- in commit c6b94eb, 26 Feb 2016)
convert.c
: refactorcrlf_action
Refactor the determination and usage of
crlf_action
.
Today, when no "crlf
" attribute are set on a file,crlf_action
is set toCRLF_GUESS
. UseCRLF_UNDEFINED
instead, and search for "text
" or "eol
" as before.Replace the old
CRLF_GUESS
usage:
CRLF_GUESS && core.autocrlf=true -> CRLF_AUTO_CRLF
CRLF_GUESS && core.autocrlf=false -> CRLF_BINARY
CRLF_GUESS && core.autocrlf=input -> CRLF_AUTO_INPUT
Make more clear, what is what, by defining:
- CRLF_UNDEFINED : No attributes set. Temparally used, until core.autocrlf
and core.eol is evaluated and one of CRLF_BINARY,
CRLF_AUTO_INPUT or CRLF_AUTO_CRLF is selected
- CRLF_BINARY : No processing of line endings.
- CRLF_TEXT : attribute "text" is set, line endings are processed.
- CRLF_TEXT_INPUT: attribute "input" or "eol=lf" is set. This implies text.
- CRLF_TEXT_CRLF : attribute "eol=crlf" is set. This implies text.
- CRLF_AUTO : attribute "auto" is set.
- CRLF_AUTO_INPUT: core.autocrlf=input (no attributes)
- CRLF_AUTO_CRLF : core.autocrlf=true (no attributes)
As torek adds in the comments:
all these translations (any EOL conversion from
eol=
orautocrlf
settings, and "clean
" filters) are run when files move from work-tree to index, i.e., duringgit add
rather than atgit commit
time.
(Note thatgit commit -a
or--only
or--include
do add files to the index at that time, though.)
For more on that, see "What is difference between autocrlf and eol".
core.autocrlf
value does not depend on OS type but on Windows default value is true
and for Linux - input
. I explored 3 possible values for commit and checkout cases and this is the resulting table:
╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║ false ║ input ║ true ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║ ║ LF => LF ║ LF => LF ║ LF => LF ║
║ git commit ║ CR => CR ║ CR => CR ║ CR => CR ║
║ ║ CRLF => CRLF ║ CRLF => LF ║ CRLF => LF ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║ ║ LF => LF ║ LF => LF ║ LF => CRLF ║
║ git checkout ║ CR => CR ║ CR => CR ║ CR => CR ║
║ ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝
Here is my understanding of it so far, in case it helps someone.
core.autocrlf=true
and core.safecrlf = true
You have a repository where all the line endings are the same, but you work on different platforms. Git will make sure your lines endings are converted to the default for your platform. Why does this matter? Let's say you create a new file. The text editor on your platform will use its default line endings. When you check it in, if you don't have core.autocrlf set to true, you've introduced a line ending inconsistency for someone on a platform that defaults to a different line ending. I always set safecrlf too because I would like to know that the crlf operation is reversible. With these two settings, git is modifying your files, but it verifies that the modifications are reversible.
core.autocrlf=false
You have a repository that already has mixed line endings checked in and fixing the incorrect line endings could break other things. Its best not to tell git to convert line endings in this case, because then it will exacerbate the problem it was designed to solve - making diffs easier to read and merges less painful. With this setting, git doesn't modify your files.
core.autocrlf=input
I don't use this because the reason for this is to cover a use case where you created a file that has CRLF line endings on a platform that defaults to LF line endings. I prefer instead to make my text editor always save new files with the platform's line ending defaults.
Did some tests both on linux and windows. I use a test file containing lines ending in LF and also lines ending in CRLF.
File is committed , removed and then checked out. The value of core.autocrlf is set before commit and also before checkout. The result is below.
commit core.autocrlf false, remove, checkout core.autocrlf false: LF=>LF CRLF=>CRLF
commit core.autocrlf false, remove, checkout core.autocrlf input: LF=>LF CRLF=>CRLF
commit core.autocrlf false, remove, checkout core.autocrlf true : LF=>LF CRLF=>CRLF
commit core.autocrlf input, remove, checkout core.autocrlf false: LF=>LF CRLF=>LF
commit core.autocrlf input, remove, checkout core.autocrlf input: LF=>LF CRLF=>LF
commit core.autocrlf input, remove, checkout core.autocrlf true : LF=>CRLF CRLF=>CRLF
commit core.autocrlf true, remove, checkout core.autocrlf false: LF=>LF CRLF=>LF
commit core.autocrlf true, remove, checkout core.autocrlf input: LF=>LF CRLF=>LF
commit core.autocrlf true, remove, checkout core.autocrlf true : LF=>CRLF CRLF=>CRLF
No, the @jmlane answer is wrong.
For Checkin (git add, git commit)
:
- if
text
property isSet, Set value to 'auto'
, the conversion happens enen the file has been committed with 'CRLF' - if
text
property isUnset
:nothing happens, enen forCheckout
- if
text
property isUnspecified
, conversion depends oncore.autocrlf
- if
autocrlf = input or autocrlf = true
, the conversion only happens when the file in the repository is 'LF', if it has been 'CRLF', nothing will happens. - if
autocrlf = false
, nothing happens
- if
For Checkout
:
- if
text
property isUnset
: nothing happens. - if
text
property isSet, Set value to 'auto
: it depends oncore.autocrlf
,core.eol
.- core.autocrlf = input : nothing happens
- core.autocrlf = true : the conversion only happens when the file in the repository is 'LF', 'LF' -> 'CRLF'
- core.autocrlf = false : the conversion only happens when the file in the repository is 'LF', 'LF' ->
core.eol
- if
text
property isUnspecified
, it depends oncore.autocrlf
.- the same as
2.1
- the same as
2.2
- None, nothing happens, core.eol is not effective when
text
property isUnspecified
- the same as
Default behavior
So the Default behavior is text
property is Unspecified
and core.autocrlf = false
:
- for checkin, nothing happens
- for checkout, nothing happens
Conclusions
- 경우
text
속성을 설정, 동작을한다 체크인하는 것은 autocrlf에, 그 자체에 있지 따라 - autocrlf 또는 core.eol은 체크 아웃 동작을위한 것이며 autocrlf> core.eol
'Programming' 카테고리의 다른 글
Git에서 되 돌린 병합 다시 실행 (0) | 2020.05.06 |
---|---|
웹 사이트 스트레스 테스트를위한 최선의 방법 (0) | 2020.05.06 |
최신 C ++로 무료 성능을 얻을 수 있습니까? (0) | 2020.05.06 |
Git의 저자와 커미터의 차이점은 무엇입니까? (0) | 2020.05.06 |
Git에서 루트 커밋 앞에 커밋을 삽입 하시겠습니까? (0) | 2020.05.05 |