Git은 소프트웨어 개발 중 소스 코드의 변경 사항을 추적하기 위해 설계된 분산 버전 관리 시스템입니다. 2005년 리누스 토발즈가 리눅스 커널 개발을 위해 만들었습니다.
일반적인 Git 명령어
git init- 새로운 Git 저장소 초기화git clone [url]- 원격 소스에서 저장소 복제git add [file]- 파일을 스테이징 영역에 추가git commit -m "[message]"- 메시지와 함께 변경 사항 커밋git status- 작업 디렉토리의 상태 확인git pull- 원격 저장소에서 변경 사항을 가져와 병합git push- 원격 저장소에 커밋 푸시git branch- 모든 로컬 브랜치 나열git checkout [branch-name]- 다른 브랜치로 전환git merge [branch]- 활성 브랜치에 다른 브랜치 병합
Git 워크플로우
- 기능 브랜치 워크플로우: 각 기능마다 새 브랜치 생성
- Gitflow 워크플로우: 프로젝트 릴리스를 중심으로 설계된 엄격한 브랜칭 모델
- 포킹 워크플로우: 오픈 소스 프로젝트에서 흔히 사용되며, 저장소 포킹 포함
관련 도구
Git은 다음과 같은 호스팅 서비스와 함께 자주 사용됩니다:
- GitHub - 세계에서 가장 인기 있는 Git 호스팅 서비스, Microsoft 소유
- GitLab - CI/CD 파이프라인이 통합된 Git 저장소 관리자
- Bitbucket - Atlassian의 Git 솔루션, Jira와 통합
- Gitea - 셀프 호스팅 가능한 경량 Git 서비스
- Azure DevOps - Microsoft의 개발자 서비스 플랫폼, Git 저장소 포함
- AWS CodeCommit - Amazon의 관리형 Git 서비스
- SourceForge - 오픈소스 프로젝트를 위한 웹 서비스, Git 지원
오픈소스 Git 라이브러리
Git을 프로그래밍 방식으로 사용할 수 있는 다양한 오픈소스 라이브러리가 있습니다:
-
libgit2: C로 작성된 Git 코어 메서드를 구현한 크로스 플랫폼 라이브러리
- 다양한 언어 바인딩 제공 (Python의 pygit2, Ruby의 rugged 등)
- 메모리 관리와 에러 처리 기능 포함
-
JGit: Java로 구현된 Git 라이브러리
- Eclipse 재단에서 관리
- 순수 Java로 작성되어 플랫폼 독립적
-
go-git: Go 언어로 작성된 Git 구현체
- 순수 Go로 작성되어 CGO 의존성 없음
- 분산 환경에서 사용하기 적합
-
nodegit: Node.js를 위한 Git 바인딩
- libgit2 기반으로 JavaScript/TypeScript에서 Git 기능 사용 가능
-
GitCafe: 중국에서 개발된 Git 호스팅 서비스
- 2015년 Coding.net에 인수됨
- 중국 개발자들 사이에서 인기 있었던 GitHub 대안
- 코드 호스팅, 이슈 트래킹, 위키 등 기본 기능 제공
-
Dulwich: Python으로 작성된 순수 Git 구현체
- 외부 Git 명령어에 의존하지 않는 순수 Python 구현
- Git 저장소 접근 및 조작을 위한 Pythonic API 제공
- 가볍고 설치가 쉬움
-
GitPython: Python용 Git 상호작용 라이브러리
- Git 명령줄 도구를 래핑하는 Python 인터페이스
- Git 저장소 조작을 위한 고수준 API 제공
- 스크립팅 및 자동화에 적합
-
grit: Ruby로 작성된 Git 라이브러리
- GitHub에서 초기에 사용했던 라이브러리
- 현재는 rugged로 대체되었지만 여전히 사용됨
- Ruby 애플리케이션에서 Git 기능 통합에 유용
-
pygit: Python용 경량 Git 인터페이스
- 기본 Git 명령어에 대한 간단한 래퍼 제공
- 최소한의 의존성으로 설계됨
이러한 라이브러리는 Git 기능을 애플리케이션에 통합하거나 Git 워크플로우를 자동화하는 데 유용합니다.
Git의 진화 (2025~2030)
SHA-256 전환
| 항목 | 내용 |
|---|---|
| 문제 | SHA-1 보안 취약점 — 2017년 SHAttered 공격으로 충돌 가능성 입증 |
| 해결 | Git 2.29(2020)에서 SHA-256 지원 추가 |
| 계획 | 2030년까지 SHA-1 제거, Git 3.0에서 SHA-256 기본값 |
| 현황 | GitHub 등 주요 플랫폼 아직 미지원 |
Reftable
| 항목 | 내용 |
|---|---|
| 문제 | 기존 개별 파일 기반 참조(ref) 구조 → 수천만 개 참조 시 성능 저하 |
| 해결 | 이진 포맷 테이블 구조로 전환 |
| 효과 | 대규모 저장소에서 참조 관리 효율화, 동시성 문제 해결 |
| 사례 | GitLab의 2GB packed-refs 파일 재작성 문제 해결 |
대용량 파일 처리 개선
- Large-object promisors: 대형 객체를 원격 저장소에 보관
- 플러그형 객체 데이터베이스: 바이너리 전용 저장 포맷 도입
- 기존 Git LFS의 한계 보완
Git 대안 VCS
Jujutsu (jj)
| 항목 | 내용 |
|---|---|
| 개발 | Google 엔지니어 (Martin von Zweigbergk) |
| 언어 | Rust |
| 핵심 | Git 호환 + 현대적 UX |
| 라이선스 | Apache 2.0 |
| GitHub | https://github.com/martinvonz/jj |
Git과의 차이점:
| 기능 | Git | Jujutsu (jj) |
|---|---|---|
| 작업 카피 | 별도 (working tree) | 자동 커밋 (항상 커밋 상태) |
| 히스토리 편집 | rebase -i (복잡) | jj squash/split (간단) |
| 충돌 해결 | merge 시 즉시 해결 필수 | 충돌을 커밋으로 기록, 나중에 해결 |
| 브랜치 | 명시적 생성/전환 | 자동 익명 브랜치 |
| Undo | reflog (복잡) | jj undo (간단) |
| 스테이징 | add → commit 2단계 | 불필요 (자동) |
| Git 호환 | - | O (Git 저장소 직접 사용) |
# jj 기본 사용법
jj init # 새 저장소 (또는 기존 Git 저장소에서)
jj new # 새 변경 시작
jj describe -m "메시지" # 커밋 메시지
jj squash # 이전 커밋에 합치기
jj split # 커밋 분리
jj undo # 실행 취소
jj log # 히스토리 (그래프)
jj git push # Git 원격에 푸시
# Git 저장소를 jj로 사용
cd existing-git-repo
jj git init --colocate # Git과 jj 공존장점:
- Git 저장소 그대로 사용 가능 (점진적 전환)
- 충돌을 나중에 해결할 수 있음 → 리베이스가 안전
- 자동 리베이스: 부모 커밋 변경 시 하위 커밋 자동 업데이트
- Git 자체도 jj의 영향을 받아 UI 개선 중
단점:
- Git 대비 작은 생태계
- IDE/도구 통합 아직 미성숙
- 팀 전체 전환 시 학습 비용
기타 VCS
| VCS | 특징 |
|---|---|
| Sapling | Meta 개발, Git 호환, 가상 파일시스템 |
| Pijul | 패치 이론 기반, 수학적 정합성 |
| Fossil | SQLite 개발자, 위키/이슈 내장 |
Git 고급 기능
-
Git Rebase: 커밋 히스토리를 재구성하여 더 깔끔한 히스토리 생성
git rebase [branch]- 현재 브랜치를 다른 브랜치 위에 재배치git rebase -i HEAD~[n]- 대화형 리베이스로 최근 n개 커밋 수정
-
Git Stash: 작업 중인 변경사항을 임시 저장
git stash- 변경사항 임시 저장git stash pop- 가장 최근 스태시 적용 및 제거git stash list- 모든 스태시 목록 표시
-
Git Cherry-pick: 특정 커밋만 선택적으로 적용
git cherry-pick [commit-hash]- 다른 브랜치의 특정 커밋을 현재 브랜치에 적용
-
Git Hooks: 특정 이벤트 발생 시 자동으로 스크립트 실행
- pre-commit, post-commit, pre-push 등 다양한 훅 제공