hg(Mercurial)のphaseを使ってリモートリポジトリをぐっちゃりさせない
Contents
push only necessary commits (ignore test commits!)
cloneで持ってきたローカルリポジトリで、「バグ修正作業なんだけど、どこをどうしたらどうなるかわかんないから、トライ&エラーでガシガシだ~」的な時は細かにコミットして行ったり戻ったり、やっぱりさっきのやっておこう、的な迷走がよくある(よくあっちゃダメだろ)のですが、その修正をまるごとリモートリポジトリに反映させると、とても可哀想なリポジトリになります。あみだくじみたいな。
これでは後から作業追いかけるにも、他人の修正を確認するにも大変。リモートリポジトリには必要な修正のコミットだけ反映させて、試行錯誤は反映させないようにしたい!
で、Phaseを使うと都合よく出来そうってことで。
//TODO: 画像(graph)挿入
Phaseで秘密の人になる
PhaseはMercurialの2.1から導入されています。 http://mercurial.selenic.com/wiki/Phases
phaseは以下で確認できます。
$ hg phase -r [リビジョン]
また、phaseコマンドはオプションを付けることで(-s:secret, -d:draft, -p:public), 指定のリビジョンのphaseを変更できます。
$ hg clone
で持って来たリビジョンのphaseはpublicになっています。
さて、試行錯誤だーってことで、適当になにか編集してcommitしちゃいます。するとPhaseがdraftのリビジョンが出来ます。 これは試行錯誤のリビジョンなので他に出したくありません。Phaseをsecretに変えちゃおう。
$ hg phase -s -r . -f (-fオプション(--force)が必要になります)
これで試行錯誤リビジョンのphaseがsecretになりました。
$ hg phase -r . >[リビジョン]: secret
もう秘密の人なのでこの状態で$ hg pushしても”secretのチェンジセットは無視するよ”と言われます。やったね!
試行錯誤がんばる
編集して$ hg commitを繰り返して修正が完了するまでがんばる。 phaseがsecretの状態でcommitしているので、子リビジョンもsecretとなるため、このコミット達はpushしても反映されません。
親リビジョン(となって欲しいリビジョン)に最終修正結果を反映させてコミット
がんばったので修正が終わったー。試行錯誤の最終コミットおわり。 さて、リモートリポジトリに最終結果だけを反映させるぞー。ということでpushするコミットを作ろう。
親リビジョンを決め、公の人に戻ります。
$ hg update -r [親リビジョンにしたいリビジョン]
試行錯誤の最終結果を反映します。
$ hg revert -r [試行錯誤の最終コミットのリビジョン] --all
コミットします。phaseがdraftのリビジョンが出来ます。
$ hg commit
状態としては、 試行錯誤方向のリビジョンと、今コミットしたリビジョンでひとつの親から2つでているので、無名ブランチがある状態になってます。hg headでみてみるとHEADが増えています。
$ hg head
リモートリポジトリに反映させる
pushするだけ。
まとめ
(親リビジョン:[REVNUM]) $ hg clone REPO -r [REVNUM] $ hg commit -m "試行錯誤中1" $ hg phase -s -r . -f $ hg commit -m "試行錯誤中2" $ hg commit -m "試行錯誤中3(修正完了!)" $ hg update -r [REVNUM] $ hg revert -r tip --all $ hg commit -m "修正完了~" $ hg push
(cloneして、)commitして、秘密の人になって、試行錯誤して、親リビジョンに戻って同時に公の人に戻って、最終結果反映させて、commitして、push!!
(余談)
無名リポジトリの話が途中で出たので、Phaseを使わないで同じようなことをする方法。。
(親リビジョン:[REVNUM]) $ hg clone REPO -r [REVNUM] $ hg commit -m "もじゃもじゃ" $ hg update -r [REVNUM] $ hg commit -m "試行錯誤中1" $ hg commit -m "試行錯誤中2" $ hg commit -m "試行錯誤中3(修正完了!)" $ hg update -r [REVNUM] $ hg revert -r tip --all $ hg commit -m "修正完了~" $ hg push -r .
こんな感じ。
phaseをsecretにして、リモートリポジトリへのpushの対象から外す代わりに、
$ hg update -r [REVNUM] $ hg commit -m "もじゃもじゃ" $ hg update -r [REVNUM] $ hg commit -m "試行錯誤中1"
[REVNUM]のリビジョンから複数の子を出すことで無名ブランチを作り、headを増やすことで、pushした時に”headがアレだぞ!”って怒られることでpushを避けます。試行錯誤の所は同様です。
$ hg push -r .
そして最後にpushする時にリビジョンを指定することで、指定したリビジョンとそのancentorsのみ反映させ、試行錯誤たちを除きます。
リビジョン指定せずにpushすると、”headがアレだぞ!”と怒られるのですが(というかそれを利用してpushから逃れるのがこの方法)、ここでhgのおすすめに従って-fオプション使って反映させようとすると、(当然ながら)試行錯誤含めて全てリモートリポジトリに入っちゃうので注意です。
ちなみに…
“headがアレだぞ!”とは↓のことです
$ hg push : : abort: push creates new remote head xxxxxxxxxxxx! (did you forget to merge? use push -f to force)
gitではどういう方法・手順になるんでしょう?
コメントはまだありません。