(git) rebase의 함정

sangkiyesangkiye
2 min read

rebase를 하면 안되는 상황

“다른 동료가 작업 중인 외부에 공개 된 저장소 브랜치를 대상으로 리베이스하면 안된다.”

  1. 초기상태

나와 동료가 같은 브랜치에서 작업중이다.

 A—B—C (origin/main)
  1. 각자 작업 시

나: C에서 시작해 D와 E 커밋을 만들었다.

동료: C에서 시작해 X와 Y 커밋을 만들었다.

당신:    A---B---C---D---E (local)
동료:    A---B---C---X---Y (local)
원격:    A---B---C (origin/main)
  1. 동료가 먼저 푸시

동료가 먼저 작업을 완료하고 푸시했다.

당신:    A---B---C---D---E (local)
원격:    A---B---C---X---Y (origin/main)
  1. 🔥 내가 Rebase를 사용 🔥

나는 최신 변경 사항을 반영하기 위해 rebase를 사용했다.

# 이전
A---B---C---D---E (local)

# rebase 후
A---B---C---X---Y---D'---E' (local)

D’와 E’는 D와 E와 같은 변경사항이지만 새로운 해시값을 가진다.

  1. 강제 푸시

내가 강제로 푸시하면

원격:    A---B---C---X---Y---D'---E' (origin/main)
  1. 문제발생
  • 다른 동료들이 git pull을 하면 혼란스러운 상황이 발생한다.

  • 이미 X,Y를 기반으로 작업중이던 사람들은 충돌이 발생한다.

  • 히스토리가 재작성되어 추적이 어려워진다.

대안 : merge를 사용한다.

4번에서 rebase가 아닌 merge를 사용했다면,

# merge 후
      D---E
     /     \
A---B---C---X---Y---M (local)
  • 모든 커밋이 보존되고 병합커밋 (M)이 생성된다.

  • 원래 커밋 해시가 유지되어 히스토리 추적이 가능해진다.

결과

  • 이미 원격저장소(origin)에 push한 커밋들을 rebase하는 것을 지양하고 merge를 사용하자.

  • rebase는 내용은 같지만, 새로운 해시를 가진 커밋을 생성한다.

*rebase 이후 push가 되지 않는 이유

동료가 작업한 최신사항을 반영하기 위해 나의 local/main 에서 git pull을 받고, 작업 브런치로 이동해 git rebase main을 한 다음, 작업 브런치의 origin으로 보내기 위해 git push oirgin feat/xx 을 하면 push를 할 수 없다.

왜 일까?

  • 결론적으로 말하면 git의 안전 메커니즘때문에 거부당하는 것이다. origin/feat/xxx 입장에서 자신의 현재 커밋 내역은 아래와 같다.
   A--B--C
      \
       D--E (origin/your-branch)

근데 local/main 으로부터 rebase 한 local/feat/xxxx의 커밋내역은 아래와 같다.

   A--B--C--F--G
                \
                 D'--E' (your-branch)

즉, git은 origin와 local의 히스토리가 다르다고 판단하여 push를 거부하는 것이다. 더 정확히 말하자면 rebase를 하면서 부모 커밋이 변경(C에서 G로) 되면서 모든 후속 커밋의 해시도 변경이 되었기때문에 거부를 당하는 것이다.

이러한 이유로 feat/xxx 브런치가 origin에 push가 한번이라도 된 상태라면 rebase 이후 push가 되지 않고, origin에 올라가 있지 않다면 push가 되는 것이다.

하지만 작업 브랜치가 여전히 “나”만 사용하고 있다고 보장할 수 있다면 git push —force 를 통해서 강제 push를 해도 상관 없으나, 어쨋든 해시가 변경되기에 애초에 rebase 보다는 merge를 통해서 local/main을 작업 브랜치 쪽으로 병합시키는게 좋다.

0
Subscribe to my newsletter

Read articles from sangkiye directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

sangkiye
sangkiye