Mustache :{

moon indicating dark mode
sun indicating light mode

git push --force

...

September 11, 2012

저는 pull-request workflow가 갑이라고 생각합니다. 비동기 방식으로 업무가 진행되고, merge 하기전에 자연스런 review 도 되고요.

근데 궁금한점이 생겻습니다. 이게 말로 한문장으로 설명하기 참 어려워서 예를 들겠습니다.

# alias.br=branch
# alias.co=checkout
$ git br
* master
topic1
topic2

3개의 브랜치가 있고 이렇게 저렇게 작업해서 각각의 이력은 아래와 같습니다. topic1topic2 가 분기한 시점은 같습니다.

  • master
bfb49285 * [origin/master] [master] init commit
  • topic1
c94f01bb * [origin/topic1] [topic1] add b.c
90d550b0 * add a.c
bfb49285 * [origin/master] [master] init commit
  • topic2
b9f6b81a * [origin/topic2] [topic2] add e.c
95ea73d0 * add d.c
2a44208b * add c.c
bfb49285 * [origin/master] [master] init commit

두개의 topic 모두 pull-request 상태이고(github 을 사용한다고 가정합니다), 매니저가 topic1merge 합니다.

ed02ed2e * [origin/master] [master] Merged in aanoaa/test/topic1 (pull request #1)
|\
c94f01bb | * [origin/topic1] [topic1] add b.c
90d550b0 | * add a.c
|/
bfb49285 * init commit

topic1 이 먼저 merge 되었기에 topic2 에서 masterrebase 합니다.

963cd74c * [topic2] add e.c
fcaba0cc * add d.c
f28849aa * add c.c
ed02ed2e * [origin/master] [master] Merged in aanoaa/test/topic1 (pull request #1)
|\
c94f01bb | * [origin/topic1] [topic1] add b.c
90d550b0 | * add a.c
|/
bfb49285 * init commit

rebase 되었기 때문에 topic2origin/topic2 HEAD 를 잃습니다. 이때 push 하게 되면 reject 됩니다.

$ git push origin topic2
To ssh://git@example.com/aanoaa/test.git
! [rejected] topic2 -> topic2 (non-fast-forward)

여기서 다른 사람들은 어떻게 처리하는지가 궁금합니다. 두개의 방법이 있을 수 있습니다.

  • $ git pull && git push non-fast-forward 이기 때문에 쉽게 생각할 수 있는 방법입니다.
  • $ git push --force origin topic2 remote 의 이력을 바꿔버립니다.

첫번째 방법으로 해결했을때는 topic2 에서 작업한 이력이 두번씩 남게 됩니다.

9647d196 * [topic2] Merge branch 'topic2' of ssh://example.com/aanoaa/test into topic2
|\
b9f6b81a | * [origin/topic2] add e.c
95ea73d0 | * add d.c
2a44208b | * add c.c
963cd74c * | [ref-topic2] add e.c
fcaba0cc * | add d.c
f28849aa * | add c.c
ed02ed2e * | [origin/master] [master] Merged in aanoaa/test/topic1 (pull request #1)
|\ \
| |/
|/|
c94f01bb | * [origin/topic1] [topic1] add b.c
90d550b0 | * add a.c
|/
bfb49285 * init commit

rebase 의 동작방식을 이해한다면 당연한 결과입니다. 마지막의 merge 커밋도 pull 을 사용했기 때문에 이해할 수 있습니다.

두번째 방식을 사용한다면 아까 topic2 에서 masterrebase 했을때의 이력을 가지게 됩니다만 공동작업에서 remote 의 이력을 변경하게 되는 것이라서 부담이 생깁니다.

두개의 결과는 같습니다만 첫번째는 중복된 이력을 가지게 되고, 두번째는 협업간에 불화가 생길 수 있습니다.

어떻게들 사용하시나요?