pull request(PR)
을 할 때 merge 옵션이 있다
여기서 옵션들은 merge의 옵션들과 같다
Create a merge commit -> git merge <branch> --no-ff
Squash and merge -> git merge <branch> --squash
Rebase and merge -> git rebase <branch>
세가지를 비교를 비교해보기 위해 상황이 다음과 같다고 가정하자
위와 같은 상황에서 긴급한 버그 수정을 위해 Hotfix
가 Master
로부터 분기하여 작업을 두개(Commit 2개) 진행했다고 가정
master > git log
* 03c0e57 (Hotfix) fix bugB
* 1693ca1 fix bugA
* a7ee0c1 (HEAD -> master, origin/master) base commit
git merge --no-ff
를 알기 위해선 --ff
를 알아야한다
-ff
는 fast-forward 의 줄임말로써 빨리감기라는 뜻이다
git merge --ff
를 할 경우master > git merge Hotfix --ff
Updating a7ee0c1..03c0e57
Fast-forward
master > git log
* 03c0e57 (HEAD -> master, Hotfix) fix bugB
* 1693ca1 fix bugA
* a7ee0c1 (origin/master) base commit
Master
의 log에는 Hotfix
의 커밋들만 추가되고 따로 추가되는 commit은 없다
-ff
는 git merge
의 기본 옵션이기때문에 git merge
와 git merge --ff
는 같은 뜻이다
다른 옵션도 테스트하기 위해 git reset --hard <돌아가려는 workspace>
master > git reset --hard origin/master
HEAD is now at a7ee0c1 base commit
master > git log
* 272c460 (Hotfix) fix bugB
* 252a393 fix bugA
* 498325c testC.txt
* a7ee0c1 (HEAD -> master, origin/master) base commit
git merge --no-ff
를 할 경우master
에 변경이력이 없어도 fast-farward
를 하지 않고 no-fast-farward
를 한다
no-fast-farward
: master
의 log에는 Hotfix의 작업내역 commit 2개와 병합commit(Merge ~ from
)이 기록
master > git merge Hotfix --no-ff // merge내용 작성
Merge made by the 'recursive' strategy.
master > git log
* 842db67 (HEAD -> master) Merge branch 'Hotfix'
|\
| * 03c0e57 (Hotfix) fix bugB
| * 1693ca1 fix bugA
|/
* a7ee0c1 (origin/master) base commit
이 때, 만들어진 commit(Merge branch 'Hotfix'
)는 2개의 Parent(Hotfix
, master
)를 갖는다
--ff
를 적용이 안되고 --no-ff
로 적용되는 경우하지만 --ff
로 옵션을 주어도 --no-ff
로 적용이 되는 경우가 있다
hotfix
가 작업을 하는동안 master
에 변경 내역이 있는 경우 master > vi testC.txt
master !1 > git add .
master +1 > git commit -m "testC.txt"
master > git log
* | 00c9de9 (HEAD -> master) testC.txt
| * 03c0e57 (Hotfix) fix bugB
| * 1693ca1 fix bugA
|/
* a7ee0c1 (origin/master) base commit
master > git merge Hotfix --ff
// Merge branch 'Hotfix'
master > git log
* 1925dd0 (HEAD -> master) Merge branch 'Hotfix'
|\
* | 00c9de9 testC.txt
| * 03c0e57 (Hotfix) fix bugB
| * 1693ca1 fix bugA
|/
* a7ee0c1 (origin/master) base commit
--no-ff
로 적용이 된다
squash란 영단어 뜻 그대로 뭉개다 라는 뜻이다
master
에 Hotfix
의 commit들이 반영되지않고 새 commit만 반영된다
master > git merge --squash Hotfix
Updating a7ee0c1..03c0e57
Fast-forward
Squash commit -- not updating HEAD
testA.txt | 2 +-
testB.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
// squash는 commit이 생성되지않고 Staged상태만 된다
// commit 추가
master +2 > git add .
master +2 > git commit -m "fix bugA,B"
[master 48975f6] fix bugA,B
2 files changed, 2 insertions(+), 2 deletions(-)
master > git log
* 48975f6 (HEAD -> master) fix bugA,B
| * 03c0e57 (Hotfix) fix bugB
| * 1693ca1 fix bugA
|/
* a7ee0c1 (origin/master) base commit
이 떄, fix bugA,B
의 parent는 한개(master
)이다
rebase
란 모든 commit이 합쳐지지 않고 각각 master에 추가된다
rebase
의 기능을 알기 위해서 master
를 base commit
으로 reset
한뒤 작업변경을 하고 testC.txt
commit을 추가한다
master > git reset --hard origin/master
HEAD is now at a7ee0c1 base commit
master > vi testC.txt
master !1 > git add .
master +1 > git commit -m "testC.txt"
[master 498325c] testC.txt
1 file changed, 1 insertion(+), 1 deletion(-)
master > git log
498325c (HEAD -> master) testC.txt
| * 03c0e57 (Hotfix) fix bugB
| * 1693ca1 fix bugA
|/
* a7ee0c1 (origin/master) base commit
현재상태
rebase 작업 진행
master > git checkout Hotfix
Switched to branch 'Hotfix'
Hotfix > git rebase master
First, rewinding head to replay your work on top of it...
Applying: fix bugA
Applying: fix bugB
Hotfix > git checkout master
Switched to branch 'master'
master > git merge Hotfix
Updating 498325c..272c460
Fast-forward
testA.txt | 2 +-
testB.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
master > git log
* 272c460 (HEAD -> master, Hotfix) fix bugB
* 252a393 fix bugA
* 498325c testC.txt
* a7ee0c1 (origin/master) base commit
fix bugA
, fix bugB
는 Hotfix
에서 작업한 commit의 내용이지만 commit의 id를 보면 다른 것을 확인 할 수 있다
rebase
의 경우 자칫 잘못하면 엉켜버릴수가 있다.sqaush
: master
에 Hotfix
이 commit 2개(commit A
,commit B
)를 PR요청하고 squash
로 merge했다고 가정Hotfix
가 추가작업(commit C
, commit D
)을 하고 또 PR을 보내면 4개의 커밋(commit A
, commit B
, commit C
, commit D
)이 PR내역에 포함되어 보내진다. 과거에 했던 commit (commit A
, commit B
)이 포함되는 문제가 있다merge
: 그냥 merge
를 사용할 경우 sqaush
의 위 문제점이 발생하지않고 작업했던 내역들만 PR 요청을 할 수 있다. 하지만 Hotfix
의 commit(commit C
, commit D
)들이 전부 master
의 log의 올라간다.-squash
는 한개의 commit(위 예제경우 fix bugA,B
)만 master
에 올라간다. commit A
, commit B
는 PR 내역을 들어가면 볼 수있다.결론
squash
merge --no-ff
develop
와 진짜 너무 감사합니다! 복받으실겁니다