회사에 처음 들어갔을 때, 평소에 사용하는 Git Merge 방식이 아닌, rebase 방식을 통해 Commit history log 및 그래프 관리를 하고 있었습니다.
Rebase 에 대해 자세히 알아보는 글 입니다.
[ 목차 ]
- Git Merge & Rebase 차이
- Git Rebase 유의사항
- Git Rebase 를 활용한 Git 시나리오
Git Merge 와 Rebase에 대해서 간단하게 개념 설명을 하고 예시를 통해 설명하겠습니다.
Git Merge는 여러 Branch 들이 존재할 때, 하나의 branch로 통합시키는 개념입니다.
Git Rebase 는 Branch 의 base를 재설정한다는 의미입니다.
여기서 Branch의 base란 Branch가 뻣어나오는 시작점을 base 입니다.
실제 예시를 통해 알아봅시다.
(이게 훨씬 이해 잘됩니다. 직접 해보면서 graph를 확인하면 이해도가 확 올라갑니다!! )
다음의 사진을 봅시다.
현재, dev 브랜치로부터 branch_1 에는 (commit 1,4) branch_2에는 (commit 2,3) 이 존재합니다. dev branch로 merge를 시켜보겠습니다.
현재 branch --> (dev)
명령어 : git merge <merge 할 branch>
#cf ) merge 명령어는 checkout 된 branch 로 다른 branch 로 merge 하는 명령어
git merge dev branch_1
git merge dev branch_2
를 순서로 진행해주면 됩니다.
cf) merge 기본 설정값이 fast-foward 일 경우 그림과 살짝 다를 수 있습니다.
branch_1 , branch_2를 순서대로 dev branch로 merge 시켜보았습니다. Commit Graph가 꼬여있는 것을 확인할 수 있습니다.
만약 동시에 작업한 branch가 여러개 존재하고, 이를 통합하는 과정에서 merge를 시킨다면 Commit graph는 꼬여있고 한눈에 변경사항들을 파악하기 어려울 것입니다. dev 브랜치를 원격 dev에 push 할 경우 상세한 커밋들의 정보도 남아있지 않아, 변경사항을 파악하는데 어려울 것이라 생각됩니다.
그렇다면 Rebase 는 어떤 것일까요?
현채 초기 graph를 보면 branch_1, branch_2 모두 dev branch base를 기반으로 뻗어나가고 있는 것을 확인할 수 있습니다. branch_1 을 merge --no-ff 방식으로 merge 시켜보겠습니다.
현재 branch --> (dev)
git merge --no-ff dev brach_1
[Git merge] 위의 설명과 똑갑습니다.
이제, branch_2 branch를 dev branch에 Rebase 시켜 보도록 하겠습니다.
현재 branch --> (dev)
명령어 : git rebase <rebase 기준이 될 branch> <rebase 할 branch>
#cf) Rebase 할 branch가 현재 checkout 된 branch 라면, 생략가능합니다. 즉 git rebase <rebase 기준이 될 branch> 만
입력하면 rebase 기준이 될 branch를 기준으로 현재 checkout 된 branch의 내용들을 rebase 시키게 됩니다.
git rebase dev branch_1
dev branch base를 기준으로 branch_2를 rebase 진행시키면 위 사진처 럼 (commit 2,3) dev base 위에 새로운 commit id 를 갖으면서 commit 이 생성되게 된다.
이제 merge 를 시켜보도록 하자 그래프의 변화를 잘 보고 merge에 관한 commit 을 남기기위해 --no-ff 방식으로 merge 하겠다.
현재 branch --> (dev)
git merge --no-ff dev branch_2
각 git commit graph가 Merge방식에 비해 깔끔하게 변한 것을 알 수 있다. 현재에서는 Local 에서만 진행하였는데 remote repository에서도 이와 마찬가지 개념으로 pull & rebase & merge 시키면서 사용하면 된다.
자세한 명령어는 아래에서 설명하도록 하겠다.
Git Rebase를 사용하면, commit graph를 깔끔하게 유지하면서, Git log를 깔끔하게 관리할 수 있었습니다. 관리에 있어서 장점이 있는 만큼 주의해서 사용해야 하는데 어떤점을 고려해야하는지 이야기해보도록 하겠습니다.
유의해야할 점은 다음과 같습니다.
"Do not rebase commits that exist outside your repository and that people may have based work on.
”다른 동료가 작업 중인 외부에 공개 된 저장소 브랜치를 대상으로 리베이스하면 안됩니다."
우선, Git rebase는 기존의 커밋을 그대로 사용하는 것이 아니라,내용은 같지만 다른 커밋을 새로 만든다고 이해하셔야 합니다.
유의사항은 무슨 말일까요?
간단히 설명하면 외부로 push 내보낸 커밋에 대해서는 rebase를 하지 말라는 뜻입니다.
예시를 들어보도록 하겠습니다.
현재 master 브랜치가 존재하고 커밋 3개를 remote branch 에 push 한 상황입니다. 다른 팀원이 이 때, remote branch를 pull 받았다고 생각하겠습니다.
이 상황에서 다른 branch로 master 에 push된 3개의 커밋들을 다른 branch로 리베이스 한 후, remote branch 에 push 해보도록 하겠습니다.
거절당하는 것을 알 수 있습니다. 왜 그럴까요..? 기존에 올렸던 커밋들 이전에 새로운 커밋들이 새로 껴있기 때문입니다. rebase 되면서 커밋들의 순서가 꼬이게 된 것입니다. 강제로 push -f 명령어를 통해 push 해보겠습니다. ( 자기 혼자 쓰는 repository 가 아닌 경우, push -f 명령어는 굉장히 위험하기 때문에 사용을 지양하셔야 합니다.)
다른 팀원의 상황을 보도록 하겠습니다.
fetch만 받아서 graph를 살펴보면 같은 commit 이 지금 2개가 생겨난 것을 확인할 수 있습니다. 만약 이상황해서 pull Merge를 해버리게 된다면,같은 내용의 커밋이 2개가 생기게 됩니다.
이 상태에서 pull rebase 하게 되면 중복되는 commit 을 skip 해주기 때문에 해결은 되지만, 해결된다고 해서 rebase를 함부로 사용하면 안됩니다. 만약 다른 팀원이 merge 방식을 사용하고 있었다면.. 큰 문제가 되겠지요?
실무에서 사용했던, Rebase 방식에 대해 간단히 설명하려고 합니다.
우선 3개의 .git 저장소가 존재합니다.
#cf) upstream branch 전략에 따라, 각각 branch를 추종하는 local
branch를 만들어 두어 sync를 맞추면서 사용하는 것이 바람직한 방법이라 생각됩니다.
Git 명령어
위의 시나리오에 사용되는 명령어들을 써보도록 하겠습니다.
0. git checkout -b <원격 branch 이름> ex) dev
1. git checkout -b <작업할 local branch 이름> ex) feat/test
2. git rebase <base가 될 branch> <작업한 local branch>
ex ) git rebase dev feat/test
3. git pull -r upstream <원격 branch 이름> ex) dev
4. git push origin dev
Github 에서 Pull Request 날리기
(git 으로도 할 수 있지만, 가시적으로 보기엔 사이트가서 하는게 더 나은거 같습니다.)
학습하는 과정에서 스스로의 생각을 적은 글 입니다. 잘못된 부분이나 문제가 있는 부분은 피드백 주시면 감사하겠습니다 ^^*
읽다보니까 한호성블로그글이네 ㅋㅋㅋㅋㅋㅋ