Git의 매직 파일들
(nesbitt.io)- Git은 저장소 내 특정 파일들을 통해 동작 방식을 제어하며, 이들은
.git/내부 설정이 아닌 커밋되어 코드와 함께 이동하는 파일임 -
.gitignore,.gitattributes,.lfsconfig,.gitmodules,.mailmap등은 각각 파일 추적 제외, 속성 정의, LFS 설정, 서브모듈 관리, 작성자 통합을 담당 -
.git-blame-ignore-revs와.gitmessage는 코드 포맷팅 커밋 무시 및 커밋 메시지 템플릿을 제공해 협업 품질을 높임 - GitHub, GitLab, Gitea 등은
.github/,.gitlab/,.gitea/같은 포지별 설정 폴더를 통해 CI/CD, 리뷰어 지정 등 기능을 확장함 - 이러한 구조는 Git을 넘어 EditorConfig, Docker, 언어 버전 관리 도구 등에서도 동일하게 적용되어, 도트파일 기반 자동 설정 생태계를 형성함
Git의 주요 매직 파일
- Git은
.gitignore,.gitattributes,.lfsconfig,.gitmodules,.mailmap등 여러 특수 파일을 인식해 저장소 동작을 제어함- 이 파일들은
.git/내부 설정이 아닌 커밋되어 공유되는 구성 요소로, 협업 시 일관된 동작을 보장함
- 이 파일들은
.gitignore
- Git이 추적하지 않아야 할 파일 패턴을 정의
- 와일드카드(
*.log), 디렉터리(dist/), 부정(!important.log) 등을 지원 -
.gitignore,.git/info/exclude, 전역 설정(~/.config/git/ignore) 순으로 적용
- 와일드카드(
- 이미 추적된 파일은
.gitignore추가 후에도 계속 추적되며,git rm --cached로 제거 가능 - GitHub, GitLab, Gitea 등은 무시된 패턴의 파일도 경고 없이 커밋 가능
- GitHub는 언어별
.gitignore템플릿을 공식 저장소에서 제공
.gitattributes
- 파일별 필터, diff, merge, 줄바꿈, 언어 감지 등을 제어
- 예:
*.psd filter=lfs,*.png binary,*.sh text eol=lf
- 예:
-
text는 줄바꿈 정규화,binary는 diff/merge 비활성화,merge=ours는 충돌 시 로컬 버전 유지 - GitHub Linguist는
.gitattributes를 읽어 언어 통계 제외, 생성 코드 접기, 문서 제외 등을 수행 - 각 디렉터리별
.gitattributes와.git/info/attributes를 함께 인식
.lfsconfig
-
Git LFS 설정을 저장소와 함께 공유
- LFS 서버 URL, 전송 재시도 횟수 등 설정 가능
- 예:
[lfs] url = https://lfs.example.com/repo [lfs "transfer"] maxretries = 3
-
.gitattributes에서 LFS 처리 파일을 지정하고,.lfsconfig는 서버 위치 등 세부 설정을 담당 - 기존 커밋 파일을 LFS로 이동하려면
git lfs migrate명령 필요
.gitmodules
-
서브모듈 구성 정보를 저장
- 각 모듈의 경로, URL, 브랜치 정보를 포함
- 예:
[submodule "vendor/lib"] path = vendor/lib url = https://github.com/example/lib.git branch = main
-
git submodule add시 생성,git submodule update시 참조 -
git clone시 자동으로 서브모듈을 가져오지 않으며,--recurse-submodules옵션 필요 - 버전 범위 추적 불가, 중첩
.git디렉터리 생성 등 단점 존재
.mailmap
-
작성자 이름과 이메일을 통합 관리
- 예:
Jane Developer <[email protected]> <[email protected]>
- 예:
-
git log,git shortlog,git blame등에서 통합된 이름으로 표시 - GitHub의 기여자 그래프는 mailmap을 반영하지 않음
-
.mailmap또는mailmap.file설정으로 위치 지정 가능
.git-blame-ignore-revs
-
git blame에서 무시할 커밋 목록을 지정- 포맷터 실행, 린트 적용 등 의미 없는 변경을 제외
- 예:
# Ran prettier on entire codebase a1b2c3d4e5f6g7h8i9j0...
-
git config blame.ignoreRevsFile .git-blame-ignore-revs로 활성화 - GitHub, GitLab(15.4+), Gitea는 자동 인식
- 파일이 없을 경우 오류 발생 가능하므로 빈 파일 유지 권장
.gitmessage
-
커밋 메시지 템플릿을 정의
- 예:
# <type>: <subject> # # Types: feat, fix, docs, style, refactor, test, chore
- 예:
-
git config commit.template .gitmessage로 설정 필요 - 클론 후 수동 설정이 필요하며, 일부 팀은 husky 등으로 자동화
- 대안으로
commit-msg훅이나prepare-commit-msg훅 사용 가능
포지별 확장 폴더
- GitHub, GitLab, Gitea, Forgejo, Bitbucket 등은 자체 설정 폴더를 사용
-
.github/,.gitlab/,.gitea/,.forgejo/,.bitbucket/
-
- CI/CD 워크플로, 이슈·PR 템플릿, CODEOWNERS 파일 등을 포함
- Forgejo는
.forgejo/ → .gitea/ → .github/, Gitea는.gitea/ → .github/순으로 폴백 - SourceHut은
.build.yml또는.builds/*.yml을 사용
기타 관례적 파일
- .gitkeep: Git이 빈 디렉터리를 추적하지 않기 때문에, 디렉터리 유지용 더미 파일로 사용
- .gitconfig: 프로젝트별 Git 설정 예시를 제공하지만 자동 로드되지 않음
-
.gitsigners: GPG/SSH 서명 키 목록을 관리,
gpg.ssh.allowedSignersFile로 지정 가능 -
.gitreview: Gerrit 코드 리뷰 서버 설정 파일
- 예:
[gerrit] host=review.opendev.org port=29418 project=openstack/nova.git defaultbranch=master
- 예:
-
.gitlint: 커밋 메시지 린팅 규칙 정의
- 예:
[general] ignore=body-is-missing [title-max-length] line-length=72
- 예:
-
.jj/: Git 호환 VCS인 Jujutsu의 상태 디렉터리,
.git/과 함께 존재 가능
Git을 넘어선 도트파일 생태계
-
.editorconfig: 에디터 간 일관된 코드 스타일 유지
- 들여쓰기, 줄바꿈, 인코딩, 공백 제거 등을 정의
- VS Code, Vim, Emacs 등 주요 에디터가 지원
- .ruby-version, .node-version, .python-version: 언어 버전 관리 도구(rbenv, nodenv, pyenv 등)가 읽어 자동 전환
- .tool-versions: asdf의 다언어 버전 관리 파일
-
.dockerignore: Docker 빌드 시 제외할 파일 목록 지정
-
.gitignore와 동일한 패턴 문법 사용, 빌드 속도 향상 및 비밀정보 제외
-
Git 연동 도구 개발 시 고려사항
- Git 저장소를 다루는 도구는 다음 파일들을 반드시 인식해야 함
-
.gitignore: 파일 탐색 시 무시 패턴 적용 -
.gitattributes: 바이너리·생성 파일 구분 -
.mailmap: 작성자 정보 통합 표시 -
.gitmodules: 서브모듈 처리
-
- Git 설정 파일 형식은
[section "subsection"] key = value구조이며,git config명령으로 읽기·쓰기 가능 - 대부분의 언어용 Git 라이브러리는 이 형식을 파싱하는 기능을 제공
Hacker News 의견들
- GitHub, GitLab, Gitea 모두
.gitignore를 존중해서 웹 UI에 무시된 파일을 안 보여준다고 했는데, 그건 잘못된 설명 같음
실제로는 무시된 파일이 저장소에 포함되지 않기 때문에 안 보이는 것임. 이미 커밋된 파일이라면, 오히려 보여야 하는 게 맞다고 생각함- 그렇지 않음. 이미 푸시된 파일을 나중에
.gitignore에 추가해도 여전히 UI에 보임. 그 파일은 여전히 repo의 일부이기 때문임
반대로, 처음부터 무시된 파일을 강제로 커밋하는 것도 가능하지만 약간의 트릭이 필요함 - 맞음, 원 댓글이 틀림.
.gitignore는 단지 untracked 파일을 숨길지 여부만 결정함. 원하면 무시된 파일도 커밋할 수 있음 -
showinwebui=(true|false)같은 옵션이 있으면 좋겠다는 생각이 듦 😄 - 이런 실수를 사람이 직접 썼을 리 없다고 느껴서, 그 부분에서 읽기를 멈췄음
- 그렇지 않음. 이미 푸시된 파일을 나중에
-
.git/info/exclude를 강조하고 싶음. 이건 로컬 전용 gitignore로, 나만을 위한 설정임
예를 들어 버그 조사 중에 임시 파일을 만들어 브랜치를 바꿔도 그대로 두고 싶을 때 유용함
나는 아래처럼 셸 alias를 만들어 씀
이렇게 하면git-ignore-local () { echo "$1" >> .git/info/exclude }git-ignore-local myfile.ext로 간단히 추가 가능함- 루트 디렉터리에 있지 않아도 작동하도록 조금 더 마법 같은 버전을 만들어봤음
MacOS에서는readlink부분만 수정하면 됨
이 함수를 PATH에git-ignore-local () { root=$(git rev-parse --show-toplevel) path=$(readlink -f "$1") relpath=$(relpath -m --relative-to="$root" "$path") echo "$relpath" >> "${root}.git/info/exclude" }git-ignore-local로 등록하면git ignore-local처럼 쓸 수 있음 -
.git/info/exclude는.gitignore설명의 첫 부분에서도 언급되어 있음 - 이런 기능은 처음 알았음. 내 프로젝트에서 이런 작은 임시 파일들 때문에 PR이 복잡해졌는데, 이걸로 해결될 것 같음
- 루트 디렉터리에 있지 않아도 작동하도록 조금 더 마법 같은 버전을 만들어봤음
-
.gitattributes에/test export-ignore를 추가하면, 프로덕션 서버로 배포 시 테스트 파일을 제외할 수 있음
Capistrano 같은 배포 도구가git export를 사용할 때 자동으로 적용되어, 테스트 파일이 서버에 올라가지 않음
개발 중에는 영향을 주지 않으면서 디스크 공간도 절약됨- 좋은 기능이지만 대부분의 사람들은
git archive자체를 잘 모르는 듯함
기본적인 CI 도구들에서도 거의 안 쓰이는 걸 봤음. Capistrano가 이걸 활용하는 첫 사례로 알게 됨
참고로export-subst옵션을 쓰면git describe와 비슷한 정보를 파일 안에 직접 넣을 수도 있음
- 좋은 기능이지만 대부분의 사람들은
-
jj를 쓰면서.jj폴더를 repo와 모든 git 작업에서 완전히 제외하고 싶었음
git clean -xdf에서도 지워지지 않게 말임. 지금은 임시로git clean -e .jjalias로 해결 중임-
.git/info/exclude를 쓰면 됨
-
- GitHub의 contributor graph는
.mailmap을 지원하지 않음
관련 논의는 GitHub Community Discussion에 있음 -
package-lock.json merge=ours설정은 위험하다고 생각함
merge나 rebase 시 ours/theirs의 의미가 불분명하기 때문임
이런 설정은 자동화된 병합 도구(예: git-annex branch)에서만 의미가 있음
참고: ours/theirs 의미 설명, git-annex 내부 구조 -
.git-blame-ignore-revs는 좋은 기능이지만, “기타 관례” 섹션에 속해야 함
git 클라이언트에 설정하지 않으면, 해당 파일이 없는 저장소에서는 git blame이 실패함- git 2.52부터는
(:optional)옵션을 써서 파일이 없어도 오류가 나지 않게 할 수 있음
관련 설명은 Stack Overflow 답변에 있음
- git 2.52부터는
- 전체적으로 잘 정리된 리스트라고 생각함
다만 모든 도구가.mailmap을 지원하지 않는 점이 아쉬움. 예를 들어 IntelliJ는 아직 관련 기능이 버그/기능 요청 상태임
또한.git-blame-ignore-revs는 단순한 관례일 뿐, 직접 설정을 해야 작동함 - 약간 다른 이야기지만, VS Code가
.ignore파일도 인식한다는 걸 최근에 알게 됨
.gitignore만 적용되는 줄 알았는데,.ignore에서 ripgrep 설정을 바꿨더니 검색 결과가 달라졌음. 알고 보니 합리적인 동작이었음 - 글 작성자가 forge-specific repository folders(일종의 “매직 폴더”)에 대한 후속 글도 올렸음
링크: nesbitt.io 글