Git 기초
Git은 분산 버전 관리 시스템(DVCS)입니다. 코드의 변경 이력을 추적하고, 여러 사람이 동시에 작업하고, 언제든 이전 상태로 되돌릴 수 있게 해줍니다. AI/ML 분야에서 Git은 단순한 코드 관리 도구를 넘어 실험 재현성의 기반이 됩니다. 어떤 코드로, 어떤 설정으로, 어떤 결과를 얻었는지 — 이 모든 것을 Git 이력으로 추적할 수 있습니다.학습 목표
- Git의 내부 모델(스냅샷, 3가지 영역, HEAD)을 이해하고 설명할 수 있다
- 브랜치를 생성하고, 커밋하고, 원격 저장소에 푸시하며, PR을 통해 협업할 수 있다
- Conventional Commits 규칙에 따른 의미 있는 커밋 메시지를 작성할 수 있다
- ML 프로젝트에 적합한
.gitignore를 구성하고, 실험 브랜치를 관리할 수 있다
왜 중요한가
ML 프로젝트에서 가장 흔한 문제 중 하나는 “지난 주에 좋았던 결과를 재현할 수 없다”는 것입니다. 하이퍼파라미터를 바꾸고, 데이터 전처리를 수정하고, 모델 구조를 변경하면서 — 어떤 조합이 최고 성능을 냈는지 추적할 수 없게 됩니다. Git으로 코드를 관리하면, 모든 변경 사항이 기록되어 특정 시점의 코드 상태를 정확히 복원할 수 있습니다. 팀 협업에서도 Git은 필수입니다. 여러 사람이 같은 코드베이스에서 동시에 작업할 때, 브랜치와 머지를 통해 충돌 없이 협업할 수 있습니다. 코드 리뷰(PR)를 통해 품질을 유지하고, 문제가 생기면 즉시 이전 버전으로 되돌릴 수 있습니다.Git 내부 모델
스냅샷 기반 (vs diff 기반)
Git은 파일의 변경분(diff) 이 아니라 스냅샷(snapshot) 을 저장합니다. 커밋할 때마다 프로젝트 전체의 스냅샷을 찍고, 변경되지 않은 파일은 이전 스냅샷에 대한 참조만 저장합니다.3가지 영역
Git은 파일의 상태를 3가지 영역으로 관리합니다. 이 개념을 이해해야add, commit, checkout 등의 명령어가 직관적으로 와닿습니다.
| 영역 | 설명 | 파일 상태 |
|---|---|---|
| Working Directory | 실제 파일이 있는 디렉터리 | Modified (수정됨), Untracked (미추적) |
| Staging Area | 다음 커밋에 포함될 변경사항 | Staged (스테이지됨) |
| Repository | 커밋된 이력이 저장되는 .git 디렉터리 | Committed (커밋됨) |
HEAD와 브랜치 포인터
- HEAD: 현재 작업 중인 커밋을 가리키는 포인터. 보통 브랜치를 통해 간접 참조
- 브랜치: 특정 커밋을 가리키는 이동 가능한 포인터. 새 커밋이 생기면 자동으로 이동
- 태그: 특정 커밋을 가리키는 고정된 포인터. 릴리스 버전 등에 사용
초기 설정
워크플로우
브랜치 전략
| 전략 | 브랜치 구조 | 적합한 팀 | 특징 |
|---|---|---|---|
| Simple | main + feature/* | 1-3인 소규모 | 간단하고 빠름, ML 실험에 적합 |
| GitHub Flow | main + feature/* + PR | 3-10인 | PR 기반 리뷰, CI/CD 연동 용이 |
| Git Flow | main + develop + feature/* + release/* + hotfix/* | 10인+ 대규모 | 체계적이나 복잡, 릴리스 주기가 명확한 제품 |
| Trunk-Based | main + 매우 짧은 feature/* | 숙련된 팀 | 짧은 브랜치 수명, 빈번한 머지, CI 필수 |
커밋 품질
Conventional Commits
커밋 메시지에 일관된 형식을 부여하여, 변경 이력을 쉽게 파악할 수 있습니다.| 타입 | 설명 | 예시 |
|---|---|---|
feat | 새 기능 | feat: add learning rate scheduler |
fix | 버그 수정 | fix: resolve OOM in DataLoader with large batch |
docs | 문서 변경 | docs: update training README with GPU setup |
refactor | 리팩터링 (기능 변경 없음) | refactor: extract data augmentation to separate module |
test | 테스트 추가/수정 | test: add unit tests for tokenizer |
chore | 빌드, 설정 등 유지보수 | chore: update PyTorch to 2.1.0 |
perf | 성능 개선 | perf: optimize batch collation with vectorized ops |
style | 코드 스타일 (동작 변경 없음) | style: apply black formatter to src/ |
ci | CI/CD 설정 변경 | ci: add GPU test pipeline to GitHub Actions |
원자적 커밋 원칙
하나의 커밋은 하나의 논리적 변경만 포함해야 합니다..gitignore
Python + ML 프로젝트 .gitignore
.gitignore에 추가하기 전에 이미 Git에 추적 중인 파일은 무시되지 않습니다. 이미 추적 중인 파일을 무시하려면 git rm --cached <파일>로 추적을 해제한 후 .gitignore에 추가하세요.Git 명령어 테이블
기본 명령어
| 명령어 | 설명 | 사용 예시 |
|---|---|---|
git init | 새 저장소 초기화 | git init |
git clone | 원격 저장소 복제 | git clone git@github.com:user/repo.git |
git status | 작업 상태 확인 | git status |
git add | 스테이징 | git add file.py |
git commit | 커밋 | git commit -m "feat: add feature" |
git log | 커밋 이력 조회 | git log --oneline --graph --all |
git diff | 변경 내용 비교 | git diff, git diff --staged |
git show | 커밋 상세 확인 | git show HEAD, git show abc1234 |
브랜치 명령어
| 명령어 | 설명 | 사용 예시 |
|---|---|---|
git branch | 브랜치 목록/생성 | git branch, git branch feature/x |
git checkout | 브랜치 전환 | git checkout main |
git switch | 브랜치 전환 (Git 2.23+) | git switch main |
git merge | 브랜치 머지 | git merge feature/x |
git rebase | 커밋 이력 재배치 | git rebase main |
git branch -d | 브랜치 삭제 | git branch -d feature/x |
원격 명령어
| 명령어 | 설명 | 사용 예시 |
|---|---|---|
git remote | 원격 저장소 관리 | git remote -v |
git fetch | 원격 변경사항 가져오기 (머지 안 함) | git fetch origin |
git pull | fetch + merge | git pull origin main |
git push | 로컬 커밋을 원격에 업로드 | git push origin feature/x |
git push -u | 업스트림 설정 + 푸시 | git push -u origin feature/x |
되돌리기 명령어
| 명령어 | 설명 | 영향 범위 | 안전성 |
|---|---|---|---|
git restore | Working Directory 파일 복원 | 작업 디렉터리 | 되돌릴 수 없음 |
git restore --staged | 스테이징 취소 | 스테이징 영역 | 안전 |
git reset --soft HEAD~1 | 마지막 커밋 취소 (변경사항 유지) | 커밋만 | 안전 |
git reset --mixed HEAD~1 | 마지막 커밋 + 스테이징 취소 | 커밋 + 스테이징 | 안전 |
git reset --hard HEAD~1 | 마지막 커밋 + 모든 변경사항 삭제 | 전부 | 위험 |
git revert | 커밋을 되돌리는 새 커밋 생성 | 커밋 이력 유지 | 매우 안전 |
git stash | 작업 중 변경사항 임시 저장 | 작업 디렉터리 | 안전 |
검사 명령어
| 명령어 | 설명 | 사용 예시 |
|---|---|---|
git blame | 줄별 마지막 수정자 확인 | git blame src/model.py |
git bisect | 이진 탐색으로 버그 커밋 찾기 | git bisect start, git bisect good/bad |
git reflog | HEAD 이동 이력 (실수 복구용) | git reflog |
충돌 해결
충돌 발생 원인
두 브랜치가 같은 파일의 같은 부분을 서로 다르게 수정한 후 머지할 때 충돌이 발생합니다.충돌 해결 순서
ML 실험에서 Git 활용
실험 브랜치 전략
하이퍼파라미터 추적
Git과 DVC/MLflow의 역할 분담
| 관리 대상 | Git | DVC | MLflow |
|---|---|---|---|
| 소스 코드 | O | - | - |
| 설정 파일 (YAML, JSON) | O | - | 파라미터 로깅 |
| 데이터셋 | - | O | - |
| 모델 체크포인트 | - | O | 아티팩트 로깅 |
| 학습 메트릭 (loss, accuracy) | - | - | O |
| 실험 비교 | 커밋 이력 | 파이프라인 비교 | UI 대시보드 |
커밋한 대용량 파일을 이력에서 완전히 제거하려면?
커밋한 대용량 파일을 이력에서 완전히 제거하려면?
git rm --cached는 현재 상태에서만 제거합니다. 이력에서 완전히 지우려면 git filter-branch 또는 더 안전한 BFG Repo-Cleaner를 사용하세요. java -jar bfg.jar --strip-blobs-bigger-than 100M으로 100MB 이상 파일을 이력에서 제거할 수 있습니다. 이 작업은 이력을 재작성하므로, 팀원에게 알리고 force push가 필요합니다.rebase와 merge의 차이는 무엇인가요?
rebase와 merge의 차이는 무엇인가요?
merge는 두 브랜치를 합치는 머지 커밋을 생성합니다. 이력에 분기와 합류가 보입니다. rebase는 현재 브랜치의 커밋을 대상 브랜치 끝에 재배치하여 직선적인 이력을 만듭니다. 팀에서는
git pull --rebase로 로컬 변경사항을 원격 위에 깔끔하게 재배치하는 것이 일반적입니다. 단, 이미 푸시한 커밋은 rebase하지 마세요 — 다른 팀원의 이력과 충돌합니다.실수로 잘못된 브랜치에 커밋했어요
실수로 잘못된 브랜치에 커밋했어요
git reflog로 커밋 해시를 확인한 후, (1) 올바른 브랜치로 체리픽: git checkout correct-branch && git cherry-pick <hash>, (2) 잘못된 브랜치에서 제거: git checkout wrong-branch && git reset --hard HEAD~1. reflog는 30일간 모든 HEAD 이동을 기록하므로, 대부분의 실수를 복구할 수 있습니다..gitignore가 적용되지 않아요
.gitignore가 적용되지 않아요
이미 Git에 추적 중인 파일은
.gitignore가 무시됩니다. git rm --cached <파일>로 추적을 해제한 후 커밋하세요. 여러 파일을 한번에 처리하려면: git rm -r --cached . → git add . → git commit -m "chore: apply gitignore". 이 방법은 모든 파일의 추적을 해제했다가 .gitignore 규칙에 따라 다시 추가합니다.ML 실험에서 Git 커밋을 어떤 단위로 해야 하나요?
ML 실험에서 Git 커밋을 어떤 단위로 해야 하나요?
(1) 설정 변경: 하이퍼파라미터, 데이터 전처리, 모델 구조 변경 시 커밋. (2) 코드 변경: 새로운 기능 추가, 리팩터링 시 커밋. (3) 실험 결과: 커밋 메시지 본문에 주요 메트릭을 기록. 체크포인트 파일 자체는 DVC/MLflow로 관리하고, Git에는 코드와 설정만 추적하세요. 이렇게 하면 특정 커밋으로 체크아웃하여 그 시점의 설정으로 실험을 재현할 수 있습니다.
Git LFS는 언제 사용하나요?
Git LFS는 언제 사용하나요?
Git LFS(Large File Storage)는 대용량 파일을 별도 스토리지에 저장하고, Git에는 포인터만 기록합니다. 100MB 이상의 바이너리 파일(모델, 데이터셋)이 반드시 Git으로 관리되어야 할 때 사용합니다. 하지만 ML 프로젝트에서는 DVC가 더 적합한 경우가 많습니다. DVC는 파이프라인 재현성까지 지원하고, S3/GCS 등 다양한 원격 스토리지를 백엔드로 사용할 수 있기 때문입니다.
체크리스트
- Git의 스냅샷 기반 동작 원리를 설명할 수 있다
- Working Directory, Staging Area, Repository의 역할을 구분할 수 있다
- HEAD, 브랜치 포인터, 태그의 차이를 이해했다
-
git config로 사용자 정보와 SSH 키를 설정할 수 있다 - clone → branch → commit → push → PR → merge 워크플로우를 수행할 수 있다
- Conventional Commits 형식으로 커밋 메시지를 작성할 수 있다
- ML 프로젝트에 적합한
.gitignore를 구성할 수 있다 - merge conflict를 확인하고 해결할 수 있다
-
git stash,git reset,git revert를 상황에 맞게 사용할 수 있다 - ML 실험에서 Git, DVC, MLflow의 역할 분담을 설명할 수 있다

