git 에서 CRLF 개행 문자 차이로 인한 문제 해결하기
익히 알다시피 Windows 에서는 line ending으로 CR(Carriage-Return, \r)과 LF(Line Feed, \n)을 사용하고 Unix 나 Mac OS 는 LF 만 사용한다.
이는 상당히 골치아픈 문제를 발생시킨다. 실제 코드는 변경된 게 없는데 소스의 CR/LF 때문에 변경으로 착각하여 commit 을 하게 될 수 있으며 변경 로그를 보거나 merge 마다 문제가 될 소지가 있다.
이런 문제를 방지하기 위해 OS 가 달라도 문제가 없도록 crlf 처리 방법을 결정해야 한다.
git 설정
core.eof
git 이 line ending을 어떻게 처리하는지 관련된 항목이다. 세 가지 설정을 할 수 있다.
- core.eol = native. 기본 설정. 시스템에서 line ending 을 처리하는 방법에 따른다. windows에서는 CRLF 를 사용하고 Linux, OS X 는 LF 만 사용한다.
- core.eol = crlf CRLF 를 line ending 으로 사용한다.
- core.eol = lf LF를 line ending 으로 사용한다.
설정은 다음 명령어로 수행할 수 있다.
## 설정 $ git config --global core.eol native ## 설정 확인 $ git config --global --list|grep core.eol
core.autocrlf
git 은 저장소 메타 데이타 디렉터리인 .git 폴더에 모든 이력 데이타를 갖고 있다. 이력 데이타는 key/value 형식의 데이타베이스이며 core.autocrlf 는 text file 을 git object database 에 checkin, checkout 할 때 어떻게 처리할지를 설정하는 변수이다.
다음 세 가지 설정이 가능하다.
- core.autocrlf = false. 기본 설정이다. 파일에 CRLF 를 썼든 LF 를 썼든 git 은 상관하지 않고 파일 그대로 checkin, checkout 한다. 이 설정은 line ending 이 다른 OS 에서는 text file 이 변경되었다고 나오므로 위에서 언급한 여러 가지 문제가 발생할 수 있다.
- core.autocrlf = true text file을 object database 에 넣기전에 CRLF 를 LF 로 변경한다.
- core.autocrlf = input LF를 line ending 으로 사용한다.
해결책
방법 #1 - autocrlf 설정 사용
OS 별 CRLF 차이로 인한 문제를 막기 위해 OS 별로 다음과 같이 crlf 처리 방법을 설정하는 걸 권장한다.
Windows
윈도에서는 CRLF 를 사용하므로 저장소에서 가져올 때 LF 를 CRLF 로 변경하고 저장소로 보낼 때는 CRLF 를 LF 로 변경하도록 true 로 설정한다.
git config --global core.autocrlf true
Linux, Mac OS
리눅스, 맥, 유닉스는 LF 만 사용하므로 input 으로 설정한다.
git config --global core.autocrlf input
방법 #2 - .gitattributes 사용
git 은 텍스트 파일의 속성을 .gitattributes 파일을 통해 설정할 수 있으며 여기에는 crlf 처리도 지정할 수 있다. .gitattributes 를 저장소에 커밋하면 다른 클라이언트는 별도의 설정이 필요없다.
# Auto detect text files and perform LF normalization * text=auto *.cs text diff=csharp *.java text diff=java *.html text diff=html *.css text *.js text *.sql text *.csproj text merge=union *.sln text merge=union eol=crlf *.docx diff=astextplain *.DOCX diff=astextplain # absolute paths are ok, as are globs /**/postinst* text eol-lf # paths that don't start with / are treated relative to the .gitattributes folder relative/path/*.txt text eol-lf
만약 git client 로 egit 을 사용하면 .gitattributes 를 읽지 못하므로 제대로 동작 안 하므로 방법 #1 을 사용해야 한다.
Ref
- http://stackoverflow.com/questions/170961/whats-the-best-crlf-handling-strategy-with-git
- http://stackoverflow.com/questions/2333424/distributing-git-configuration-with-the-code/2354278#2354278
- http://stackoverflow.com/questions/2825428/why-should-i-use-core-autocrlf-true-in-git
- http://git-scm.com/book/ko/Git%EB%A7%9E%EC%B6%A4-Git-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0
- http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/