티스토리 뷰

Git

[Git] Git merge 방법

CharlieZip 2021. 8. 9. 01:47
반응형

Git을 사용하다 보면 자주 Merge를 사용하게 되는데요.

Merge의 다양한 방법과 그로 인해 git log가 어떤식으로 변하는지 살펴보겠습니다.

먼저 Merge에 대한 이해를 쉽게 하기 위해 다음과 같은 환경에서 테스트하겠습니다.

  • Local 환경에서만 Git을 사용
  • Confilct가 발생하는 하는 경우는 고려하지 않음
  • 기본적인 git command(add, commit, branch) 명령어 설명은 생략하겠습니다.

제가 사용할 git log 명령어입니다.

$ git log --all --graph --oneline
# --all 로그 전체를 보여준다
# --graph 그래프형식을 이용해 표현해준다
# --oneline 한 커밋당 한줄로 표현해준다.

다양한 log 명령어가 궁금하시다면 여기를 참고해보세요!

 

[ merge-v1 기본 Merge ]

환경세팅

먼저 우리가 아는 기본적인 merge를 해보겠습니다.

$ git checkout master
$ git merge merge-v1

결과

그냥 merge를 수행하면 새로운 커밋이 하나 추가되며 합쳐지는 걸 볼 수 있습니다.

merge를 완료한 branch는 삭제

$ git branch -d merge-v1

하지만 현재는 하나의 브랜치에서만 merge를 했지만

만약 여러개의 브랜치가 있고, 여러 브랜치에서 merge를 수행한다고 생각하면 우리의 깃 로그 기록이 매우 복잡해 질거라는걸 상상해 볼 수 있습니다.

깃 로그가 복잡해지면 나중에 유지보수측면이나, 프로젝트를 이해할 때 많은 불편함을 겪을 수 있습니다.

그래서 좀더 깃 로그를 깔끔하게 정리하면 'merge' 할 수 있는 다른 방법들을 알아보겠습니다.

 

 

[ merge-v2 Rebase Merge ]

환경세팅

rebase 명령어를 실행하고 결과를 보면서 설명을 하겠습니다.

$ git checkout merge-v2
$ git rebase master

결과

rebase 명령어를 실행하면 실제 동작하는 방식은

  1. 두 브랜치가 나뉘기 전인 공통 커밋 work 3로 이동한뒤
  2. 지금 checkout 한 브랜치(merge-v2)가 가리키는 커밋까지 diff를 차례로 만들어 저장해 놓는다.
  3. rebase 할 브랜치(merge-v2)가 합칠 브랜치(master)가 가리키는 커밋을 가리키게 하고 아까 저장해 놓았던 변경사항을 차례대로 적용한다.

하지만 이 동작하는 방식을 한번에 이해하기란 쉽지 않습니다.

쉽게 생각해보자면 merge-v2 에 있는 커밋을 master가 가리키는 work 4 커밋부터 하나씩 merge를 한다고 생각하면 됩니다.

  1. work 4 커밋과 merge-v2 work 1 커밋이 merge 한다. 충돌이 일어나지 않기 때문에 바로 병합된다.
  2. merge-v2 work 1 커밋과 merge-v2 work 2 커밋이 merge 한다.

rebase 명령어는 rebase 할 브랜치(merge-v2)의 커밋 수 만큼 새로운 커밋이 추가됩니다.

지금 깃 로그를 보니 master 브랜치는 work 4 커밋을 가리키고 있다.

우리가 생각하는 건 master 브랜치가 merge-v2 work 2 를 가리키게 하는 것입니다.

rebase 한 merge-v2를 master 브랜치랑 합쳐 줍시다.

master 브랜치 Fast-forward

$ git checkout master
$ git merge merge-v2

드디어 우리가 원하는 결과가 나왔다.

rebase 명령어는 좀 더 복잡하지만 깃 로그를 봤을때 merge-v1 보다 훨씬 깔끔한걸 볼 수 있다.

주의
rebase는 merge와 반대로 git checkout merge-v2 를 통해 merge-v2 브랜치로 가서 rebase 명령어를 실행했다.
rebase는 자기자신 브랜치를 변경하는 명령어 이므로 꼭 헷갈리지 말고 실행할려는 branch로 checkout 한뒤 사용하도록 하자.

현재는 Local환경에서만 하는거라 문제가 없지만, github 같은 remote 환경도 같이 사용하고 있다면 rebase를 함부로 사용하면 안된다.

딱, 한가지 규칙만 명심하면 된다. remote 저장소로 push 한 커밋은 rebase 하지 않는다.

왜 그런지 이유가 궁금하신 분들은 여기 링크에서 Ctrl+F로 '위험성' 이라 검색해서 읽어보시길 추천드립니다.

 

 

[ merge-v3 Squash Merge ]

rebase를 사용하니 깃로그가 깔끔해졌다.

하지만 뭔가 아쉬운 부분이 있습니다. 만약 rebase 하는 브랜치에 커밋이 100개가 있다면 rebase 후에 새로 커밋이 100개가 추가됩니다. 하지만 우리는 100개의 커밋 추가하고 싶지 않고 딱 하나의 커밋으로 합치고 싶다.

그럴때는 squash라는 명령어를 사용하면 된다.

환경세팅

$ git checkout master
$ git merge --squash merge-v3
Automatic merge went well; stopped before committing as requested
Squash commit -- not updating HEAD

squash 명령어를 사용하면 자동 병합이 완료되지만 새로운 커밋을 update 해주지는 않습니다.

추가적으로 commit을 실행해 줘야 합니다.

$ git commit -m "squash merge complete"

결과

Merge-v3브랜치의 3개의 커밋이 한개로 합쳐져서 merge 된걸 볼 수 있습니다.

다만, merge —squash 는 Merge-v3 의 변경사항이 그대로 남아있습니다.

또한 커밋을 하나로 모두 줄여 깔끔하게 합칠 수 있는 장점이 있지만 무분별하게 'squash' 를 사용해서는 안됩니다.

보통 팀의 동의가 있고 'squash'를 했을때 이득이 있을 경우에만 사용하는 것이 좋습니다.

반대로 커밋 로그가 남아있길 원한다면 이 방법을 사용해서는 안됩니다.

[ 커밋 압축하기 ]

추가로 여러개의 커밋을 하나의 커밋으로 합칠 수 있습니다.

$ git rebase -i HEAD~N  # N은 합칠 커밋의 수

HEAD~3을 할 경우 3개의 커밋을 합칠 수 있습니다.

환경설정

제일 최근 work 9, work 8, work 7 세개의 커밋을 한번 합쳐보겠습니다.

$ git rebase -i HEAD~3

를 입력하면 이러한 창이 뜨게 됩니다.

rebase에는 여러가지 명령어가 있는데 저희는 squash를 사용하겠습니다.

 

 

pick → squash 로 변경해 줍니다.

squash로 변경한 커밋들은 합쳐줄 것입니다.

 

 

다음으로 넘어가면 빨간부분에 새로 저장할 커밋 메시지를 작성하면 됩니다.

 

 

실제로 커밋 work 7, work 8, work 9 가 합쳐져 하나의 rebase squash 3 to 1 커밋으로 바뀐걸 확인할 수 있습니다.

또한 이 방법을 사용해 미리 커밋을 합친후 merge 를 하는 방법도 가능합니다.

 

부족한 제 글 읽어주셔서 감사합니다. 오늘도 좋은 하루 되세요!!

반응형

'Git' 카테고리의 다른 글

[Git] password authentication 에러  (0) 2021.08.14
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함