Branch (브랜치)
1. 개요
브랜치(Branch)란 버전 관리 시스템(VCS)에서 메인 코드 라인에서 분리되어 독립적으로 작업을 수행할 수 있도록 만든 가지 형태의 개발 경로를 의미합니다.
소프트웨어 개발 과정에서 새로운 기능을 추가하거나 버그를 수정할 때, 기존의 안정적인 코드(Main/Master)에 직접 수정 사항을 반영하면 예기치 못한 오류가 발생하여 전체 시스템이 중단될 위험이 있습니다. 브랜치를 활용하면 개발자는 독립된 환경에서 실험적인 시도를 하거나 기능을 구현한 뒤, 검증이 완료된 시점에만 메인 코드에 [Merge]함으로써 프로젝트의 안정성을 유지하고 여러 명의 개발자가 동시에 서로 다른 기능을 개발하는 병렬 작업 환경을 구축할 수 있습니다.
2. 작동 원리
Git과 같은 현대적인 분산 버전 관리 시스템에서 브랜치는 물리적인 파일 복사본이 아니라, 특정 [Commit]을 가리키는 가벼운 포인터(Lightweight Pointer)로 작동합니다.
내부 메커니즘
- 커밋 그래프: 모든 변경 사항은 스냅샷 형태의 [Commit]으로 저장되며, 각 커밋은 이전 커밋의 해시 값을 가지고 있어 연결 리스트 형태의 그래프를 이룹니다.
- 브랜치 생성: 새로운 브랜치를 생성하면, 현재 가리키고 있는 커밋의 해시 값을 가진 새로운 포인터가 생성될 뿐입니다. 실제 데이터가 복제되지 않으므로 생성 속도가 매우 빠릅니다.
- HEAD 포인터: 현재 작업 중인 브랜치가 무엇인지 나타내는 특수 포인터입니다. 브랜치를 전환(Checkout)하면 HEAD가 해당 브랜치 포인터를 가리키게 되며, 작업 디렉토리의 파일들이 해당 커밋 상태로 변경됩니다.
[브랜치 이동 도식]
graph LR
A((Commit A)) --> B((Commit B))
B --> C((Commit C))
B --> D((Commit D))
C --- Main[Main Branch]
D --- Feature[Feature Branch]
Feature --- HEAD((HEAD))
3. 로컬 브랜치와 원격 브랜치의 차이
협업 환경에서는 내 컴퓨터에 존재하는 브랜치와 서버(GitHub, GitLab 등)에 존재하는 브랜치를 구분하여 관리합니다.
| 구분 |
로컬 브랜치 (Local Branch) |
원격 브랜치 (Remote Branch) |
| 위치 |
개발자의 로컬 저장소 (Local Repository) |
중앙 서버의 원격 저장소 (Remote Repository) |
| 특징 |
개인적인 작업 공간이며, Push 전까지는 타인에게 보이지 않음 |
팀원들이 공유하는 공용 공간이며, 협업의 기준점이 됨 |
| 동기화 |
git commit을 통해 로컬에 저장 |
git push 또는 git pull을 통해 로컬과 동기화 |
| 참조 방식 |
feature/login |
origin/feature/login (원격 추적 브랜치(Remote-Tracking Branch): 원격 저장소의 상태를 로컬에 캐싱해둔 읽기 전용 포인터) |
4. 주요 브랜치 전략 (Branching Strategy)
프로젝트의 규모와 배포 주기, 팀의 성격에 따라 적절한 브랜치 운영 전략을 선택해야 합니다.
| 전략 |
핵심 특징 |
장점 |
단점 |
적합한 프로젝트 |
| Git-flow |
Main, Develop, Feature, Release, Hotfix 5종 브랜치 운영 |
엄격한 릴리스 관리, 역할 분담 명확 |
구조가 복잡하고 [Merge] 횟수가 많음 |
대규모 프로젝트, 정기 릴리스 주기 |
| GitHub-flow |
Main과 Feature 브랜치만 사용, [Pull Request] 중심 |
단순함, 빠른 배포(CD) 가능 |
Main 브랜치 오염 위험, 세밀한 버전 관리 어려움 |
소규모 팀, 지속적 배포(CI/CD) 환경 |
| Trunk-based |
모든 개발자가 하나의 Main(Trunk)에 짧게 병합 |
[Conflict] 최소화, 통합 속도 매우 빠름 |
높은 수준의 테스트 자동화 필수, 숙련도 요구 |
매우 빠른 배포 주기, 고도로 자동화된 팀 |
[Git-flow 브랜치 관계도]
graph TD
Main[Main: 제품 출시 버전]
Develop[Develop: 다음 출시 버전 개발]
Feature[Feature: 기능 개발]
Release[Release: 출시 준비]
Hotfix[Hotfix: 긴급 수정]
Main --> Develop
Develop --> Feature
Feature --> Develop
Develop --> Release
Release --> Main
Release --> Develop
Main --> Hotfix
Hotfix --> Main
Hotfix --> Develop
5. 핵심 작업 흐름 (Workflow)
5.1. 기본 명령어 및 프로세스
브랜치의 생성부터 병합까지의 일반적인 흐름은 다음과 같습니다.
# 1. 새로운 브랜치 생성
git branch feature/login
# 2. 생성한 브랜치로 전환 (최신 버전은 switch 권장)
git switch feature/login # 또는 git checkout feature/login
# [Tip] 생성과 전환을 동시에 수행하는 효율적인 방법
git switch -c feature/login # 또는 git checkout -b feature/login
# 3. 작업 후 커밋
git add .
git commit -m "Add login functionality"
# 4. 메인 브랜치로 복귀
git switch main
# 5. 작업한 브랜치를 메인에 병합
git merge feature/login
두 브랜치에서 동일한 파일의 동일한 라인을 수정했을 때, Git은 자동으로 병합하지 못하고 충돌([Conflict])을 발생시킵니다.
[충돌 해결 단계]
1. 충돌 확인: git merge 실행 시 CONFLICT (content): Merge conflict in [파일명] 메시지가 출력됩니다.
2. 파일 수정: 충돌이 발생한 파일을 열면 아래와 같은 표식(Conflict Marker)이 보입니다.
- <<<<<<< HEAD: 현재 브랜치의 변경 내용
- =======: 구분선
- >>>>>>> branch-name: 병합하려는 브랜치의 변경 내용
3. 코드 선택: 개발자가 직접 코드를 검토하여 남길 내용을 선택하고 마커(<<<<, ====, >>>>)를 모두 제거합니다.
4. 변경 사항 반영:
git add [충돌해결파일명]
git commit -m "Fix merge conflict in [파일명]"
6. 병합 방식의 차이: [Merge] vs Rebase
커밋 히스토리를 어떻게 남길 것인가에 따라 두 가지 방식을 사용합니다.
| 비교 항목 |
[Merge] (병합) |
Rebase (재배치) |
| 히스토리 형태 |
비선형 (갈라졌다가 합쳐지는 모습 유지) |
선형 (한 줄로 깔끔하게 정렬됨) |
| 추적 가능성 |
병합 커밋이 생성되어 언제 합쳐졌는지 기록됨 |
기존 커밋 해시가 변경되어 원래 흐름 추적이 어려움 |
| 사용 목적 |
기능 완료 후 메인 브랜치에 통합할 때 |
로컬 작업 내용을 최신 메인 상태 위로 올릴 때 |
| 위험성 |
비교적 안전함 |
이미 원격에 Push된 커밋을 Rebase할 경우, 다른 팀원의 히스토리와 불일치하여 심각한 충돌 및 데이터 유실 위험이 있음 |
7. 브랜치 삭제 및 정리
작업이 완료된 브랜치를 방치하면 저장소가 복잡해지므로 주기적인 정리가 필요합니다.
# 1. 로컬 브랜치 삭제 (병합이 완료된 경우)
git branch -d feature/login
# 2. 로컬 브랜치 강제 삭제 (병합되지 않았더라도 삭제)
git branch -D feature/login
# 3. 원격 저장소의 브랜치 삭제
git push origin --delete feature/login
# 4. 원격에서 삭제된 브랜치 정보를 로컬에 동기화 (Prune)
git fetch --prune
8. 주의사항 및 모범 사례 (Best Practices)
효율적인 협업과 유지보수를 위해 다음 가이드를 준수하는 것이 권장됩니다.
- 명명 규칙(Naming Convention) 수립: 브랜치 이름만으로 목적을 알 수 있게 합니다.
feature/ : 새로운 기능 개발
bugfix/ 또는 hotfix/ : 버그 수정
docs/ : 문서 수정
refactor/ : 코드 리팩토링
- 짧은 생명주기 유지: 브랜치를 너무 오래 유지하면 메인 코드와의 격차가 커져 병합 시 거대한 충돌(Merge Hell)이 발생합니다. 가능한 한 작게 쪼개어 자주 병합하십시오.
- 원자적 커밋(Atomic Commit): 하나의 브랜치/[Commit]에는 하나의 논리적 변경 사항만 담아, 문제 발생 시 롤백(Rollback)을 쉽게 만듭니다.
- [Pull Request](PR) 활용: 직접 병합하기보다 PR을 통해 팀원의 코드 리뷰를 거친 후 병합하여 코드 품질을 높입니다.
# Branch (브랜치)
## 1. 개요
**브랜치(Branch)**란 버전 관리 시스템(VCS)에서 메인 코드 라인에서 분리되어 독립적으로 작업을 수행할 수 있도록 만든 가지 형태의 개발 경로를 의미합니다.
소프트웨어 개발 과정에서 새로운 기능을 추가하거나 버그를 수정할 때, 기존의 안정적인 코드(Main/Master)에 직접 수정 사항을 반영하면 예기치 못한 오류가 발생하여 전체 시스템이 중단될 위험이 있습니다. 브랜치를 활용하면 개발자는 독립된 환경에서 실험적인 시도를 하거나 기능을 구현한 뒤, 검증이 완료된 시점에만 메인 코드에 [[Merge]](Merge)함으로써 프로젝트의 안정성을 유지하고 여러 명의 개발자가 동시에 서로 다른 기능을 개발하는 병렬 작업 환경을 구축할 수 있습니다.
## 2. 작동 원리
Git과 같은 현대적인 분산 버전 관리 시스템에서 브랜치는 물리적인 파일 복사본이 아니라, 특정 **[[Commit]](Commit)**을 가리키는 **가벼운 포인터(Lightweight Pointer)**로 작동합니다.
### 내부 메커니즘
1. **커밋 그래프**: 모든 변경 사항은 스냅샷 형태의 [[Commit]](Commit)으로 저장되며, 각 커밋은 이전 커밋의 해시 값을 가지고 있어 연결 리스트 형태의 그래프를 이룹니다.
2. **브랜치 생성**: 새로운 브랜치를 생성하면, 현재 가리키고 있는 커밋의 해시 값을 가진 새로운 포인터가 생성될 뿐입니다. 실제 데이터가 복제되지 않으므로 생성 속도가 매우 빠릅니다.
3. **HEAD 포인터**: 현재 작업 중인 브랜치가 무엇인지 나타내는 특수 포인터입니다. 브랜치를 전환(Checkout)하면 HEAD가 해당 브랜치 포인터를 가리키게 되며, 작업 디렉토리의 파일들이 해당 커밋 상태로 변경됩니다.
**[브랜치 이동 도식]**
```mermaid
graph LR
A((Commit A)) --> B((Commit B))
B --> C((Commit C))
B --> D((Commit D))
C --- Main[Main Branch]
D --- Feature[Feature Branch]
Feature --- HEAD((HEAD))
```
## 3. 로컬 브랜치와 원격 브랜치의 차이
협업 환경에서는 내 컴퓨터에 존재하는 브랜치와 서버(GitHub, GitLab 등)에 존재하는 브랜치를 구분하여 관리합니다.
| 구분 | 로컬 브랜치 (Local Branch) | 원격 브랜치 (Remote Branch) |
| :--- | :--- | :--- |
| **위치** | 개발자의 로컬 저장소 (Local Repository) | 중앙 서버의 원격 저장소 (Remote Repository) |
| **특징** | 개인적인 작업 공간이며, Push 전까지는 타인에게 보이지 않음 | 팀원들이 공유하는 공용 공간이며, 협업의 기준점이 됨 |
| **동기화** | `git commit`을 통해 로컬에 저장 | `git push` 또는 `git pull`을 통해 로컬과 동기화 |
| **참조 방식** | `feature/login` | `origin/feature/login` (**원격 추적 브랜치(Remote-Tracking Branch)**: 원격 저장소의 상태를 로컬에 캐싱해둔 읽기 전용 포인터) |
## 4. 주요 브랜치 전략 (Branching Strategy)
프로젝트의 규모와 배포 주기, 팀의 성격에 따라 적절한 브랜치 운영 전략을 선택해야 합니다.
| 전략 | 핵심 특징 | 장점 | 단점 | 적합한 프로젝트 |
| :--- | :--- | :--- | :--- | :--- |
| **Git-flow** | Main, Develop, Feature, Release, Hotfix 5종 브랜치 운영 | 엄격한 릴리스 관리, 역할 분담 명확 | 구조가 복잡하고 [[Merge]](Merge) 횟수가 많음 | 대규모 프로젝트, 정기 릴리스 주기 |
| **GitHub-flow** | Main과 Feature 브랜치만 사용, [[Pull Request]](Pull Request) 중심 | 단순함, 빠른 배포(CD) 가능 | Main 브랜치 오염 위험, 세밀한 버전 관리 어려움 | 소규모 팀, 지속적 배포(CI/CD) 환경 |
| **Trunk-based** | 모든 개발자가 하나의 Main(Trunk)에 짧게 병합 | [[Conflict]](Conflict) 최소화, 통합 속도 매우 빠름 | 높은 수준의 테스트 자동화 필수, 숙련도 요구 | 매우 빠른 배포 주기, 고도로 자동화된 팀 |
**[Git-flow 브랜치 관계도]**
```mermaid
graph TD
Main[Main: 제품 출시 버전]
Develop[Develop: 다음 출시 버전 개발]
Feature[Feature: 기능 개발]
Release[Release: 출시 준비]
Hotfix[Hotfix: 긴급 수정]
Main --> Develop
Develop --> Feature
Feature --> Develop
Develop --> Release
Release --> Main
Release --> Develop
Main --> Hotfix
Hotfix --> Main
Hotfix --> Develop
```
## 5. 핵심 작업 흐름 (Workflow)
### 5.1. 기본 명령어 및 프로세스
브랜치의 생성부터 병합까지의 일반적인 흐름은 다음과 같습니다.
```bash
# 1. 새로운 브랜치 생성
git branch feature/login
# 2. 생성한 브랜치로 전환 (최신 버전은 switch 권장)
git switch feature/login # 또는 git checkout feature/login
# [Tip] 생성과 전환을 동시에 수행하는 효율적인 방법
git switch -c feature/login # 또는 git checkout -b feature/login
# 3. 작업 후 커밋
git add .
git commit -m "Add login functionality"
# 4. 메인 브랜치로 복귀
git switch main
# 5. 작업한 브랜치를 메인에 병합
git merge feature/login
```
### 5.2. [[Conflict]](Conflict) 해결 가이드
두 브랜치에서 동일한 파일의 동일한 라인을 수정했을 때, Git은 자동으로 병합하지 못하고 **충돌([[Conflict]](Conflict))**을 발생시킵니다.
**[충돌 해결 단계]**
1. **충돌 확인**: `git merge` 실행 시 `CONFLICT (content): Merge conflict in [파일명]` 메시지가 출력됩니다.
2. **파일 수정**: 충돌이 발생한 파일을 열면 아래와 같은 표식(Conflict Marker)이 보입니다.
- `<<<<<<< HEAD`: 현재 브랜치의 변경 내용
- `=======`: 구분선
- `>>>>>>> branch-name`: 병합하려는 브랜치의 변경 내용
3. **코드 선택**: 개발자가 직접 코드를 검토하여 남길 내용을 선택하고 마커(`<<<<`, `====`, `>>>>`)를 모두 제거합니다.
4. **변경 사항 반영**:
```bash
git add [충돌해결파일명]
git commit -m "Fix merge conflict in [파일명]"
```
## 6. 병합 방식의 차이: [[Merge]](Merge) vs Rebase
커밋 히스토리를 어떻게 남길 것인가에 따라 두 가지 방식을 사용합니다.
| 비교 항목 | [[Merge]](Merge) (병합) | Rebase (재배치) |
| :--- | :--- | :--- |
| **히스토리 형태** | 비선형 (갈라졌다가 합쳐지는 모습 유지) | 선형 (한 줄로 깔끔하게 정렬됨) |
| **추적 가능성** | 병합 커밋이 생성되어 언제 합쳐졌는지 기록됨 | 기존 커밋 해시가 변경되어 원래 흐름 추적이 어려움 |
| **사용 목적** | 기능 완료 후 메인 브랜치에 통합할 때 | 로컬 작업 내용을 최신 메인 상태 위로 올릴 때 |
| **위험성** | 비교적 안전함 | **이미 원격에 Push된 커밋을 Rebase할 경우, 다른 팀원의 히스토리와 불일치하여 심각한 충돌 및 데이터 유실 위험이 있음** |
## 7. 브랜치 삭제 및 정리
작업이 완료된 브랜치를 방치하면 저장소가 복잡해지므로 주기적인 정리가 필요합니다.
```bash
# 1. 로컬 브랜치 삭제 (병합이 완료된 경우)
git branch -d feature/login
# 2. 로컬 브랜치 강제 삭제 (병합되지 않았더라도 삭제)
git branch -D feature/login
# 3. 원격 저장소의 브랜치 삭제
git push origin --delete feature/login
# 4. 원격에서 삭제된 브랜치 정보를 로컬에 동기화 (Prune)
git fetch --prune
```
## 8. 주의사항 및 모범 사례 (Best Practices)
효율적인 협업과 유지보수를 위해 다음 가이드를 준수하는 것이 권장됩니다.
- **명명 규칙(Naming Convention) 수립**: 브랜치 이름만으로 목적을 알 수 있게 합니다.
- `feature/` : 새로운 기능 개발
- `bugfix/` 또는 `hotfix/` : 버그 수정
- `docs/` : 문서 수정
- `refactor/` : 코드 리팩토링
- **짧은 생명주기 유지**: 브랜치를 너무 오래 유지하면 메인 코드와의 격차가 커져 병합 시 거대한 충돌(Merge Hell)이 발생합니다. 가능한 한 작게 쪼개어 자주 병합하십시오.
- **원자적 커밋(Atomic Commit)**: 하나의 브랜치/[[Commit]](Commit)에는 하나의 논리적 변경 사항만 담아, 문제 발생 시 롤백(Rollback)을 쉽게 만듭니다.
- **[[Pull Request]](Pull Request)(PR) 활용**: 직접 병합하기보다 PR을 통해 팀원의 코드 리뷰를 거친 후 병합하여 코드 품질을 높입니다.