개인 프로젝트와 업무 프로젝트를 한 컴퓨터에서 관리할 때, 저장소마다 설정을 반복하지 않고 상위 폴더를 기준으로 Git 커밋 작성자 정보를 분리하는 방법을 정리했다.
시작하며
한 컴퓨터에서 개인 프로젝트와 업무 프로젝트를 함께 관리하면 Git 커밋에 사용할 이름과 이메일을 구분해야 할 때가 있다.
~/dev/personal/ → 개인 이름과 이메일
~/dev/company/ → 업무용 이름과 이메일
Git의 전역 사용자 정보를 업무 계정으로 바꾸면 개인 저장소에도 같은 정보가 적용된다. 반대로 저장소마다 로컬 설정을 추가하면 저장소를 새로 만들거나 내려받을 때마다 같은 작업을 반복해야 한다.
원하는 동작은 다음과 같았다.
- 기본적으로 개인 사용자 정보를 사용한다.
- 특정 폴더 아래의 저장소에서는 업무용 사용자 정보를 사용한다.
- 해당 폴더에 저장소가 추가돼도 별도 설정 없이 같은 규칙을 적용한다.
- 실제 커밋 전에 어느 설정 파일의 값이 적용되는지 확인할 수 있어야 한다.
이 문제는 Git의 조건부 설정인 includeIf로 해결할 수 있다.
--global과 --local만으로는 무엇이 부족할까
Git 사용자 정보는 흔히 전역 설정으로 등록한다.
git config --global user.name "Personal Name"
git config --global user.email "personal@example.com"
이 값은 별도의 설정이 없는 모든 저장소에서 사용된다. 컴퓨터 전체의 기본값으로는 적합하지만, 폴더에 따라 계정을 구분할 수는 없다.
저장소 하나만 다르게 설정하려면 해당 저장소에서 로컬 설정을 사용할 수 있다.
git config --local user.name "Work Name"
git config --local user.email "work@example.com"
로컬 설정은 .git/config에 저장되고 해당 저장소에만 적용된다. 업무 저장소가 하나라면 충분하지만 저장소가 늘어날수록 같은 설정을 반복해야 한다.
company/
├── api-a/ → 로컬 설정 필요
├── api-b/ → 로컬 설정 필요
└── batch-job/ → 로컬 설정 필요
새 저장소에서 설정을 빠뜨리면 기본 계정으로 커밋할 수도 있다. 저장소 단위가 아니라 상위 폴더를 하나의 설정 범위로 묶는 방법이 필요했다.
Git 설정의 적용 범위
Git 설정은 대표적으로 다음 범위에서 읽힌다.
| 범위 | 대표 파일 | 적용 대상 |
|---|---|---|
| System | /etc/gitconfig |
시스템의 모든 사용자와 저장소 |
| Global | ~/.gitconfig |
현재 사용자의 모든 저장소 |
| Local | .git/config |
현재 저장소 |
일반적으로 더 구체적인 범위의 값이 우선한다.
System < Global < Local
includeIf는 조건이 맞을 때 다른 설정 파일을 현재 설정에 포함한다. gitdir 조건을 사용하면 현재 저장소의 .git 디렉터리 경로를 기준으로 포함 여부를 결정할 수 있다.
따라서 전역 설정 안에 다음 규칙을 둘 수 있다.
현재 저장소가 ~/dev/company/ 아래에 있다면
→ 업무용 Git 설정 파일을 추가로 읽는다.
업무용 사용자 설정을 별도 파일로 분리하기
먼저 업무용 사용자 정보만 담을 설정 파일을 만든다.
git config --file ~/.gitconfig-company user.name "Work Name"
git config --file ~/.gitconfig-company user.email "work@example.com"
생성된 ~/.gitconfig-company의 내용은 다음과 같다.
[user]
name = Work Name
email = work@example.com
개인 기본값과 업무용 값을 파일로 나누면 각 설정의 역할이 명확해진다.
~/.gitconfig → 기본 설정과 개인 사용자 정보
~/.gitconfig-company → 업무용 사용자 정보
업무용 서명 키나 커밋 서명 옵션처럼 계정과 함께 바뀌어야 하는 설정이 생기면 같은 파일에 추가할 수도 있다. 다만 처음에는 user.name과 user.email처럼 실제로 분리해야 하는 값만 두는 편이 관리하기 쉽다.
특정 폴더에서만 설정 파일 불러오기
이제 전역 설정에 조건부 포함 규칙을 등록한다.
git config --global \
'includeIf.gitdir:~/dev/company/.path' \
~/.gitconfig-company
명령을 실행하면 ~/.gitconfig에 다음 설정이 추가된다.
[user]
name = Personal Name
email = personal@example.com
[includeIf "gitdir:~/dev/company/"]
path = ~/.gitconfig-company
이후 ~/dev/company/ 아래에 있는 Git 저장소에서는 ~/.gitconfig-company의 사용자 정보를 읽는다.
~/dev/
├── personal/
│ └── side-project/ → Personal Name <personal@example.com>
└── company/
├── api/ → Work Name <work@example.com>
└── batch/ → Work Name <work@example.com>
저장소마다 .git/config를 수정하지 않아도 상위 폴더에 포함되는 새 저장소까지 같은 규칙을 적용받는다.
실제로 적용하면서 확인한 순서
내 경우에는 하나의 업무 폴더 아래에 API, 데이터 처리 도구 등 여러 Git 저장소가 이미 있었다. 저장소마다 로컬 설정을 추가하는 대신 전역 개인 설정은 그대로 두고, 업무용 설정 파일과 includeIf 규칙만 추가했다.
설정을 넣은 뒤에는 다음 순서로 범위를 확인했다.
| 확인 단계 | 확인한 내용 | 통과 기준 |
|---|---|---|
| 1. 업무 저장소 A | user.name, user.email의 값과 출처 |
업무용 별도 설정 파일이 표시됨 |
| 2. 같은 폴더의 업무 저장소 B | 새 저장소에도 동일한 규칙이 적용되는지 | 별도 로컬 설정 없이 같은 파일이 표시됨 |
| 3. 업무 폴더 밖의 저장소 | 개인 기본값이 유지되는지 | 기본 전역 설정 파일이 표시됨 |
| 4. 실제 커밋 | Author와 Committer | 둘 다 의도한 업무용 정보로 기록됨 |
여기서 실제 커밋은 원격 저장소에 올리지 않고 로컬에서만 만들었다. 사용자 정보는 커밋 객체를 생성하는 순간 기록되므로, 적용 여부를 확인하기 위해 Push까지 할 필요는 없다.
처음에는 git config user.email의 출력만 맞으면 끝이라고 생각하기 쉽다. 하지만 특정 저장소의 로컬 설정이 우선하거나 Author와 Committer를 별도로 지정한 환경 변수가 있으면 예상과 다른 기록이 남을 수 있다. 그래서 설정값 확인과 실제 커밋 확인을 별개의 단계로 두었다.
경로 끝의 /가 중요한 이유
조건의 경로는 다음처럼 /로 끝내는 것이 중요하다.
[includeIf "gitdir:~/dev/company/"]
Git은 gitdir 패턴이 /로 끝나면 뒤에 **를 붙인 것처럼 처리한다. 따라서 위 조건은 해당 디렉터리와 그 아래에 있는 저장소를 재귀적으로 포함한다.
개념적으로 다음과 같은 의미다.
gitdir:~/dev/company/
→ gitdir:~/dev/company/**
절대 경로를 사용해도 된다.
[includeIf "gitdir:/Users/example/dev/company/"]
path = ~/.gitconfig-company
경로의 대소문자를 구분하지 않고 비교해야 한다면 gitdir/i 조건도 사용할 수 있다.
[includeIf "gitdir/i:~/dev/company/"]
path = ~/.gitconfig-company
운영체제와 실제 디렉터리 표기를 일관되게 관리할 수 있다면 기본 gitdir를 사용하는 것으로 충분하다.
실제 적용된 값과 출처 확인하기
설정을 추가한 뒤에는 업무 저장소 안에서 적용 결과를 확인한다.
git config --show-origin --get user.name
git config --show-origin --get user.email
정상적으로 적용됐다면 값뿐 아니라 값을 읽은 설정 파일도 함께 표시된다.
file:/Users/example/.gitconfig-company Work Name
file:/Users/example/.gitconfig-company work@example.com
개인 저장소에서도 같은 명령을 실행해 기본 설정이 유지되는지 확인한다.
file:/Users/example/.gitconfig Personal Name
file:/Users/example/.gitconfig personal@example.com
저장소 경로를 직접 지정해서 확인할 수도 있다.
git -C ~/dev/company/api config --show-origin --get user.name
git -C ~/dev/company/api config --show-origin --get user.email
git -C를 사용하면 현재 디렉터리를 이동하지 않고도 지정한 저장소를 기준으로 Git 명령을 실행할 수 있다.
저장소의 로컬 설정이 남아 있다면
조건부 설정이 예상대로 보이지 않는다면 먼저 로컬 설정을 확인해야 한다.
git config --local --get user.name
git config --local --get user.email
로컬 설정은 조건부로 포함한 전역 설정보다 구체적인 저장소 범위에 있으므로 우선 적용된다.
기존 로컬 사용자 정보가 더 이상 필요하지 않다면 해당 저장소에서 제거한다.
git config --local --unset user.name
git config --local --unset user.email
삭제한 뒤 다시 출처를 확인한다.
git config --show-origin --get user.name
git config --show-origin --get user.email
반대로 특정 저장소만 폴더 규칙과 다른 계정을 써야 한다면 로컬 설정을 유지하면 된다. 상위 폴더에는 공통 규칙을 적용하고 예외 저장소만 로컬 설정으로 덮어쓰는 구조다.
Global 기본값
↓
폴더별 includeIf 설정
↓
저장소별 Local 예외 설정
커밋에 기록된 작성자까지 확인하기
설정 조회 결과가 맞다면 작은 변경을 커밋한 뒤 실제 기록도 확인한다.
git show -s \
--format='Author: %an <%ae>%nCommitter: %cn <%ce>' \
HEAD
출력은 다음과 같은 형태다.
Author: Work Name <work@example.com>
Committer: Work Name <work@example.com>
user.name은 Git 호스팅 서비스의 로그인 아이디가 아니라 커밋 객체에 기록되는 이름이다. user.email도 커밋에 함께 기록된다. 설정을 바꿔도 이미 만들어진 과거 커밋의 작성자 정보는 자동으로 변경되지 않으며, 변경 이후 생성한 커밋부터 새 값이 사용된다.
따라서 설정을 처음 적용할 때는 git config의 결과만 보지 말고 테스트 커밋의 Author와 Committer까지 확인하는 편이 안전하다.
커밋 작성자와 원격 저장소 인증은 별개다
user.name과 user.email을 업무용으로 바꿨다고 해서 Push할 때 사용하는 계정까지 자동으로 바뀌는 것은 아니다. 이번 설정이 바꾸는 것은 커밋에 기록되는 작성자 정보다.
| 구분 | 관련 설정 또는 수단 | 하는 일 |
|---|---|---|
| 커밋 작성자 | user.name, user.email |
커밋 객체의 Author와 Committer 기본값 결정 |
| 원격 저장소 인증 | SSH Key, Credential Helper, Access Token | Clone, Fetch, Push 권한 확인 |
| 커밋 서명 | user.signingKey, commit.gpgSign |
커밋이 해당 키로 서명됐는지 검증 |
따라서 다음 상황은 모순이 아니다.
커밋 Author → 업무용 이름과 이메일
Push 인증 → 개인 SSH Key
이 경우 커밋 기록은 업무용으로 남더라도 Push는 개인 계정의 권한으로 시도된다. 계정별로 원격 인증까지 분리하려면 SSH Host alias나 저장소별 remote URL, Credential Helper 설정을 별도로 구성해야 한다.
이 구분을 모르고 includeIf만 설정하면 커밋 작성자는 바뀌었는데 Push 계정은 그대로인 상황을 설정 실패로 오해할 수 있다. 반대로 Push에 성공했다고 해서 커밋 작성자 정보까지 올바르다는 뜻도 아니다.
적용되지 않을 때 확인할 순서
문제가 생겼을 때는 값을 다시 덮어쓰기보다 어떤 설정 파일이 선택됐는지부터 확인하는 편이 빠르다.
| 증상 | 먼저 확인할 것 | 자주 발생하는 원인 |
|---|---|---|
| 업무 폴더에서 개인 정보가 표시됨 | --show-origin 결과 |
gitdir 경로 불일치 또는 경로 끝 / 누락 |
| 특정 저장소만 다른 정보가 표시됨 | --local --get-regexp '^user\.' |
.git/config의 로컬 설정이 우선함 |
| 터미널마다 결과가 다름 | 전역 설정 파일 경로와 HOME |
실행 환경이 서로 다른 사용자 설정을 읽음 |
| 커밋 작성자는 맞지만 Push 계정이 다름 | SSH Key 또는 Credential Helper | 작성자 설정과 인증 설정을 같은 것으로 오해함 |
| 과거 커밋이 그대로임 | 커밋 생성 시점 | 설정 변경은 새 커밋부터 적용됨 |
현재 저장소에 적용된 사용자 설정 전체와 범위를 한 번에 보려면 다음 명령도 유용하다.
git config --show-origin --show-scope --get-regexp '^user\.'
출력된 값만 보지 말고 global, local 범위와 설정 파일 경로를 함께 보면 어떤 값이 마지막에 적용됐는지 추적하기 쉽다.
폴더별 사용자 설정 점검표
- 기본 전역 사용자 정보는 그대로 유지했는가
- 업무용 사용자 정보를 별도 설정 파일로 분리했는가
-
includeIf.gitdir가 실제 업무 저장소의 상위 경로와 일치하는가 - 하위 저장소까지 포함하도록 조건 경로를
/로 끝냈는가 - 서로 다른 두 업무 저장소에서 같은 설정 파일이 표시되는가
- 업무 폴더 밖의 저장소에는 개인 기본값이 유지되는가
- 저장소 로컬 설정이 의도하지 않게 값을 덮어쓰지 않는가
- 실제 커밋의 Author와 Committer를 모두 확인했는가
- Push 인증 계정은 SSH 또는 Credential 설정에서 별도로 확인했는가
마치며
저장소가 하나라면 --local 설정으로 충분하다. 하지만 개인 프로젝트와 업무 프로젝트처럼 폴더 자체가 명확한 경계라면 includeIf가 반복 설정과 계정 혼용을 함께 줄여 준다.
이번 설정의 핵심은 세 단계다.
- 용도별 사용자 정보를 별도 Git 설정 파일로 분리한다.
- 전역 설정에서
includeIf와gitdir로 적용할 폴더를 지정한다. --show-origin과 실제 커밋 정보로 적용 결과를 검증한다.
설정 범위를 폴더 구조와 일치시키면 새 저장소를 추가해도 별도의 기억이나 수작업에 의존하지 않아도 된다. 기본값, 폴더별 규칙, 저장소별 예외라는 세 단계로 나누면 여러 계정을 한 컴퓨터에서 관리할 때도 어떤 값이 적용되는지 설명하기 쉬워진다.
공식 문서에서는 includeIf와 gitdir 조건, Git 설정 범위와 우선순위를 더 자세히 확인할 수 있다.