ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [쉬운 Git] git rebase 의 방법과 다양한 문제 해결
    소프트웨어 & 잡다 2020. 4. 12. 01:59

    Git 의 'rebase'는 가장 강력한 무기중의 하나라고 생각한다. Git의 특성과 더해져 수많은 버전 컨트롤의 문제가 미연에 예방되는 마법과 같은 툴이다. Git의 사용법은 매우 쉽지만, SVN에서 Git으로 갈아타시는 분들의 경우 이런저런 컨셉의 차이때문에 많이 혼란스러워 하기도 한다. SVN에 대해서 싹 잊어버리고, 버전컨트롤이라는 개념을 처음 배우는 아기같은 기분으로 받아들여야 할 필요가 있다. 이 글은 Git을 많이 사용하는 분들이 대상이지만, 블로그의 다른 글들을 보면 Git을 처음 사용하는 분들도 도움을 받을 수 있을것이다.

    Rebase는 왜 사용하나?

    쉽게 설명하자면, 내가 브랜치에서 작업하고 있는 동안 master 에 적용된 커밋들을 나의 브랜치에 적용하기 위해서다. 아래의 그림을 살펴보면, 내브랜치를 commit #2 에서 생성했고, 그 위에 두번 더 커밋을 하였다. 그사이에 마스터 브랜치에는  commit #3과 #4가 추가 되었다.

    두가지 선택이 있는데, master 를 내 브랜치에 merge 하는 방법, 그리고 두번째는 rebase 하는 방법이다. 나는 Git 을 사용하면서 merge 는 전혀 사용을 하지 않는데, 이 방법을 유지하면 매우 깨끗한 커밋 트리를 유지할 수 있고, 실수를 예방할 수 있다. 그래서 이 경우에도 당연히 Rebase를 사용한다.

    브랜치 생성 이후에 master에 변경 3, 4가 생김

    아래와 같은 간단한 명령어로 rebase를 할 수 있다.

    $ git rebase master

    rebase가 성공적으로 수행 되면, 아래와 같은 형태로  트리가 생성된다. 내 커밋들이 커밋 4 이후에 추가되는 형태로 변경 된 것을 확인할 수 있다. 

    commit 2 위에 있었던 나의 커밋들이 commit 4 위로 옮겨졌다.

    이 rebase를 자주 하면 할 수록 branch에서의 작업을 나중에 master에 적용할 때 안전하고 쉽다.

    Rebase의 원리?

    그러면 rebase는 도데체 어떤 원리로 동작하는 것일까? 생각보다 매우 간단한데, 이 원리를 알아두는것은 매우 매우 매우 중요하다. 나중에 conflict 처리 할 때 이 원리를 알고 모르고의 차이가 엄청나기 때문이다. 우선 rebase 를 수행하면,  master 브랜치 (target commit)에 my_branch에 적용되었던 커밋들을 하나 하나 머지를 한다. 매 커밋을 머지 할 때마다 conflict 이 발생할 수도 있고, 자동으로 resolve 되거나 자동 resolve가 실패할 수 있다. 모든게 자동으로 resolve 되는 경우, 마지막 커밋까지 모두 머지 되고 종료 된다.

    commit 4 에 my_branch의 커밋들을 머지하기 시작
    첫번째 커밋인 2-1을 머지

     

    두번째 커밋인 2-2를 머지

    충돌이 없는 경우는 이렇게 아주 수월하게 rebase가 된다.

    충돌 발생시 해결 방법

    그런데 보통은 충돌이 생긴다. 충돌은 보통 내 브랜치의 첫 커밋을 머지할 때 생기고 나머지는 부드럽게 머지 되기도 하는데, 운이 나쁘면 매 커밋 머지마다 충돌이 생기기도 한다. 충돌이 생기면, 개발자가  conflict을 해결하거나 rebase를 취소할 수 있도록 rebase 가 잠시 멈춘다.

    rebase가 실패하면, git status 명령으로 현재의 상태를 확인 할 수 있다. 여기서 conflict 이 생긴 파일들의 목록을 보여주는데

    1. rebase를 완전히 취소하려면 --abort 명령을 이용한다.

    $ git rebase --abort

    2. conflict을 수정하고 계속 하고싶다면 해당 파일들을 열어서 충돌사항을 고친 후 --continue 를 이용해서 계속 진행을 시도한다. 파일에서 충돌 사항을 찾을때는 "====" 을 검색하면 된다.

    $ git add -u
    $ git rebase --continue

    위에서 설명한 것 처럼, rebase는 내 브랜치의 커밋 하나 하나를 따로 머지 하기 때문에, 이 과정을 반복 하게 될 수도 있다. 그러니 당황하지 말고 천천히 하나하나 수정해 나가도록 하자.

    3. 만일 충돌이 일어났는데 내 브랜치의 변경 사항을 무시해도 되는 경우거나, 내 브랜치 변경 사항이 맞다고 확신하는 경우  매우 간단하게 해결 할 수 있다.

    # 내 브랜치의 변경점을 우선으로적용
    $ git checkout --thers 파일_풀_경로
    
    # master의 변경점을 우선으로 적용
    $ git checkout --ours 파일_풀_경로
    

    내 브랜치의 변경점을 수락하며 자동으로 conflict을 해결하려면 theirs, master 브랜치의 변경점을 수락하며 자동으로 conflict을 해결하려면 ours. 여기서 theirs 와 ours를 헛길리면 안된다. rebase는 master에 나의 각 커밋들을 하나하나 머지 하는 방식으로 master가 ours 이고 내 브랜치가 theirs 이다.

    처음부터 충돌을 방지하기

    개발자가 처음부터 어느쪽 변경사항을 적용하는것이 맞는지 확실히 아는 경우에는 rebase 명령어 사용시에 theirs 와 ours를 지정할 수 있다. 예를 들면,

    git rebase --strategy-option theirs master
    git rebase -X theirs master # 짧은버전

    -> 내 브랜치의 변경점을 우선으로 해서 자동으로 resolve 하면서 rebase 한다.

     

    오늘은 수많은 기능중 하나인 rebase에 대해서만 설명 했지만, 사실 Git을 어떻게 사용하면 쉽고 편한지를 설명하기 위해서는 몇가지 더 설명해야 할 것들이 많이 있다. 반응이 좋아서 더 많은 내용을 다룰 기회가 있으면 좋겠다.

     

     

    글이 도움이 되었다면 "공감" 버튼으로 응원해 주세요.

    로그인 없어도 됩니다 ^^

    댓글

Designed by Tistory.