
버전 관리는 소프트웨어 개발 및 유지 보수 과정에서 발생하는 소스 코드, 문서 등의 생성, 변경 이력, 삭제 이력 등을 관리하는 것이다.
우리는 다음과 같은 상황에서 버전 관리의 필요성을 느낀다
버전 관리 없이 작업할 때
프로젝트_최종.zip
프로젝트_최종2.zip
프로젝트_최종_진짜최종.zip
프로젝트_최종_완료.zip
이런 방식의 문제점은 어떤 파일이 최신인지 알기 어렵고, 변경 내용을 파악하기 힘들며 협업시 파일 충돌 발생, 특정 시점으로 되돌리기(롤백)이 복잡하다.
버전 관리 시스템은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 불러올 수 있는 시스템이다.
문제점
Git은 리누스 토르발즈가 2005년에 개발한 분산 버전 관리 시스템으로, 여러 명의 개발자가 하나의 소프트웨어 개발 프로젝트에 참여할 때 소스 코드를 관리하는 데 사용된다.
주의: commit(로컬 저장소에 저장)과 push(서버로 전송)는 다른 개념이다.
Git은 브랜치로 작업을 관리하는데, 팀에서 브랜치를 어떻게 사용할지에 대해 정해둔 규칙을 Workflow라고 한다.
브랜치의 역할이 명확하고 대규모 프로젝트에 적합한 워크플로우이다. 5개의 브랜치로 관리한다.
develop에서 feature 브랜치를 따서 작업한다.develop에 병합한다.develop 브랜치에서 배포 준비가 끝나면 release 브랜치로 분할한다.release 브랜치에서 디버깅하고 문제가 없으면 master와 develop 브랜치에 합친다.master 브랜치를 배포한다.hotfix 브랜치를 따서 작업한다.hotfix에서 버그 수정이 끝나면 master와 develop에 합친다.적용 사례:
하나의 메인 브랜치인 master 브랜치를 중점으로 운용하며 pull request를 활용하는 방식의 워크플로우이다.
Pull Request: "작업한 코드가 있으니 내 브랜치를 pull해 검토, 병합해달라"라는 의미
feature 브랜치에서 작업하며 작업이 끝나면 pull request를 생성한다.master에 병합한다.master에 병합하면 바로 배포 작업을 수행한다. (CI 자동화 권장)적용 사례:
Master와 Develop 2개의 메인 브랜치로 관리하는 방식의 워크플로우이다. 항상 최신 버전을 유지하지 않아도 되며 배포 버전과 개발 버전을 따로 둘 수 있다는 장점이 있다.
develop 브랜치는 항상 최신 버전의 코드를 관리하며 작업을 하는 메인 브랜치이다.develop 브랜치가 배포되기 적합하다고 판단되면 master 브랜치에 merge한다.적용 사례:
Git은 다음과 같은 핵심 구성 요소로 이루어져 있다:
- 저장소(Repository): 프로젝트의 모든 파일과 이력 정보를 포함
- 커밋(Commit): 변경 사항의 스냅샷
- 브랜치(Branch): 독립적인 개발 라인
- 원격 저장소(Remote): 서버에 호스팅된 저장소
다양한 Git Workflow 모델이 존재하며, 각각의 특징은 다음과 같다:
Centralized Workflow:

Feature Branch Workflow:

Gitflow Workflow:

Forking Workflow:

각 워크플로우는 브랜치를 다르게 활용한다:
Git은 파일 시스템에 기반한 Key-Value(딕셔너리) 저장소로 동작한다:
워크플로우에 따라 개발 프로세스가 크게 달라진다:
Centralized Workflow 프로세스:
1. 변경 사항 커밋
2. 원격 저장소에서 최신 변경 가져오기(pull)
3. 충돌 해결 후 원격 저장소에 푸시(push)
Gitflow Workflow 프로세스:
1. develop 브랜치에서 feature 브랜치 생성
2. 기능 개발 및 커밋
3. 완성된 기능을 develop에 병합
4. release 브랜치 생성 및 버그 수정
5. release를 master와 develop에 병합
6. 필요시 hotfix 브랜치로 긴급 수정
워크플로우에 따라 팀 협업 방식이 달라진다:
Git은 한 브랜치에서 작업한 내용을 Main 브랜치에 병합(Merge) 할 수 있는 다양한 방법들을 제공한다. 이러한 방법들을 Merge 전략이라고 부른다.
Create a merge commit은 모든 브랜치의 commit log와 merge log가 동시에 기록되는 방식이다.
A---B---C feature
/ \
D---E---F---G main
↑
병합 커밋 생성
사용 시기:
Squash and merge는 여러 개의 commit을 하나로 합친 후 merge하는 방식이다.
기존: A---B---C feature
/
D---E---F main
결과: D---E---F---G main
↑
A+B+C를 합친 새 커밋
사용 시기:
Rebase and merge는 Rebase 기능을 사용해 브랜치를 merge하는 방식으로, 신규 branch의 시작점을 main의 가장 최근 커밋으로 (강제로) 옮기는 것이다.
메인브랜치와 새로운 브랜치가 각각 추가적인 커밋을 한 경우에서 새로운 브랜치의 시작점을 강제로 옮기는 것이다.
기존: A---B---C feature
/
D---E---F main
Rebase 후: D---E---F---A'---B'---C' main
↑
선형적 히스토리
메인브랜치는 변경사항이 없고 새로운 브랜치만 변경사항이 있는 상황에서, 단순히 새로운 브랜치를 메인브랜치로 옮기는 것을 말한다.
사용 시기:
| 방식 | 히스토리 | 장점 | 단점 |
|---|---|---|---|
| 3-way Merge | 복잡한 그래프 | 완전한 이력 보존 | 복잡한 히스토리 |
| Squash Merge | 간단한 선형 | 깔끔한 히스토리 | 세부 이력 손실 |
| Rebase Merge | 깔끔한 선형 | 읽기 쉬운 이력 | 충돌 해결 복잡 |