Rebasing in Mercurial

원문: http://bitquabit.com/post/rebasing-mercurial/

hg rebase

자, 여러분은 git을 선택했습니다. 어쩌면 Mercurial을 선택했을지도 모르죠. 아무튼 지금껏 썼습니다. 문제는 “Merged with stable,” “merged with base” 또는 이와 비슷한 커밋 내용입니다. 이런 커밋은 그다지 쓸모 없는 정보이고 커밋 이력을 완전히 엉망으로 만들어 버립니다. 어떻게 하면 이력을 더 유용하게 할 수 있을까요?

답은 재배치(rebase)에 있습니다. 재배치(rebase)란 아직 다른 저장소로 보내지 않은(not-yet-pushed) 패치를, 마지막으로 패치를 가져온(pull) 저장소의 tip이 아니라 현재 원격 tip에 대해 적용하는 git을 통해 널리 알려진 기술입니다. 이것의 이점은 주개발(upstream) 저장소와 병합할 때 단순히 개별적인 병합 하나로 표시하기보다 (주요 브랜치 사이에) 유용한 여러 병합 내용으로 표시합니다.

오늘, 곧 나올 Mercurial 1.1에서 지원할 기능에 대해 동료와 얘기하다 다음 얘기를 듣고 깜짝 놀랐습니다. ”와, 정말 멋져, 드디어 Mercurial에서 재배치를 지원해!” 이번에 나올 Mercurial 버전에서 pull --rebase 명령을 지원하지만 그 이면을 보면 mq로 처리하는 일 중 일부를 자동화한 것이 전부입니다.

참고: 다음 내용은 최근 Mercurial 버전에서 동작하지만 hg rebase와, 자매 명령인 hg pull --rebase를 사용하면 아래에서 설명한 내용을 훨씬 쉽게 처리할 수 있으며, Mercurial에서 MQ를 지원한 것은 현 시점에서 볼 때 1년이 넘었습니다. MQ를 배우기 전에, 사용하는 Mercurial에서 rebase 명령을 지원하는지 hg help rebase로 확인해 보길 바랍니다. 지원하면 그 명령을 사용하는 게 더 낫습니다.

지금부터 Copilot 개발 저장소를 예로 들어 살펴 보겠습니다.


gozer:Host benjamin$ hg out
comparing with ssh://fcs//hg/copilot-helpers-devel
searching for changes
changeset:   1937:fe42e5e8e0cf
user:        Benjamin Pollack <[email protected]>
date:        Mon Nov 24 14:49:30 2008 -0500
summary:     Make CPUpgrader a proper framework so that OneClick can include it

changeset:   1938:20033e199dc7
user:        Benjamin Pollack <[email protected]>
date:        Mon Nov 24 20:08:06 2008 -0500
summary:     Undo accidental rename of Host to OneClick

changeset:   1939:127619345a57
tag:         tip
user:        Benjamin Pollack <[email protected]>
date:        Mon Nov 24 20:12:39 2008 -0500
summary:     Add OneClick

gozer:Host benjamin$ hg in stable
comparing with ssh://fcs//hg/copilot-helpers-stable
searching for changes
changeset:   1940:6db7e59a82c5
tag:         tip
parent:      1936:3140f971d7ab
user:        Benjamin Pollack <[email protected]>
date:        Mon Nov 24 12:38:14 2008 -0500
summary:     Added tag 000253 for changeset 3140f971d7ab

gozer:Host benjamin$

보낼 변경 내용이 세 개이고 가져올 것은 태그만 추가한 것 하나입니다. 명시적으로 병합하면 이력만 아주 복잡하게 만들 뿐 아무런 이점이 없습니다. 완벽한 해결책은 커밋을 재배치하는 겁니다.

이 전투에서 승리할 계획은 다음과 같습니다.

  1. 보낼 패치를 모두 mq 큐에 추가합니다.
  2. 큐에 추가한 패치를 패치 스택에서 모두 꺼냅니다.
  3. hg pull로 stable 저장소에서 변경 내용을 가져 옵니다.
  4. 보낼 패치를 다시 적용합니다.
  5. 패치를 Mercurial 체인지셋으로 다시 변환합니다.

시작해 봅시다. 현재 base 커밋은 체인지셋 fe42e5e8e0cf이므로 이 체인지셋에서 tip 사이 모든 내용을 mq에 추가한 후 스택에서 꺼내야 합니다.


gozer:Host benjamin$ hg qimport -r fe42:tip
gozer:Host benjamin$ hg qpop -a
Patch queue now empty
gozer:Host benjamin$

모든 걸 순조롭게 잘 마치면 보낼 패치는 없어야 합니다.


gozer:Host benjamin$ hg out
comparing with ssh://fcs//hg/copilot-helpers-devel
searching for changes
no changes found
gozer:Host benjamin$

생각한 대로 됐으므로 이제 hg pull -u로 간단히 원격 저장소에서 변경 내용을 가져올 수 있습니다.


gozer:Host benjamin$ hg pull -u stable
pulling from ssh://fcs//hg/copilot-helpers-stable
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
gozer:Host benjamin$

그런 다음 패치를 다시 적용하고 체인지셋으로 변환합니다.


gozer:Host benjamin$ hg qpush -a
applying 1937.diff
applying 1938.diff
applying 1939.diff
gozer:Host benjamin$ hg qdelete -r qbase:qtip
gozer:Host benjamin$

마지막으로, 생각한 대로 됐는지 확인합니다.


gozer:Host benjamin$ hg glog -l 4
@  changeset:   1940:0b08e0a83965
|  tag:         tip
|  user:        Benjamin Pollack <[email protected]>
|  date:        Mon Nov 24 20:12:39 2008 -0500
|  summary:     Add OneClick
|
o  changeset:   1939:a730a92acb01
|  user:        Benjamin Pollack <[email protected]>
|  date:        Mon Nov 24 20:08:06 2008 -0500
|  summary:     Undo accidental rename of Host to OneClick
|
o  changeset:   1938:01954591e76e
|  user:        Benjamin Pollack <[email protected]>
|  date:        Mon Nov 24 14:49:30 2008 -0500
|  summary:     Make CPUpgrader a proper framework so that OneClick can include it
|
o  changeset:   1937:6db7e59a82c5
|  user:        Benjamin Pollack <[email protected]>
|  date:        Mon Nov 24 12:38:14 2008 -0500
|  summary:     Added tag 000253 for changeset 3140f971d7ab
|
gozer:Host benjamin$

완벽합니다. 이력은 한 줄로 나열됐고 변경 내용은 원격 tip 위로 재배치했습니다.

지금까지 한 것은 분명히 hg pull --rebase보다 더 복잡하지만 Mercurial 1.1을 기다리고 싶지 않다면 지금 당장 같은 기능을 사용할 수 있습니다.

Notes:
1. 마지막으로 패치를 가져왔을 당시 tip이 아니라 앞으로 가져올 패치의 tip에 대해 적용한다는 의미입니다.
2. .hgrc 또는 mercurial.ini 파일에 다음 내용을 추가해야 합니다.

[extensions]
rebase =

마지막으로 패치를 가져왔을 당시 tip이 아니라 앞으로 가져올 패치의 tip에 대해 적용한다는 의미입니다.
.hgrc 또는 mercurial.ini 파일에 다음 내용을 추가해야 합니다.
[extensions]
rebase =

You may also like...