| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 |
- 코딩테스트
- 항해플러스
- 코딩부트캠프후기
- 백준
- 파이썬
- print("""
- 99클럽 #99일지 #코딩테스트 #개발자스터디 #항해 #til
- print sep
- 파이썬 sep
- Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
- 파이썬 |
- Til
- 항해
- 개발자사이드프로젝트
- vscode cp949
- fatal:not a git repository
- 주니어개발자멘토링
- 항해99
- cp949
- 파이썬 int()
- MomentumParameters
- 10430번
- not a git repository
- 파이썬 map 함수
- 99일지
- 99클럽
- 주니어개발자역량강화
- 파이썬 클래스
- 개발자스터디
- EnvCommandError
- Today
- Total
선발대
[에러] Git에서 modified 무한 반복됨 본문
문제
서버에서 git pull을 하면 이미지, 폰트 파일이 계속 수정됨(modified) 상태로 표시되고, 이 때문에 pull이 충돌로 중단되었다. 대상 파일은 전부 이미지(.png, .gif)와 폰트(.eot, .ttf) 같은 바이너리였다. 하지만 이 파일들을 수정한 적도 없고 화면에서도 정상으로 보이는데 git status 하면 계속 변경된 상태로 인식하고 있었다. git stash, git checkout으로 되돌려도 그 때마다 다시 modified 상태로 살아나는 무한 반복 상태였다. 서버를 최신 상태로 업데이트할 때마다 계속 거슬려서 해결방법을 찾아봤다.
원인
근본 원인은 .gitattributes 첫 줄의 규칙이었다.
* text=auto eol=lf
이 규칙은 모든 파일(*)을 텍스트로 취급하고 줄바꿈을 LF로 강제한다. 예외도 없어서 이미지, 폰트 같은 바이너리까지 텍스트로 취급이 되어버렸다. git check-attr text eol -- public/images/test.png로 확인했을 때 이미지 파일에 text:auto, eol:if가 적용되고 있던 것이 결정적인 증거였다.
문제가 생긴 과정은 이렇다. git은 파일을 저장소에 넣거나 꺼낼 때 이 규칙에 따라 줄바꿈을 변환한다. 바이너리 이미지 안에 바이너리 이미지 안에 우연히 CRLF(0D 0A)처럼 보이는 바이트가 있어서 git이 그걸 줄바꿈으로 오해하고 LF(0A)로 변경해버린 것이다. 이미지 입장에서는 데이터가 손상된 것이다.
화면에서 제대로 보이는 이유도 변환이 이미지를 완전히 깨뜨릴 만큼은 아니어서 그랬다. 하지만 git 입장에서는 바이트가 1개라도 다르면 다른 파일이니 modified로 나온 것이다. 정리해보자면 이렇다.
- 저장소에 커밋된 정본 이미지가 있다.
- pull(또는 checkout)로 이 이미지를 작업 디렉토리에서 꺼낼 때, eol=lf 규칙이 변환을 적용한다.
- 그 결과 작업 디렉토리와 저장소의 정본이 달라진 상태가 된다.
- git이 이 차이를 감지하고 modified를 보여준다.
git에서 파일을 꺼내는 행위 자체가 차이를 만든 것이었다. 그 때마다 변환이 다시 적용되어 가짜 변경이 무한 재생성되었다.
해결 방법
.gitattributes 파일에 바이너리 파일 예외를 추가해서 이 파일들을 텍스트가 아닌 바이너리로 취급하게 만들었다. 이러면 줄바꿈 변환 자체가 일어나지 않는다.
# .gitattributes
# Binary files - do not apply text/eol normalization
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.svg binary
*.eot binary
*.ttf binary
*.woff binary
*.woff2 binary
*.otf binary
*.pdf binary
*.zip binary
# 로컬에서 실행
git add .gitattributes
git add --renormalize .
git status
git commit -m ".gitattributes 바이너리 파일 예외 추가"
git push origin main
# 서버에서 실행
git pull origin main
# 서버에서 검증
# 수정 전: text: auto, eol: lf
# 수정 후: text: unset, eol: unset
git check-attr text eol -- public/images/test.png
