Git Merge vs Rebase

October 27, 2023


git은 서로 다른 작업을 하기 위한 별도의 공간을 생성할 때, 브랜치를 생성할 수 있습니다.

각자 작업한 사항을 하나로 합칠 때, 합치는 방법으로는 merge와 rebase가 있습니다.

Merge

진행 과정

  1. 기능 구현을 위해서 해당 기능을 구현하기 위한 브랜치를 생성

  2. 기능 구현이 되는 경우, 해당 기능을 main 브랜치에 merge 함

git checkout main
git merge branch-1

Fast-forward

가리키고 있던 commit을 merge할 브랜치의 commit으로 이동하는 것이 fast-forward입니다.

두 브랜치의 base가 같을 때, 최신 버전을 따라가는 것!

base가 다른데 merge한다면?

git fetch upstream main
git merge upstream/main

base가 다른데 merge하는 경우, git은 자동으로 새로운 merge commit을 새로 만듭니다. 바로 merge remote-tracking branch라는 commit을 생성합니다.

즉, git이 별도의 최적 공통 조상을 자동으로 찾고, feat 브랜치가 해당 commit을 가리키도록 변경합니다.

Conflict

만약 로컬과 원격 모두 같은 파일을 수정해서 자동 merge를 할 수 없는 경우, 이를 conflict이라고 합니다.

충돌이 발생한 파일을 가면 HEAD(현재 브랜치), 아래가 merge할 브랜치로, 두 파일의 충돌 사항을 볼 수 있으며, 이를 수정해야 합니다.

수정 후, 이 파일을 git add하면, 충돌이 해소되어 이전과 마찬가지로 자동적으로 merge commit이 정상적으로 생성됩니다.

Github의 3 가지 Merge 방식

1. Create merge commit

create and merge

Fast-forward를 하는 것이 아니라, 하나의 merge commit을 생성해서 merge를 진행

2. Squash and Merge

squash and merge

하나의 merge commit을 생성해서, 해당 commit을 가리키도록 함

feature에서 작업했던 모든 commit들을 하나의 commit으로 통합해서 merge를 진행

그래서, 한 기능에 commit이 너무 많은 경우, 특정 기능에 대한 commit을 하나만 두어서 가독성이 좋아질 수 있음

PR 단위마다 해당 commit이 이름으로 작성되어서 누가 작업했는지 보기 쉽습니다.

git checkout main
git merge --squash feature
git commit -m "squash merge message"

3. Rebase and Merge

rebase and merge

feature에서 작업한 사항들을 main 브랜치로 최상단에 복사 붙여넣기 하는 작업

한 줄로 모든 commit이 저장되어 오히려 더 난잡해 보일 수 있습니다.

git checkout feature
git rebase master

git checkout master
git merge feature

Rebase

방식 설명
Merge 브랜치를 합침
Rebase Merge보다 깨끗한 commit history를 만듦
commit history가 merge와 다르게 선형적으로 그려짐

현재 branch의 Base를 재설정(변경)하여 합치는 것입니다.

주의해야 할점은 그냥 Base 포인터만 바뀌는 것이 아니라, Base가 바뀔 commit 들을 복사하여 연이어 붙이는 것입니다.

merge를 한 코드 결과와 rebase를 한 결과는 같아야 합니다.

원격 저장소로 올라간 commit을 rebase하는 경우, 같은 commit이지만 id가 달라져서 비권장된다고 합니다.

Cherry pick

원하는 변경점만 고를 수 있습니다.

  1. main에 직접 push
git checkout main
git cherry-pick <commit id>
git push origin main
  1. 브랜치를 생성 후, 해당 브랜치에서 cherry-pick 진행

main 브랜치로의 merge PR을 요청한 후,

git checkout main
git checkout -b <생성할 브랜치 이름>
git cherry-pick <commit id>
git push origin cherry
  • 여러 개 가져오고 싶은 경우

    공백으로 구분하여 여러 commit들 지정 가능

    git cherry-pick 29dk349 18fef123 38sdf192
  • 특정 구간에 연속된 commit들을 가져오는 경우

    git cherry-pick 29dk349..38sdf192

conflict가 발생하면?

  1. 충돌 해결을 위해 코드를 수정
  2. git add 명령어로 수정된 코드를 add
  3. git cherry-pick --continue 명령을 수행

주의할 점으로는 같은 commit 이름이 생겨서 알아보기 어려울 수도 있습니다.

참조

[10분 테코톡] 오리&코린의 Merge, Rebase, Cherry pick


Profile picture

이재원

이해하기 쉬운 코드를 작성하려 고민합니다.


© 2024 Won's blog Built with Gatsby