Rebase エクステンション

現在、このエクステンションは Mercurial とともに配布されています。

作者: Stefano Tortarolo

設定

設定ファイル(例えば .hg/hgrc)でエクステンションを有効にしてください:

[extensions]
rebase =

はじめに

プロジェクトに貢献するときに、いくつかのパッチは非公開にしたまま、リポジトリ全体を最新の状態に保ちたい場合があります。

そういう場合には、一度手元の変更を"デタッチ"して、リポジトリをメインストリームと同期したあと、手元の変更をリモートから取得した最新の変更の上に追加するのが有効です。この手順を rebase(リベース) と呼びます。

一般に、このエクステンションを使って、リビジョンをある地点から別の地点に移動することができます。良くあるパターンを、"シナリオ" セクションで説明しています。

機能

使い方

概要

   hg rebase [--source REV | --base REV] [--dest REV] [--collapse] [--detach] [--keep] [--keepbranches] | [--continue] | [--abort]

説明

pullコマンドとの統合

このエクステンションによって、pullコマンドにオプションが追加されます。

   hg pull --rebase

これを指定すると、もしリベースするべきリビジョンが手元にある場合はプル後にリベースされ、なければhg pull --updateと同様の動作をします。

一般的なケース

このエクステンションを引数なしで実行することができるというのは重要なポイントです。

意味的には、引数なしのリベースは、 自分が今作業しているブランチを取って、正しい状態にする ことであると言えます。言い換えると、手元で行った変更を、チェックアウト中の名前つきブランチの最新HEAD上に移動することを意味します。

次のようなシチュエーションを考えてみましょう。:

L* は、最後にプルしてから手元で行った変更を表しています。

hg pull

メインストリームから、新しいリビジョンを2つプルしました。

たいてい、ここでやりたいのは L* を R2 の上に移動することです。それは、以下のように簡単にできます。:

hg rebase

結果:

Note: 前述の通り, これは hg pull --rebase で1アクションで実行できます。

衝突するマージの扱い

L* における変更が R* における変更と衝突することがあります。その場合、エクステンションは停止し、現在の状態を保存して、ユーザ自身が衝突を解消できるようにします。

リベースが中断したときには、2つの選択肢があります。:

中止

以下のコマンドで、中断されている処理は中止され、リポジトリは元の状態に戻ります。:

$ hg rebase --abort

続行

しかし、中断されている処理を再開する方が一般的です。それは以下のコマンドで出来ます:

$ hg rebase --continue

リベースが出来ない場合

リベースができないシチュエーションがいくつかあります。:

MQパッチに関する注意事項

現在の実装では、MQパッチはqfinishされ、リベース後にqimportされます。これによって、exportのようなヘッダがリベースされたパッチに追加されます。例えば、

シナリオ

ここからは、もっと興味深いシナリオを分析していきましょう。

シナリオ A

最初は、もっとも単純なパターンの、シンプルブランチです。

このシナリオでは、2つの興味深い相互作用があります。

トップへのリベース

$ hg up C
$ hg rebase -d E

以下のやり方でも同じ結果になります。:

$ hg up E
$ hg rebase -s C

中間リビジョンへのリベース

$ hg up C
$ hg rebase -d D

シナリオ B

2番目のシナリオには、もっと複雑なパターンが含まれます。このシナリオでは、アップストリームからクローンし、何度かマージを行っています。

Iの上にDをリベース

Iの上にBをリベース

Bの上にCをリベース

Iの上にGをリベース

Note: 親がリベース先の祖先の場合に 限り 、リベースによって親との関係が削除されます。 --detach オプションを指定すると、強制的にこの関係を削除します。

シナリオ C

このケースは、リポジトリがひとつだけの(マージされた)HEADを持つという、非常に一般的なシチュエーションを表しています。

Cの上にDをリベース

集約

複数のチェンジセットを、ひとつだけのリビジョンとして別のブランチにリベースできると便利なこともあります。

これは --collapse を指定すればできます。

Bの上にCを集約してリベース

詳細

親リビジョンとの関係付け

与えられたノード(N) をリベースする際に、その親の状態によってことなる結果になることがあります。

ここからは、 P1NN の一つ目の親、 P2N は二つ目の親を指すものとします。

例えば、 P1'N は、リベースされた N の一つ目の親です。

それらのシチュエーションは、以下の表にまとめられます。:

P2N = A

P2N = S

P2N = E

P2N = N

P1N = A

p1 = P2'N

p1 = target, p2 = P2N

p1 = target

P1N = S

p1 = P1'N

p1 = P1'N, p2 = P2'N

p1 = P1'N, p2 = P2N

p1 = P1'N

P1N = E

p1 = target, p2 = P1N

p1 = P2'N, p2 = P1N

p1 = target, p2 = P1N

A: リベース先の祖先 S: リベース対象内 E: 外部 N: なし

空のセルは、以下の場合にあたります。:

以下のことも注意してください:

コマンドのヘルプ

Mercurial 2.0では、以下がrebaseコマンドの公式なドキュメントです。

    Rebase uses repeated merging to graft changesets from one part of history
    (the source) onto another (the destination). This can be useful for
    linearizing *local* changes relative to a master development tree.

    You should not rebase changesets that have already been shared with
    others. Doing so will force everybody else to perform the same rebase or
    they will end up with duplicated changesets after pulling in your rebased
    changesets.

    If you don't specify a destination changeset ("-d/--dest"), rebase uses
    the tipmost head of the current named branch as the destination. (The
    destination changeset is not modified by rebasing, but new changesets are
    added as its descendants.)

    You can specify which changesets to rebase in two ways: as a "source"
    changeset or as a "base" changeset. Both are shorthand for a topologically
    related set of changesets (the "source branch"). If you specify source
    ("-s/--source"), rebase will rebase that changeset and all of its
    descendants onto dest. If you specify base ("-b/--base"), rebase will
    select ancestors of base back to but not including the common ancestor
    with dest. Thus, "-b" is less precise but more convenient than "-s": you
    can specify any changeset in the source branch, and rebase will select the
    whole branch. If you specify neither "-s" nor "-b", rebase uses the parent
    of the working directory as the base.

    By default, rebase recreates the changesets in the source branch as
    descendants of dest and then destroys the originals. Use "--keep" to
    preserve the original source changesets. Some changesets in the source
    branch (e.g. merges from the destination branch) may be dropped if they no
    longer contribute any change.

    One result of the rules for selecting the destination changeset and source
    branch is that, unlike "merge", rebase will do nothing if you are at the
    latest (tipmost) head of a named branch with two heads. You need to
    explicitly specify source and/or destination (or "update" to the other
    head, if it's the head of the intended source branch).

    If a rebase is interrupted to manually resolve a merge, it can be
    continued with --continue/-c or aborted with --abort/-a.

関連リンク


CategoryJapanese

English

JapaneseRebaseExtension (last edited 2012-11-07 14:41:13 by YuyaNishihara)