문제 발생

회사 PC는 윈도우를 사용하고 있으며 도커 환경(linux)에서 작업을 진행하고 있다. 개인노트북은 M1 맥북으로 재택이나 주말(심심할때)에 작업을 진행하고 있다. 근데, winodws > docker 컨테이너 환경으로 들어가면 변경된게 없는데 모든 소스코드가 변경된것 처럼 발생한다.

그 이유는 OS별로 CR/LF 새줄 문자 처리하는게 다르기 때문이다.
새줄 문자(new line)이란, 텍스트의 한 줄이 끝남을 표시하는 문자 또는 문자열을 말한다. 개행 문자, 줄바꿈 문자(line break), EOL(end-of-line) 모두 같은 말이다. 기종이나 운영체제별로 새줄 문자를 나타내는 코드가 다를 수 있다. 그래서 git 사용시 새줄 문자를 통일시켜야 한다.

Windows Linux / Mac OS
LF(Line Feed, \n) LF(Line Feed, \n)
CR(Carriage-Return, \r)  

위의 표처럼, 로컬 개발 환경에서 사용하는 운영체제별로 새줄 문자를 인식하는게 다를 수 있다. 이 문제로 리모트 저장소에 있는 동일한 소스 코드를 각 로컬 환경(Windows, Mac OS, Linux 등)에서 각각 받아와도 새줄 문자 차이로 오류가 발생할 수 있다.

해결방법

git 설정을 해주면 된다.

core.eof는 git이 line ending을 어떻게 처리할건지 설정할 수 있다.

  • core.eol = native, 기본 설정으로 시스템의 line ending을 따른다. 윈도우는 CRLF를 Linux는 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.eol=native


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으로 사용한다.

Windows 설정

$ git config --global core.autocrlf true

Linux/Mac OS 설정

$ git config --global core.autocrlf input

이렇게 설정하게 되되면

image

  • windows => git, push할때 CRLF -> carriage-return을 지워서 LF로 저장한다.
  • windows <= git, pull할때 LF -> carriage-return를 붙여 CRLF로 가져온다.

  • Mac OS => git, push할때 carriage-return을 지워서 LF로 저장한다.
  • Mac OS <= git, pull할때 LF로 가져온다.

엇? 결론은 모든 line ending을 LF로 변경하는 건데 Mac OS는 따로 설정안해줘도 되는거 아니야? 응 아니야.
그 이유는 만약에 맥에서 이메일같은 곳에서 텍스트를 복사 붙여넣기 하게되면 실수로 CR(carriage-return)이 들어갈 수 있으므로 설정해주는 것이 안전하다.

Ref