Git crlf
Git CRLF
배경
기존에 Git에 push했던 폴더와 실제 개발하던 폴더를 따로 구분해서 진행하다 보니
파일들이 점점 많아지면서 어떤 파일을 변경했는지 추적하기 어려워졌다.
이를 해결하기 위해 개발 폴더를 기존 레포지토리와 합치는 작업을 진행했고,
그 과정에서 CRLF(줄바꿈 문자) 문제가 발생했다.
이 글은 해당 문제를 해결하는 과정을 정리한 것이다.
문제 원인
왜 CRLF 문제가 생겼나?
- VS Code와 PyCharm 등 에디터마다 기본 줄바꿈 설정이 다르다.
- VS Code는 보통
LF, PyCharm은 Windows 환경에서CRLF로 저장되는 경우가 많다. - 코드 내용(글자)은 완전히 같아도 줄 끝에
\r문자가 있고 없고의 차이로 Git이 파일을 변경된 것으로 인식한다. - 이 때문에
git status에 수정하지도 않은 파일이 전부 올라오고,git diff를 보면 코드는 같은데 줄마다 빨간색/초록색이 가득 찬다.
Git 전역 설정이 문제를 악화시킨다
Git의 기본 전역 설정인 core.autocrlf=true(Windows 기본값)는
.gitattributes에 eol=lf를 설정해도 계속 CRLF로 덮어쓰려고 한다.
이 설정이 충돌을 일으켜 아래와 같은 경고가 뜬다.
1
LF will be replaced by CRLF the next time Git touches it
해결 과정
Step 1. Git clone으로 레포 가져오기
새 폴더를 만들고 기존 repo를 clone한다.
git clone <repo_주소>를 하면 레포 이름으로 폴더가 자동 생성되고,
그 안에 GitHub에 올라가 있던 파일과 커밋 히스토리가 그대로 들어온다.
1
2
git clone <repo_주소>
cd <레포_폴더명>
주의: 기존 폴더를 삭제하고 새 폴더를 붙여넣는 방식은 Git이 모든 파일을 새로 추가된 것으로 인식하기 때문에
반드시 clone으로 히스토리를 살려야 한다.
git clone 후에 git log를 보고 해당 git의 log인지 확인한다.(git remote -v)
Step 2. Git 전역 설정 변경
core.autocrlf를 false로 설정해 충돌 경고를 없앴다.
1
git config --global core.autocrlf false
| 설정 | 의미 |
|---|---|
core.autocrlf true | Windows 기본값. 체크아웃 시 LF→CRLF, 커밋 시 CRLF→LF 자동 변환 |
core.autocrlf false | 변환 없음. .gitattributes 규칙만 따름 |
Step 3. .gitattributes 파일 생성 후 push
줄바꿈을 LF로 통일하는 규칙을 .gitattributes에 추가한다.
1
2
3
4
5
echo "* text=auto eol=lf" > .gitattributes
git add .gitattributes
git commit -m "Add .gitattributes for LF normalization"
git push origin main
Step 4. 개발 폴더 파일 복사
개발하던 폴더(예: develop)에서 레포 폴더 안으로 복사한다.
예를 들어 develop 폴더 안에 chat, config 폴더가 있다면:
1
2
3
4
5
6
7
8
develop/
├── chat/ ← 복사할 폴더
└── config/ ← 복사할 폴더
레포_폴더/
├── .git/ ← 절대 건드리면 안 됨
├── chat/ ← 기존 것 삭제 후 develop의 chat으로 교체
└── config/ ← 기존 것 삭제 후 develop의 config로 교체
.git 폴더만 건드리지 않으면 나머지 폴더는 삭제하고 개발 폴더의 것으로 교체해도 된다.
Git은 .git 폴더 안에 히스토리를 저장하고 있기 때문에 다른 폴더를 교체해도 히스토리는 그대로 유지된다.
Step 5. 기존 파일 줄바꿈 정규화 후 push
기존에 레포에 올라가 있던 파일들의 줄바꿈도 LF로 한 번에 정규화한다.
1
2
3
git add --renormalize .
git commit -m "Normalize line endings to LF"
git push origin main
이 커밋은 코드 로직 변경이 아닌 줄바꿈 문자만 정리하는 커밋이다.
이 한 번만 감수하면 이후부터는 진짜 변경된 파일만
git status에 뜬다.
Step 6. .gitignore 설정 (선택)
특정 폴더를 Git 추적에서 제외하고 싶다면 .gitignore에 추가한다.
예를 들어 어느 경로에 있든 test 폴더를 전부 제외하려면:
1
**/test/
*test/: 이름이 test로 끝나는 폴더만**/test/: 어느 경로에 있든 test 폴더 전부 제외
결과
이렇게 push하고 나면 CRLF 문제가 있던 파일들은 GitHub 커밋 기록에 잡히지 않고
실제로 코드가 변경된 파일들만 커밋 기록에 나타난다.
이후 작업 흐름
앞으로는 매번 새 폴더를 만들 필요 없이 아래 흐름만 반복하면 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 최신 상태로 업데이트
git pull origin main
# 2. develop 폴더에서 작업한 폴더(예: chat, config)를 레포 폴더에 교체
# 3. 변경된 파일 확인
git status
git diff
# 4. 커밋 & push
git add .
git commit -m "기능 X 추가"
git push origin main
핵심 정리
| 문제 | 원인 | 해결 |
|---|---|---|
| 모든 파일이 변경된 것으로 인식 | Git 히스토리 없는 새 폴더에서 작업 | git clone으로 히스토리 살리기 |
| CRLF 경고 및 줄바꿈 충돌 | 에디터별 줄바꿈 설정 차이 | core.autocrlf false + .gitattributes |
| 기존 파일에도 CRLF 남아있음 | 이미 커밋된 파일은 자동 변환 안 됨 | git add --renormalize . |