코드리뷰 시 왜 GitHub이 파일 끝에 엔터를 치도록 요구하는지 궁금했습니다. 이참에 Git을 쓰며 개행문자 문제를 해결하는 방안이 떠올라 함께 썼습니다. 왜냐하면 엔터는 개행문자를 텍스트파일에 쓰는 것이니까요(?)
필요한 부분들을 살펴보기 위해, 논의에 연관이 없다고 판단되는 부분은 생략하려 합니다.
먼저, 코드가 쓰여지는 텍스트 파일의 정의를 먼저 살펴봅시다.
A file that contains characters organized into zero or more lines. (중략)
모든 텍스트 파일에서 줄(Line)은 개행문자(newline)를 기준으로 만들어 집니다.
A sequence of zero or more non-
characters plus a terminating character. (중략)
끝나지 않은 줄(Incomplete Line)은 파일 끝에 non-newline 문자가 하나 이상 있는 것을 의미합니다
A sequence of one or more non-
characters at the end of the file. (중략)
다시말해, 파일 끝에 newline 문자가 없으면 끝나지 않은 행으로 한다는 것입니다.
Git을 사용할 때, 윈도우즈에서 수정한 코드를 가져오면 ^M
문자열이 온 코드 끝에 다 붙어있는 경우를 간혹 보게됩니다. 이는 개행문자의 차이로 인해 발생하는 문제입니다.
윈도우즈는 CRLF 방식의 개행을, GNU/Linux나 macOS에서는 LF를 개행으로 사용합니다. 엔터키를 눌렀을 때, 파일에 새 줄을 어떻게 기록할 것인지를 구별하는 바이너리 값이 다르게 붙음을 의미합니다.
Git에서는 이를 방지할 수 있도록 설정을 부여해줄 수 있습니다. 여러 방법이 있습니다만 이 글에서 소개할 방법은 리포지토리에 .gitattributes
파일을 추가하는 방안입니다.
git config --global core.autocrlf [true|false|input]
명령을 통해 개인 PC에 설정을 넣어두는 것으로 해결할 수 있습니다. 하지만 저는 프로젝트 전체에.gitattributes
파일 추가를 통해 모든 사람과 논의하는 것이 좋다고 생각합니다. 이유는 아래와 같습니다:첫째, 모든 이에게 이런 문제가 일어날 수 있음을 제고할 수 있습니다.
둘째, 해결책을 제시하고 보다 나은 사항을 알아볼 수 있게끔 방향을 잡을 수 있습니다.
.gitattributes
이 파일은 프로젝트에 Git 설정을 동일하게 하여 혼동을 없앨 때 사용합니다. 그 중, EOL 과 관련한 옵션을 살펴봅시다.
text=auto
옵션이 설정은 EOL normalization에 대한 설정입니다. text=auto
을 주면 모든 텍스트 파일의 EOL이 LF로 normalize됩니다. 하지만 현재 워킹 트리의 텍스트 파일은 CRLF 그대로입니다. 바이너리(이미지, 폰트 등)들의 EOF는 변경되지 않습니다(참조링크를 확인해보세요).
아래 설정은 이 리포지토리에서 가져왔습니다(이런 게 있군요!).
# THIS IS ONLY FOR THE gitattributes REPOSITORY.
# Handle line endings automatically for files detected as text
# and leave all files detected as binary untouched.
* text=auto
git add --renormalize . # normalize 수행
git status # 변경된 상태확인
git ls-files --eol # 파일의 EOL을 살펴봅시다.
git ls-files path/to/file --eol # 특정 파일의 EOL을 살펴봅시다.
git 버전이 그보다 아래라면, find
와 sed
를 적절히 이용하거나, dos2unix
같은 바이너리를 이용하여 수동으로 개행 바이너리값을 바꾸어 커밋하면 되겠죠.
파일에 EOL을 균일하게 넣고, 모든 구성원들에게 동일한 설정을 부여하는 것으로 일어나는 문제를 해결할 수 있었습니다.