git merge와 rebase 이해하기

개발자는 회사에서 가장 많이 사용하는 공통적인 기술은 단언컨데 Git이라 할 수 있습니다.

형상관리는 어떤 팀에도 코드를 작성한다면 필수적으로 사용하는 데 함께 일을 하기 때문에 특히 많이 사용하곤 합니다.

오늘은 그 중에서 git merge에 대한 내용을 다뤄보겠습니다.

Git Merge 이해하기

보통 Git을 혼자 사용한다면 Merge 보다는 branch 관리, commit, push와 pull과 같은 명령어를 많이 사용합니다. 하지만 함께 일을 시작한다면 Git Merge를 참 많이 사용합니다.

git merge는 여러 명이 공동으로 작업하는 repository를 받아 작업할 때 사용합니다.

예를 들어보죠.

Git Merge 명령어 사용 예시

보통 회사에서 새로운 기능을 만들 때 main이나 dev에서 새로운 branch를 만듭니다.

01 A forked commit history
git merge와 rebase 이해하기 6

그 다음 branch에서 기능을 개발하고, 완료를 합니다. 그러면 다시 dev나 main에 코드를 합쳐야 합니다

이럴 때 Git Merge 명령어를 사용하게 됩니다.

02 Merging main into the feature branh
git merge와 rebase 이해하기 7
git branch new-branch // branch 생성
git checkout new-branch // branch 이동

/* 작업을 완료한 뒤 */
git checkout main // 합치려는 branch로 이동
git merge new-branch // 작업한 브랜치를 호출해서 현재 branch로 merge

이렇게 되면 새로운 작업을 한 branch를 다시 main으로 합치게 됩니다.

02 Branch 1 kopiera
git merge와 rebase 이해하기 8

이런식으로 merge를 진행하게 됩니다.

주의 사항 – 충돌 처리

Git Merge나 Rebase를 할 때, 가장 처리가 어려운 것은 기존 코드와 충돌입니다.

코드가 충돌하면 기존 코드와 병합 처리를 잘해야 합니다. 특히, 코드가 충돌할 때 함부로 기존 코드를 지우거나 하면 안됩니다. 그래서 코드가 충돌한다면 꼭 소통을 해야 합니다. 그리고 불필요한 코드는 삭제하고 필요한 코드를 살린 후 merge를 이어서 진행합니다.

뒤에 다룰 rebase도 동일하게 처리합니다.

On branch main
Unmerged paths:
(use "git add/rm ..." as appropriate to mark resolution)
both modified: hello.py

위 코드는 main을 기준으로 hello.py 파일에 충돌이 발생했을 때 나타나는 예시 내용입니다.

보통 출돌이 나게 되면 코드는 아래와 같이 나옵니다.

here is some content not affected by the conflict
<<<<<<< main
this is conflicted text from main
=======
this is conflicted text from feature branch
>>>>>>> feature branch

위 내용을 보면 ======= 이라는 마커를 기준으로 기존의 내용과 바뀐 내용이 나옵니다. 이를 비교해서 적용해야 할 코드를 선택해서 반영하거나 둘 다 반영해서 코드를 정리한 후 다시 commit을 진행해야 합니다.

Git Rebase 이해하기

Git Rebase는 커밋 시퀀스를 새 기준 커밋으로 이동하거나 결합하는 프로세스입니다. rebase와 merge의 차이점은 merge는 합쳐진다는 느낌이라면 rebase는 다른 커밋에서 브랜치를 만든 것처럼 보이게 합니다. 이를 통해 커밋 로그를 깔끔하게 바꾸고, 브랜치를 동일하게 만들지만 완전히 새로운 커밋으로 구성되어 있다는 것을 이해해야 합니다.

rebase를 사용하는 가장 큰 이유는 선형 프로젝트 기록을 유지하기 위해서 입니다.

선형 프로젝트 기록은 왜 유지해야 할까요? 바로 나중에 기능 브랜치를 메인 브랜치로 깨끗하게 병합할 수 있다는 이점이 있습니다. 지속적인 merge 작업은 commit 기록이 계속해서 쌓입니다.

Untitled1

이런식으로 계속해서 쌓이게 되면, commit log를 추적하기가 힘듭니다. 또한, 사소한 commit도 계속해서 쌓이게 되죠. 이것을 그대로 main branch로 합치게 되면 지저분한 모든 기록이 합쳐지면서 기록이 복잡해 집니다.

이것이 문제가 되는 이유는 추후 git commit 기록을 검색할 때 문제가 됩니다.

과거 새로운 기능을 추가할 때, 오류가 발생했습니다. 이것을 찾기 위해 commit log를 검색했는데 이상한 commit들이 검색되면서 내용이 많이 나오게 됩니다. 이러한 상황에서는 버그가 발생한 commit를 찾기 어렵습니다. 그렇기 때문에 rebase를 통해 의미 없는 commit을 없애고, main branch는 깔끔하게 병합하는 과정을 갖습니다.

여기서 알 수 있는 것은 main, dev와 같은 메인 branch에서는 rebase를 사용하면 안됩니다. 새로운 기능 branch에서 기능 작업을 할 때만 rebase를 사용합니다.

> git rebase -i HEAD~2

위와 같은 명령어를 통해 HEAD부터 2개의 Commit을 합치는 명령을 실행합니다.

이 명령을 실행하면 commit log가 나옵니다.

pick 2231360 some old commit
pick ee2adc2 Adds new feature

# Rebase 2cf755d..ee2adc2 onto 2cf755d (9 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit

여기서 삭제할 commit의 pick 명령어를 s로 변경합니다.

아래 주석에 나와있는 squash 명령어로 해당하는 commit를 남아있는 commit에 병합하면서 로그를 삭제합니다.

그리고 commit과 push를 통해 변경사항을 반영합니다.

> git commit
> git push -f // 강제 옵션을 통해 push 한다.

이를 통해 commit 로그를 깔끔하게 정리할 수 있게 됩니다.

마무리

git merge와 rebase 명령어는 협업을 할 때 많이 사용하는 명령어입니다.

협업에서 가장 중요한 git command 이기 때문에 능숙하게 사용해야 하는 명령어 이기도 합니다.

이번 글을 통해 git을 좀 더 깔끔하고 효율적으로 사용할 수 있습니다.

참고 자료

https://im-developer.tistory.com/182

https://www.atlassian.com/ko/git/tutorials/using-branches/git-merge

https://www.atlassian.com/ko/git/tutorials/rewriting-history/git-rebase

https://www.atlassian.com/ko/git/tutorials/merging-vs-rebasing

https://velog.io/@himprover/%EB%8C%80%EC%B6%A9-%EC%93%B4-Git-Commit-%ED%95%A9%EC%B9%98%EA%B8%B0-rebase

함께 보면 좋은 글

Leave a Comment