1. 병합(Merge)

  • 개념: 독립된 브랜치에서 개발 작업이 끝난 후, 원본 브랜치(master 등)에 작업 결과를 반영하여 하나로 합치는 작업이다.

  • 방식

    • 수동 병합: 사람이 직접 코드를 한 줄씩 비교하며 합치는 방식 (어렵고 오류 발생 가능성 높음)
    • 자동 병합(Git): 도구를 사용하여 변경 이력을 비교해 자동으로 코드를 합친다.
  • 원리: Git은 브랜치를 기준으로 병합하며, 두 파일의 변경 이력을 비교하여 처리한다.

2. Fast-Forward 병합

  • 정의: ‘빨리 감기’라는 의미로, 가장 간단한 병합 방식이다.
  • 조건: 기준 브랜치(예: master)에서 분기된 이후, 기준 브랜치에 추가적인 커밋이 없을 때 발생한다.
  • 동작: 기준 브랜치의 포인터(HEAD)를 단순히 병합 대상 브랜치의 최신 커밋으로 이동시킨다.
  • 특징: 별도의 병합 커밋(Merge Commit)이 생성되지 않고 히스토리가 선형(일직선)으로 유지된다.

3. 3-way 병합

  • 정의

    • 두 브랜치 모두 변경 사항이 생겼을 때 사용하는 병합 방식이다.
    • 협업 시 가장 일반적인 형태이다.
  • 조건: 기준 브랜치와 대상 브랜치 모두 각자 새로운 커밋이 존재할 때 발생한다.

  • 동작

    1. 두 브랜치의 공통 조상 커밋(Base)을 찾는다.
    2. 공통 조상, 내 브랜치, 대상 브랜치 3개의 커밋을 비교한다.
    3. 두 브랜치의 변경 사항을 모두 포함하는 새로운 병합 커밋(Merge Commit)을 생성한다.
  • 특징: 병합 커밋은 부모 커밋이 2개이며, 그래프 상에서 두 갈래가 하나로 합쳐지는 모양이 된다.

3.1. Fast-Forward 병합 vs 3-way 병합

  • Fast-Forward 병합

    • 병합하려는 두 브랜치가 일직선상에 있을 때
    • 기준 브랜치의 포인터(HEAD)만 최신 커밋으로 이동한다.
    • 별도의 병합 커밋이 생성되지 않는다.
  • 3-way 병합

    • 병합하려는 두 브랜치가 갈라져서 서로 다른 작업을 했을 때
    • 3개의 커밋(공통 조상(Base), 기준 브랜치, 대상 브랜치)을 비교한다.
    • 새로운 병합 커밋이 생성된다.

4. 브랜치 삭제

  • 필요성

    • 병합이 완료되어 더 이상 필요 없거나, 중복되는 브랜치는 저장소 정리를 위해 삭제한다.
  • 명령어

    • git branch -d [브랜치명]: 병합이 완료된 브랜치만 삭제 (안전)
    • git branch -D [브랜치명]: 병합 여부와 관계없이 강제 삭제

5. 충돌(Conflict)

  • 발생 원인

    • 3-way 병합 과정에서, 두 브랜치가 동일한 파일의 동일한 위치를 서로 다르게 수정했을 때 Git이 자동으로 병합하지 못하고 발생한다.
  • 해결 과정

    1. Git이 충돌이 난 파일에 충돌 기호(<<<<<<, ======, >>>>>>)를 표시하고 병합을 중단한다.
    2. 사용자가 직접 해당 파일을 열어 충돌 부분을 수정(선택)한다.
    3. 수정 완료 후 스테이지에 등록(add)하고 커밋(commit)하여 병합을 완료한다.

6. 브랜치 병합 여부 확인

  • 다수의 브랜치를 관리할 때 병합 상태를 확인하는 명령어이다.
    • git branch --merged: 현재 브랜치에 병합된 브랜치 목록 표시 (삭제해도 안전)
    • git branch --no-merged: 아직 병합되지 않은 브랜치 목록 표시

7. 리베이스(Rebase)

  • 개념

    • 브랜치의 베이스(조상 커밋)를 변경하여, 마치 처음부터 그곳에서 파생된 것처럼 커밋 히스토리를 재정렬하는 것이다.
  • 목적

    • 복잡한 병합(Merge) 로그 대신, 선형적이고 깔끔한 커밋 히스토리를 만들기 위해 사용한다.
  • 특징

    • 기존 커밋들을 새로운 베이스 위로 재배치하므로 커밋 해시(ID)가 변경된다.
    • Interactive Rebase(-i 옵션): 커밋 순서 변경, 커밋 합치기(squash), 메시지 수정 등 커밋 히스토리를 편집할 수 있다.
  • 주의사항

    • 이미 원격 저장소에 Push되어 공유된 커밋은 리베이스하면 안 된다. (협업 시 혼란 초래)
    • 충돌 발생 시 해결 후 --continue로 진행한다.

7.1. 병합(Merge) vs 리베이스(Rebase)

  • 한 브랜치에서 다른 브랜치로 합치는 방법
    • git merge [가져올 브랜치]
    • git rebase [새로 베이스가 될 브랜치]
구분병합 (Merge)리베이스 (Rebase)
히스토리 형태분기되었다가 합쳐지는 모양 (보존)**한 줄(Linear)**로 깔끔하게 정리
커밋 ID (Hash)기존 커밋 ID 유지새로운 커밋 ID 발급 (재배치되므로)
기준점(Base)변경 없음브랜치의 시작점(Base)을 최신 커밋으로 변경
주 사용 목적이력 보존, 협업 시 일반적로컬 작업 정리, 깔끔한 히스토리 유지

8. 정리

  • 협업 시 충돌은 필연적으로 발생한다.
  • 충돌을 최소화하기 위해서는 master(원본) 브랜치의 변경 사항을 내 브랜치로 자주 가져와서(병합/리베이스) 반영하며 작업하는 것이 좋다.
  • 원격 저장소의 상태를 지속적으로 모니터링하는 습관이 중요하다.

Dev.

cf. 커밋 메시지의 변경

# 가장 최근(마지막) 커밋 메시지 변경
git commit --amend
git commit --amend -m "새로운 커밋 메시지"
 
# 이전 또는 여러 개의 커밋 메시지 변경
git rebase -i HEAD~3  # 현재 커밋 포함 이전 3개의 커밋