
Git에서 줄바꿈 경고가 나오면 먼저 작업 파일의 줄바꿈과 인덱스에 저장된 줄바꿈을 따로 확인해야 한다. 경고를 없애려고 전역 설정부터 바꾸면 다른 저장소까지 영향을 받을 수 있다. 팀에서 공유할 규칙은 .gitattributes에 적고, 이미 추적 중인 파일은 변경 내용을 확인한 뒤 정규화한다.
CRLF는 \r\n, LF는 \n이다. 화면에서 같은 두 줄로 보이더라도 파일 바이트는 다를 수 있다. 아래 예제는 실제 프로젝트가 아닌 별도 연습 저장소에서 확인하는 순서다.
먼저 어느 위치의 줄바꿈인지 확인하기
프로젝트 루트에서 다음 명령을 각각 실행한다. 첫 두 명령은 설정이 없으면 출력 없이 종료 코드 1을 반환할 수 있다. 설정이 없다는 사실도 확인 결과다.
git config --show-origin --get core.autocrlf
git config --show-origin --get core.eol
git ls-files --eol
git check-attr text eol -- example.txt
example.txt는 확인할 파일 경로로 바꾼다. git ls-files --eol의 i/는 인덱스, w/는 작업 파일, attr/는 적용된 속성이다. 예를 들어 i/lf w/crlf는 인덱스에는 LF로 저장됐지만 지금 작업 파일에는 CRLF가 있다는 뜻이다. 이 조합만으로 파일이 손상됐다고 판단할 수는 없다.
core.autocrlf=true는 텍스트 파일을 인덱스에 넣을 때 LF로 정규화하고 작업 파일을 만들 때 CRLF를 사용할 수 있게 한다. input은 인덱스 쪽 정규화만 하고 체크아웃 때 CRLF로 변환하지 않는다. false여도 파일에 별도 속성이 설정되어 있으면 그 속성에 따른 변환이 일어날 수 있다.
저장소에서 공유할 규칙 정하기
다음은 .gitattributes 파일 내용이다. 셸에서 실행하는 명령이 아니다. 기존 파일이 있다면 통째로 덮어쓰지 말고 이미 정한 규칙과 합친다.
* text=auto
*.sh text eol=lf
*.py text eol=lf
*.bat text eol=crlf
*.png -text
*.jpg -text
텍스트는 기본적으로 자동 판별하고, 셸·Python 스크립트는 작업 파일도 LF를 쓰도록 지정한다. 배치 파일은 CRLF를 사용하도록 따로 정했다. -text는 해당 파일에 줄바꿈 변환을 하지 않게 한다.
eol이 명시된 파일은 그 규칙을 기준으로 확인한다. 텍스트로 강제 지정한 파일과 Git이 자동으로 텍스트라고 판단한 파일은 적용 조건이 다르므로, 확장자가 특이한 파일이나 바이너리는 실제 속성 결과를 확인하는 편이 좋다.
CRLF 파일이 인덱스에 들어가는 과정 재현하기
아래 블록은 macOS·Linux·Git Bash 등 Bash 환경과 Python 3가 필요하다. 모든 명령을 같은 셸에서 순서대로 실행한다. mktemp로 새 연습 폴더를 만들기 때문에 기존 작업 저장소의 파일은 바꾸지 않는다. 출력된 폴더는 확인이 끝난 뒤 직접 정리하면 된다.
eol_demo_dir=$(mktemp -d)
cd "$eol_demo_dir"
git init -q
git config core.autocrlf false
git config core.safecrlf false
python3 -c 'from pathlib import Path; Path("demo.txt").write_bytes(b"alpha\r\nbeta\r\n")'
git add demo.txt
git ls-files --eol -- demo.txt
python3 -c 'from pathlib import Path; Path(".gitattributes").write_text("*.txt text eol=lf\n", encoding="utf-8")'
git add .gitattributes
git add --renormalize -- demo.txt
git ls-files --eol -- demo.txt
python3 -c 'import subprocess; from pathlib import Path; print(repr(subprocess.check_output(["git", "show", ":demo.txt"]))); print(repr(Path("demo.txt").read_bytes()))'
pwd
처음에는 i/crlf w/crlf, 정규화 후에는 i/lf w/crlf가 나타난다. 마지막 Python 명령의 출력은 다음과 같다.
b'alpha\nbeta\n'
b'alpha\r\nbeta\r\n'
인덱스는 LF로 바뀌었지만 작업 파일의 바이트는 그대로다. git add --renormalize는 인덱스를 갱신하는 작업이므로 편집기에 열린 파일까지 즉시 LF로 바뀐다고 기대하면 안 된다. 편집기에서 LF로 저장한 뒤 git ls-files --eol로 다시 확인할 수 있다.
기존 프로젝트에 적용할 때
먼저 git status --short로 작업 중인 변경을 확인한다. 줄바꿈 정규화와 기능 수정이 섞이면 검토가 어려워진다. 관련 작업을 별도 커밋으로 정리한 뒤 다음 순서로 진행한다.
git status --short
git add .gitattributes
git add --renormalize .
git diff --cached --stat
git diff --cached --check
git diff --cached --ignore-space-at-eol
--renormalize .는 현재 경로 아래 추적 파일을 다시 인덱스에 넣는다. 줄바꿈 외에 이미 수정한 내용이나 삭제된 추적 파일도 함께 스테이징될 수 있어 마지막 diff를 꼭 읽어야 한다. --ignore-space-at-eol은 줄 끝 공백 차이도 숨기므로, 결과가 비어 있다고 모든 변경이 줄바꿈뿐이라고 확정하지 않는다. 일반 git diff --cached도 함께 확인한다.
줄바꿈은 문자 인코딩과도 다른 문제다. 한글이 깨지는 현상은 UTF-8·CP949 등의 인코딩을 별도로 확인해야 한다. 스테이징과 작업 파일의 차이를 구분한 상태에서, 마지막으로 git ls-files --eol의 인덱스·작업 파일·속성이 팀의 규칙과 맞는지 확인하면 된다.
'개발 > 트러블슈팅' 카테고리의 다른 글
| GitHub Actions matrix 한 작업 실패 뒤 나머지도 취소될 때 (1) | 2026.09.18 |
|---|---|
| Git restore와 reset 비교: 수정 파일과 스테이징 되돌리기 (1) | 2026.09.12 |
| gitignore 적용 전 확인할 추적 상태와 예외 규칙 (0) | 2026.09.10 |
| GitHub Actions Docker 빌드가 느릴 때: cache-from·cache-to로 캐시 적용 (1) | 2026.09.08 |
| GitHub Actions에서 AWS 액세스 키 없애기: OIDC 배포 역할 연결 (0) | 2026.09.06 |
댓글