🔥 git merge

677자
9분

git merge 명령어는 여러 브랜치의 작업을 하나로 통합하는 데 사용됩니다. 브랜치를 통한 병렬 개발 후, 최종적으로 한 브랜치에 모든 변경 사항을 통합하는 과정은 매우 중요합니다.

git merge의 기본

git merge 명령어는 두 개의 브랜치를 병합합니다. 보통은 피처 브랜치(feature branch)의 변경 사항을 메인 브랜치(main branch)에 병합합니다.

# main 브랜치로 전환
git checkout main
 
# feature 브랜치 병합
git merge feature-branch
shell

이 명령은 feature-branch의 변경 사항을 main 브랜치에 병합합니다.

병합 충돌 해결하기

병합 과정에서 충돌(conflict)이 발생할 수 있습니다. 이 경우, 충돌이 발생한 파일을 열어 수동으로 충돌을 해결하고, 변경 사항을 커밋해야 합니다.

# 충돌 해결 후 파일 추가
git add [파일명]
 
# 충돌 해결 커밋
git commit -m "Resolve merge conflict"
shell

Fast-forward 병합

Fast-forward 병합은 병합 대상 브랜치의 모든 커밋이 현재 브랜치의 커밋 이후에 위치할 때 사용되는 방법입니다. 이 경우, Git은 단순히 현재 브랜치의 포인터를 병합 대상 브랜치의 최신 커밋으로 이동시킵니다.

# Fast-forward 병합
git checkout main
git merge feature-branch
shell

Fast-forward 병합은 별도의 병합 커밋을 생성하지 않기 때문에 히스토리가 선형적으로 유지됩니다. 이는 히스토리를 간단하고 깨끗하게 유지할 수 있게 해줍니다.

그러나, 이 방식의 단점은 브랜치의 존재와 작업 히스토리가 사라진다는 것입니다. 따라서 특정 기능 개발이나 버그 수정의 과정을 히스토리에서 추적하고 싶을 때는 non-fast-forward 병합을 고려해야 할 수 있습니다.

Fast-forward 병합은 주로 작은 변경 사항이나 긴급한 버그 수정에 적합하며, 복잡한 기능 개발이나 여러 사람이 참여하는 프로젝트에서는 non-fast-forward 병합이 더 적합할 수 있습니다.

Non-fast-forward 병합

Non-fast-forward 병합은 두 브랜치가 서로 다른 커밋 이력을 가진 경우 사용되는 병합 방법입니다. 이 과정에서는 새로운 '병합 커밋'(merge commit)이 생성되어, 두 브랜치의 이력이 모두 보존됩니다.

# Non-fast-forward 병합 옵션 사용
git checkout main
git merge --no-ff feature-branch
shell

이 명령어는 main 브랜치에 feature-branch를 병합할 때, 병합 커밋을 생성합니다. 이 커밋은 두 브랜치의 차이점을 모두 포함하며, 브랜치의 이력을 명확하게 보여줍니다.

Non-fast-forward 병합의 장점은 브랜치의 커밋 이력을 명확하게 유지하면서 팀원들이 작업한 내용을 추적하기 쉽다는 것입니다. 특히, 여러 사람이 참여하는 큰 프로젝트나 복잡한 기능 개발에 적합합니다.

그러나, 이 방식은 커밋 히스토리가 복잡해질 수 있으므로, 프로젝트의 관리 방식이나 팀의 선호도에 따라 적절한 병합 방식을 선택하는 것이 중요합니다. Non-fast-forward 병합은 프로젝트의 이력을 보다 상세하게 기록하고 싶을 때 유용하게 사용될 수 있습니다.

Squash 병합

Squash 병합은 여러 커밋을 하나의 커밋으로 압축하여 메인 브랜치에 병합하는 방법입니다. 이 방식은 피처 브랜치의 변경 이력을 간결하게 유지하면서 메인 브랜치에 통합할 때 유용합니다.

# Squash 병합을 위한 준비
git checkout main
git merge --squash feature-branch
 
# Squash 병합 후 커밋
git commit -m "Integrate feature-branch changes"
shell

Squash 병합을 사용하면 feature-branch의 모든 커밋이 하나의 커밋으로 메인 브랜치에 추가됩니다. 이는 메인 브랜치의 커밋 히스토리를 깔끔하게 유지하는 데 도움이 됩니다.

하지만, 이 방식은 개별 커밋의 세부적인 이력을 잃게 되므로, 어떤 상황에서 squash 병합을 사용할지 신중하게 결정해야 합니다. 일반적으로, 작은 기능이나 버그 수정과 같이 단일 목적을 가진 브랜치에 적합합니다.

병합 전략 선택하기

Git에서 효과적인 병합 전략을 선택하는 것은 프로젝트의 유지 관리와 팀 작업의 효율성에 큰 영향을 미칩니다. 다양한 병합 전략 중 가장 적합한 것을 선택하려면 프로젝트의 특성과 팀의 작업 방식을 고려해야 합니다.

  1. Fast-forward 병합: 이 방식은 간단하고 깨끗한 히스토리를 유지하고자 할 때 적합합니다. 특히, 작은 변경이나 단기 프로젝트에 유리합니다.
  2. Non-fast-forward 병합: 복잡한 프로젝트나 여러 사람이 참여하는 경우, 각 브랜치의 상세한 이력을 보존하고 싶다면 이 방법이 좋습니다. 이는 추후 코드의 변경 이유와 역사를 명확히 파악하는 데 도움이 됩니다.
  3. Squash 병합: 이 방식은 메인 브랜치의 히스토리를 간결하게 유지하고자 할 때 사용됩니다. 여러 커밋을 하나로 압축하여 병합하므로, 메인 브랜치의 로그가 깔끔해집니다. 그러나, 개별 커밋의 상세 정보는 손실됩니다.
  4. Rebase 사용: Rebase는 병합과는 다른 접근 방식이지만, 히스토리를 선형으로 유지하면서 브랜치의 변경 사항을 메인 브랜치에 통합할 수 있습니다. 이 방법은 병합 충돌을 최소화하고, 히스토리를 더욱 깔끔하게 유지할 수 있습니다.

각각의 전략은 장단점을 가지고 있으므로, 프로젝트의 요구사항과 팀의 작업 방식에 따라 적절한 전략을 선택하는 것이 중요합니다. 예를 들어, 깨끗한 히스토리를 선호하는 팀은 squash 병합을, 상세한 히스토리를 선호하는 팀은 non-fast-forward 병합을 선택할 수 있습니다. 프로젝트의 성격과 팀원들의 의견을 충분히 고려하여 가장 적합한 병합 전략을 결정해야 합니다.

연습문제

  1. 두 개의 브랜치를 생성하고 각각 다른 변경 사항을 커밋한 후, 하나의 브랜치에 병합해보세요.
  2. 병합 과정에서 충돌이 발생했을 때 충돌을 해결하고 병합을 완료하는 과정을 연습해보세요.
  3. Fast-forward 병합과 Non-fast-forward 병합의 차이를 실험해보세요.
  4. 병합 전략 중 하나를 선택하여 적용해보고, 그 결과를 분석해보세요.