放牧日記スマートフォン用の表示で見る放牧日記この広告は、90日以上更新していないブログに表示しています。[PARTAKE]の1日目です。(日付間違っただけでフライングじゃないよ。)最初は小ネタという事で、MercurialのRebase拡張の使い方についてケーススタディで説明したいと思います。パターンを上げていったらかなり長い記事になってしまいました。読むのに10分くらいかかります。説明に出てくるリポジトリはhttps://bitbucket.org/troter/mercurial-advent-calendar-2011-1/に置いてあるシェルスクリプトで作成出来ます。unixやcygwinの環境が有る方は次のコマンドで作業環境が整います。(コマンドを列挙しているだけなのでwindows環境でも簡単に再現できると思います。make注意点まずはじめに履歴改変全般に関する注意点です。中央リポジトリに反映されてた公の履歴の改変は絶対厳禁です。次に、rebaseに関する注意点です。現在のリビジョンの場所に気をつけて下さい。適切な場所(移動させたい場所)に居るとrebaseがスムーズに実行できます。rebaseになれないうちは--keepオプション(後で出てきます)を利用しましょう。rebase指定したリビジョンの親リビジョンを差し替える事をrebaseと呼びます。rebaseを利用する主な目的には逆方向マージ(マージの前にマージ先の変更をあらかじめ取り込む事)の代替手段マルチプルヘッドのマージ(≓無駄なマージ)を減らしリビジョングラフの可読性を高めるためなどが有ります。RebaseExtensionを利用する為の準備Mercurialでは履歴改変を行う(危険な?)機能はデフォルトで無効化されているため、rebaseを利用する為に設定が必要です。$HOME/.hgrcや%USERPROFILE%\mercurial.iniに次の記述を追加しましょう。=基本(ex1-*)rebaseの基本的な使い方について説明します。利用するリポジトリのリビジョングラフです。BASEこのリポジトリは次の設定で作成されています。リビジョン1、リビジョン2は自分の変更(かつ、中央リポジトリに反映されていない変更)リビジョン3、リビジョン4は他人の変更(中央リポジトリの変更)この分岐をいかにrebaseするかが最初のテーマです。rebase)ex1-1-basicのリポジトリに移動します。rebaseを行います。rebaseコマンドを実行してみましょう。BASELOCALのコミットの親リビジョンからBASEからOTHERに移動しました。(現在のリビジョンの親リビジョンが差し替えられました。XXXX'とうメッセージが有りました。これは実はrebaseはリビジョンを削除している為です。削除させないためには--keepオプションを利用します。ex1-2-keepのリポジトリに移動して確認して見ましょう。BASEex1-2-keepリポジトリはex1-1-basicリポジトリと同じ内容です。--keepを行います。BASEリビジョン5、リビジョン6という新しいリビジョンが作成されています。このためLOCAL1とLOCAL2のコミットが重複しています。リビジョン1、リビジョン2を削除(MQ拡張のstripコマンド)するとex1-1-basicと同じリビジョングラフに変化します。BASEこのようにrebaseは移動させたいリビジョンを複製させた後、古いリビジョンを削除します。rebase初心者の場合や、複雑なrebaseを行う場合は--keepオプションを利用しましょう。4)ex1-1-basic、ex1-2-keepの場合、リビジョン2上でrebaseを実施しました。リビジョン4上でrebaseを実施したい場合はどうすれば良いのでしょうか?ex1-3-dest-base-or-sourceのリポジトリに移動して確認して見ましょう。BASErebaseを実行してみましょう。rebaserebaseする必要が無いと言われてしまいました。これはrebaseがリビジョン4とリビジョン3をリビジョン2に移動させようとしているからです。これは意図ではありませんし、公な履歴を改変しています。リビジョン2、リビジョン1を移動させる場合には次のコマンドを使います。BASEオプションはそれぞれ次の意味を持ちます。そのリビジョンの祖先を移動させる。そのリビジョンの子孫として移動させる(移動先)また、次のコマンドでも同じ意味になります。4オプションは次の意味を持ちます。そのリビジョンの子孫を移動させる。この例の通り、通常--baseと--sourceオプションはどちらか一方を指定します。--collapse)rebaseのおまけ機能でrebaseするリビジョンを1つに圧縮します。ex1-4-collapseのリポジトリに移動して確認して見ましょう。BASEこの状態で--collapseオプションを付けてrebaseします。BASEリベースしたリビジョンは2つではなく1つになりました。--collapseオプションの注意点collapseオプションはある程度便利な機能ですが、rebaseの中でリビジョンを1つにするとコンフリクト時に混乱するので、rebaseとの併用はオススメしません。Collapse拡張などを利用してrebase後に実施するのをオススメします。コンフリクトが発生したら(ex2-*)rebase時にコンフリクトが発生したらどうするのでしょうか。ex2-conflictに移動して確認してみましょう。BASEこの状態でrebaseします。--continue)失敗しました。rebaseを再開してみましょう。resolve)コンフリクトを解決しろ!と怒られてしまいましたね。諦めて解決しましょう。BASEコンフリクトを解決したので、改めてrebaseを再開します。BASErebase出来ました。マージもrebase(ex3-*)ここまでの例でマージしていない履歴のrebaseについて説明してきました。ここでは「すでにマージしてしまったが、なんとかそこからrebaseしたい」場合にどうすればいいか説明します。ex3-1-merge-only一度マージしてしまった場合はどうなるのでしょうか?ex3-1-merge-onlyに移動して確認してみます。BASEこの状態で単なるrebaseは行えません。Mercurialからすると「マージしているのだからrebaseは不要だろう」という話のようです。rebaseこういう場合は--destで移動先を指定してrebaseしましょう。BASE履歴が一直線になりました。ex3-2-merge-and-commit-otherマージの後にコミットがある場合はどうなるでしょうか。ex3-2-merge-and-commit-otherはマージの後に他人がコミットをした場合の例です。BASE実はこの例では特にオプションを指定せずにrebaseできます。BASEさっぱりしました。ex3-3-merge-and-commit-local先ほどの例では、他人の変更がありましたが、自分の変更が有った場合はどうなるのでしょうか。ex3-3-merge-and-commit-localで確認します。BASEこの場合、現在のリビジョンには全ての履歴が含まれているため単にrebase出来ません。rebaseするためには--sourceと--destを指定します。BASELOCALのリビジョンが全て移動しました。ブランチ名の消失とその対策(ex4-*)今までの例は全て同じブランチ名での話でした。ブランチ名が設定されている場合のrebaseの挙動についても確認しましょう。利用するリポジトリのリビジョングラフです。BASEissue1という名前のブランチが存在します。ex4-1-disappear-branchでは早速移動してrebaseしてみましょう。場合と同じ形をしたリビジョングラフです。BASE履歴は一直線になりましたが、よく見るとissue1ブランチは消失しています。--keepbranches)ex4-1-disappear-branchではrebase時にブランチ名が消え去ってしまいました。rebaseにはこういうときの為のオプションが存在します。ex4-2-keep-branchで試してみましょう。BASEここで--keepbranchesオプションを付けてrebaseしてみましょう。BASEブランチ名が維持されました!ブランチ名の問題はイシュー毎にブランチを切る運用の中でrebaseを利用すると発生しがちな問題です。何をrebaseしたいのか、ブランチ名を維持したいのかを確認して、適切なオプションを利用しましょう。Bのrebaseを体験してみましょう。利用するリポジトリのリビジョングラフです。BASErebaseします。BASE履歴が一直線になる気持ちいいrebaseです。BASErebaseします。BASEリビジョンが一つ減りました。LOCAL1が中央リポジトリに反映済みの場合は、この形になる(一見中途半端な)rebaseを利用する事があります。BASErebaseします。BASEあまり良くないリビジョンが出来てしまいました。いうのも、リビジョン7は「LOCAL2の変更を含み、かつマージの変更を含む」リビジョンです。--detachが存在します。I(detach)」に当たる例です。BASE--detachオプション付きrebaseします。BASE今度はLOCAL2のみのマージを含まないリビジョンが作成されました。こちらの方がrebaseの意図通りです。--detachの注意点これも--collapseと同じでかなり危険な機能です。いうのも、これがうまくいく為にはLOCAL2がLOCAL1の変更に影響されない、独立した変更であることが要求されます。切り離し行う場合はrebaseではなくMQ拡張やMQ拡張とTransplant拡張を組み合わせて利用した方が安全に履歴改変を行えます。まとめrebaseの代表的な使い方を紹介しました。これ以外にも適応出来る場面はたくさんあると思いますが、用法用量を守って履歴改変をしていきましょう。rebaseだけが履歴改変の手段ではありません。様々な拡張(=MQ、Transplant、Collapse、etc)も駆使して履歴改変をしていきましょう。(3)はてなブログをはじめよう!troterさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。