3.3 Branching and Merging
핵심 개념
브랜치는 Git의 가장 강력한 기능 중 하나로, 메인 개발 라인에서 분기하여 독립적인 작업을 수행할 수 있게 합니다. 생물정보학 연구에서는 실험적 분석 방법, 매개변수 조정, 새로운 알고리즘 테스트를 위해 브랜치를 활용하여 안정적인 메인 코드를 보호하면서 혁신적인 시도를 할 수 있습니다.
브랜치 모델과 동작 원리
Git의 브랜치는 커밋을 가리키는 가벼운 포인터입니다. 새로운 브랜치를 생성해도 저장소 크기가 거의 증가하지 않으며, 브랜치 간 전환도 매우 빠릅니다.
# 브랜치 구조 시각화
$ git log --oneline --graph --all
* a1b2c3d (HEAD -> feature-qc) feat(qc): Add advanced quality metrics
* e4f5g6h (main) fix(pipeline): Correct alignment parameters
* i7j8k9l feat(data): Add sample metadata processing
* m1n2o3p Initial commit
# 브랜치는 단순히 커밋 해시를 가리키는 파일
$ cat .git/refs/heads/main
e4f5g6h1234567890abcdef1234567890abcdef12
$ cat .git/refs/heads/feature-qc
a1b2c3d1234567890abcdef1234567890abcdef12
HEAD 포인터의 역할:
# HEAD는 현재 작업 중인 브랜치를 가리킴
$ cat .git/HEAD
ref: refs/heads/feature-qc
# 브랜치 전환 시 HEAD가 이동
$ git checkout main
$ cat .git/HEAD
ref: refs/heads/main
# detached HEAD 상태 (특정 커밋으로 이동)
$ git checkout a1b2c3d
$ cat .git/HEAD
a1b2c3d1234567890abcdef1234567890abcdef12
브랜치 생성과 관리
효과적인 브랜치 관리는 연구 프로젝트의 복잡도와 팀 규모에 따라 달라집니다. 생물정보학 프로젝트에서는 분석 방법별, 데이터셋별, 또는 연구 단계별로 브랜치를 구성할 수 있습니다.
# 브랜치 생성 방법들
git branch feature-alignment # 브랜치 생성 (전환하지 않음)
git checkout -b feature-alignment # 브랜치 생성 후 전환
git switch -c feature-alignment # Git 2.23+ 새로운 문법
# 특정 시점에서 브랜치 생성
git checkout -b hotfix-bug main # main에서 분기
git checkout -b experiment-v2 a1b2c3d # 특정 커밋에서 분기
# 브랜치 목록 확인
git branch # 로컬 브랜치만
git branch -a # 로컬과 원격 브랜치 모두
git branch -v # 마지막 커밋 정보와 함께
git branch --merged # 병합된 브랜치들
git branch --no-merged # 병합되지 않은 브랜치들
브랜치 명명 규칙:
# 생물정보학 프로젝트 브랜치 명명 예시
feature/rna-seq-pipeline # 새 기능 개발
bugfix/alignment-memory-leak # 버그 수정
experiment/deep-learning-model # 실험적 기능
analysis/patient-cohort-2024 # 특정 분석
data/gtex-v8-integration # 데이터 통합
config/cluster-optimization # 설정 개선
# 개인 작업 브랜치 (팀 작업 시)
john/methylation-analysis
mary/quality-control-update
브랜치 전환과 상태 관리:
# 안전한 브랜치 전환
git status # 현재 변경사항 확인
git stash # 작업 중인 변경사항 임시 저장
git checkout target-branch # 브랜치 전환
git stash pop # 저장된 변경사항 복원
# 변경사항이 있어도 강제 전환 (주의 필요)
git checkout -f target-branch # 변경사항 버리고 전환
# 현재 브랜치 확인
git branch --show-current # Git 2.22+
git rev-parse --abbrev-ref HEAD # 구버전에서 사용
머지 전략과 방법
Git은 세 가지 주요 머지 전략을 제공합니다: Fast-forward, Recursive (3-way merge), 그리고 Rebase. 각 전략은 서로 다른 상황과 팀 정책에 적합합니다.
# Fast-forward 머지 (선형 이력 유지)
# main: A---B
# feature: C---D
# 결과: A---B---C---D (main, feature)
git checkout main
git merge feature-branch # Fast-forward 가능 시 자동 적용
git merge --ff-only feature-branch # Fast-forward만 허용
# 3-way 머지 (병합 커밋 생성)
# main: A---B---E
# feature: C---D
# 결과: A---B---E---F (F는 병합 커밋)
# \ /
# C---D
git merge --no-ff feature-branch # 항상 병합 커밋 생성
git merge -m "Merge feature-qc into main" feature-qc
리베이스를 통한 선형 이력 유지:
# 리베이스 (커밋을 다른 베이스로 이동)
# Before:
# main: A---B---E
# feature: C---D
# After rebase:
# main: A---B---E
# feature: C'---D' (C, D가 E 이후로 이동)
git checkout feature-branch
git rebase main # feature 브랜치를 main 위로 재배치
# 대화형 리베이스 (커밋 편집)
git rebase -i HEAD~3 # 최근 3개 커밋 편집
git rebase -i main # main 이후의 모든 커밋 편집
# 리베이스 중 충돌 해결
git add resolved-file.py
git rebase --continue # 리베이스 계속
git rebase --abort # 리베이스 취소
스쿼시 머지 (여러 커밋을 하나로 압축):
# 방법 1: 머지 시 스쿼시
git checkout main
git merge --squash feature-branch # 모든 변경사항을 스테이징만
git commit -m "feat: Add quality control pipeline"
# 방법 2: 대화형 리베이스로 스쿼시
git checkout feature-branch
git rebase -i HEAD~4 # 최근 4개 커밋 압축
# 편집기에서 'pick' → 'squash' 또는 's'로 변경
충돌 해결
머지나 리베이스 과정에서 같은 파일의 같은 부분이 서로 다르게 수정된 경우 충돌이 발생합니다. 충돌 해결은 Git 사용에서 피할 수 없는 과정입니다.
# 충돌 발생 상황
$ git merge feature-alignment
Auto-merging scripts/pipeline.py
CONFLICT (content): Merge conflict in scripts/pipeline.py
Automatic merge failed; fix conflicts and then commit the result.
# 충돌 상태 확인
$ git status
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: scripts/pipeline.py
충돌 표시 형식:
# scripts/pipeline.py 파일 내용
def run_alignment(reads, reference):
"""RNA-seq read alignment function"""
<<<<<<< HEAD
# Use STAR aligner with default parameters
aligner = "STAR"
params = {"threads": 8, "memory": "32G"}
=======
# Use HISAT2 aligner for better performance
aligner = "HISAT2"
params = {"threads": 16, "memory": "16G"}
>>>>>>> feature-alignment
return align_reads(reads, reference, aligner, params)
충돌 해결 과정:
# 1. 충돌 파일 편집 (마커 제거 후 최종 버전 작성)
# 편집 후:
def run_alignment(reads, reference):
"""RNA-seq read alignment function"""
# Use HISAT2 aligner with optimized parameters
aligner = "HISAT2"
params = {"threads": 12, "memory": "24G"}
return align_reads(reads, reference, aligner, params)
# 2. 해결된 파일 스테이징
git add scripts/pipeline.py
# 3. 충돌 해결 완료
git commit # 기본 머지 메시지 사용
# 또는
git commit -m "Merge: Integrate HISAT2 alignment with optimized params"
충돌 해결 도구 활용:
# 3-way 머지 도구 사용
git mergetool # 설정된 도구로 충돌 해결
git mergetool --tool=vimdiff # 특정 도구 지정
# Git 내장 도구로 충돌 확인
git diff # 충돌 상태의 diff 표시
git log --merge # 충돌 관련 커밋만 표시
git show :1:filename # 공통 조상 버전
git show :2:filename # HEAD (현재 브랜치) 버전
git show :3:filename # 머지하려는 브랜치 버전
# 충돌 해결 취소
git merge --abort # 머지 취소하고 이전 상태로
git reset --hard HEAD # 모든 변경사항 취소
브랜치 워크플로우 패턴
팀의 규모와 프로젝트 특성에 따라 다양한 브랜치 워크플로우를 채택할 수 있습니다. 생물정보학 연구에서는 분석의 안정성과 재현성이 중요하므로 적절한 워크플로우 선택이 필수적입니다.
GitHub Flow (단순한 브랜치 모델):
# 1. 메인 브랜치에서 기능 브랜치 생성
git checkout main
git pull origin main
git checkout -b analysis/deseq2-update
# 2. 작업 후 푸시
git add -A
git commit -m "feat(analysis): Update DESeq2 analysis pipeline"
git push origin analysis/deseq2-update
# 3. Pull Request 생성 및 검토
# (GitHub 웹 인터페이스에서)
# 4. 검토 완료 후 메인으로 머지
git checkout main
git pull origin main # 최신 상태로 업데이트
git branch -d analysis/deseq2-update # 로컬 브랜치 삭제
Git Flow (복잡한 프로젝트용):
# 브랜치 구조:
# main: 프로덕션 릴리스
# develop: 개발 통합 브랜치
# feature/*: 기능 개발
# release/*: 릴리스 준비
# hotfix/*: 긴급 수정
# 새 기능 개발
git checkout develop
git checkout -b feature/rna-seq-v2
# ... 개발 작업 ...
git checkout develop
git merge --no-ff feature/rna-seq-v2
git branch -d feature/rna-seq-v2
# 릴리스 준비
git checkout develop
git checkout -b release/v2.1.0
# ... 버그 수정, 문서 업데이트 ...
git checkout main
git merge --no-ff release/v2.1.0
git tag v2.1.0
git checkout develop
git merge --no-ff release/v2.1.0
연구 프로젝트용 워크플로우:
# 브랜치 구조:
# main: 검증된 안정 버전
# develop: 개발 통합
# experiment/*: 실험적 분석
# data/*: 새로운 데이터셋 처리
# paper/*: 논문별 분석
# 실험적 분석 브랜치
git checkout develop
git checkout -b experiment/machine-learning-classifier
# 논문용 분석 브랜치 (특정 시점에서 분기)
git checkout -b paper/nature-genetics-2024 v2.1.0
# ... 논문에 사용된 정확한 분석 보존 ...
# 데이터셋별 브랜치
git checkout -b data/tcga-integration develop
원격 브랜치 관리
팀 협업에서는 로컬 브랜치와 원격 브랜치 간의 동기화가 중요합니다.
# 원격 브랜치 확인
git branch -r # 원격 브랜치만
git branch -a # 로컬과 원격 모두
git remote show origin # 원격 저장소 상세 정보
# 원격 브랜치 추적
git checkout -b local-branch origin/remote-branch # 원격 브랜치 추적
git checkout --track origin/remote-branch # 동일한 이름으로 추적
git branch -u origin/remote-branch local-branch # 기존 브랜치에 추적 설정
# 원격 브랜치 동기화
git fetch origin # 원격 정보 업데이트
git fetch --prune # 삭제된 원격 브랜치 정보 정리
git pull origin main # 특정 브랜치 가져와 머지
git push origin feature-branch # 로컬 브랜치를 원격으로 푸시
# 원격 브랜치 삭제
git push origin --delete old-feature # 원격 브랜치 삭제
git branch -d old-feature # 로컬 브랜치 삭제
Practice Section: 브랜치와 머지 실습
실습 1: 기본 브랜치 생성과 전환
cd ~/bioproject
# 새 기능 브랜치 생성
git checkout -b feature-quality-control
git branch --show-current
# 간단한 작업
echo "def quality_check(): pass" > scripts/qc.py
git add scripts/qc.py
git commit -m "feat(qc): Add quality control module"
# 메인 브랜치로 돌아가기
git checkout main
git branch -v
실습 2: Fast-forward 머지
# 메인에서 기능 브랜치 머지
git merge feature-quality-control
git log --oneline -3
# 브랜치 정리
git branch -d feature-quality-control
git branch
실습 3: 3-way 머지 시나리오
# 메인에서 추가 작업
echo "version = '1.1'" > scripts/version.py
git add scripts/version.py
git commit -m "feat: Add version information"
# 새 브랜치에서 다른 작업
git checkout -b feature-config
echo "config = {'debug': True}" > scripts/config.py
git add scripts/config.py
git commit -m "feat: Add configuration module"
# 메인으로 돌아가서 머지
git checkout main
git merge --no-ff feature-config -m "Merge config feature"
git log --oneline --graph -5
실습 4: 충돌 해결 연습
# 두 브랜치에서 같은 파일 수정
git checkout -b branch-a
echo "method = 'fastqc'" > scripts/qc.py
git add scripts/qc.py
git commit -m "Use FastQC method"
git checkout main
echo "method = 'multiqc'" > scripts/qc.py
git add scripts/qc.py
git commit -m "Use MultiQC method"
# 충돌 머지 시도
git merge branch-a
# 충돌 해결 후:
echo "method = 'fastqc_and_multiqc'" > scripts/qc.py
git add scripts/qc.py
git commit -m "Merge: Use both QC methods"
실습 5: 브랜치 정리
# 브랜치 현황 확인
git branch -v
git branch --merged
# 불필요한 브랜치 삭제
git branch -d branch-a
git branch -d feature-config
# 최종 상태 확인
git log --oneline --graph
git branch
핵심 정리
브랜치 관리 필수 명령어
# 브랜치 생성/전환
git checkout -b new-branch # 생성 후 전환
git switch -c new-branch # Git 2.23+ 새 문법
git branch new-branch # 생성만
# 머지
git merge branch-name # 브랜치 머지
git merge --no-ff branch # 항상 머지 커밋 생성
git merge --squash branch # 스쿼시 머지
# 브랜치 정리
git branch -d branch-name # 브랜치 삭제
git branch --merged # 머지된 브랜치 확인
생물정보학 브랜치 전략
# 브랜치 명명 규칙
feature/pipeline-optimization # 기능 개발
experiment/deep-learning # 실험적 분석
data/gtex-integration # 데이터 통합
paper/nature-2024 # 논문별 분석
bugfix/memory-leak # 버그 수정
# 안전한 머지 패턴
git checkout main && git pull # 최신 상태 확인
git merge --no-ff feature # 머지 이력 보존
git branch -d feature # 정리