SYNOPSIS

git rebase [-i | --interactive] [<options>] [--exec <cmd>]
        [--onto <newbase> | --keep-base] [<upstream> [<branch>]]
git rebase [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
        --root [<branch>]
git rebase (--continue | --skip | --abort | --quit | --edit-todo | --show-current-patch)

DESCRIPTION

<branch> が指定されている場合、 「git rebase」は他の処理を行う前に自動で git switch <branch> を実行します。それ以外の場合は、引き続き現在のブランチに滞在しています。

<upstream> が指定されていない場合、 branch.<name>.remotebranch.<name>.mergebranch オプションで構成されたアップストリーム(詳細はgit-config(1) 参照) および --fork-point オプションが想定されています。あなたが現在ブランチを一切使用していない場合、または、現在のブランチにアップストリームが構成されていない場合、リベースは中止(abort)されます。

現在のブランチでコミットによって行われたが、 <upstream> に無いすべての変更は、一時領域(temporary area)に保存されます。 これは git log <upstream>..HEAD で表示されるのと同じコミットのセットで、または --fork-point がアクティブな場合 git log 'fork_point'..HEAD で表示されるのと同じコミットのセットで、または --root オプションが指定されている場合 git log HEAD で表示されるのと同じコミットのセットです。

現在のブランチは <upstream> にリセットされます。 または --onto オプションが指定されている場合は <newbase> にリセットされます。 これは、 git reset --hard <upstream> (または <newbase> )とまったく同じ効果があります。 ORIG_HEAD は、リセット前にブランチの先端を指すように設定されています。

Note
リベース中に、その疑似refを書き込む他のコマンド(例えば git reset)が使用された場合、リベースの最後で ORIG_HEAD が以前のブランチ先端を指していることは保証されません。 ただし、 以前のブランチの先端には、 現在のブランチの reflog を使用してアクセスできます(つまり @{1} です。 gitrevisions(7) 参照)。

以前に一時領域に保存されたコミットは、現在のブランチに1つずつ順番に再適用されます。注意: HEAD..<upstream> でのコミットと同一のテキスト変更を導入する HEAD でのコミットは省略されることに注意してください(つまり、異なるコミットメッセージまたはタイムスタンプで、アップストリームで既に受け入れ済のパッチはスキップされます)。

マージに失敗すると、このプロセスが完全には自動で行われなくなる事があります。あなたは、このようなマージの失敗を解決し、そして git rebase --continue を実行する必要があります。 別のオプションとしては、 git rebase --skip でマージの失敗を引き起こしたコミットをバイパスすることです。そして、元の <branch> をチェックアウトし、.git/rebase-apply 作業ファイルを削除するには、代わりにコマンド git rebase --abort を使用します。

以下の履歴が存在し、現在のブランチが topic であるとします:

          A---B---C topic
         /
    D---E---F---G master

この時点で、以下のコマンドのいずれかを実行します:

git rebase master
git rebase master topic

そうすると以下のようになります:

                  A'--B'--C' topic
                 /
    D---E---F---G master

注意 : 後者の形式は、 git checkout topic の後に git rebase master が続く省略形です。 リベースが終了すると、チェックアウトされたブランチ(topic)のままになります。

(たとえば、アップストリームに適用されたパッチをメールで送信したため)アップストリームブランチにすでに行った変更が含まれている場合、そのコミットはスキップされ、警告が発行されます(merge バックエンドが使用されている場合)。たとえば、以下の履歴で git rebase master を実行します(A'A は同じ変更セットを導入しますが、コミッター情報は異なります):

          A---B---C topic
         /
    D---E---A'---F master

これの結果は以下のようになります:

                   B'---C' topic
                  /
    D---E---A'---F master

これは、あるブランチに基づいてトピックブランチを別のブランチに移植し、 rebase --onto を使用して、トピックブランチを後者のブランチからフォークしたふりをする方法です。

まず、「topic」がブランチ「next」に基づいているとしましょう。 たとえば「topic」で開発された機能は、「next」にあるいくつかの機能に依存しています。

    o---o---o---o---o  master
         \
          o---o---o---o---o  next
                           \
                            o---o---o  topic

我々は topic をブランチ master からフォークさせたいのです。たとえば「topic」が依存する機能が、より安定した「master」ブランチにマージされたためです。 ツリーを以下のようにしたいわけです:

    o---o---o---o---o  master
        |            \
        |             o'--o'--o'  topic
         \
          o---o---o---o---o  next

これは、以下のコマンドを使用して取得できます:

git rebase --onto master next topic

--onto オプションの別の例は、ブランチの一部をリベースすることです。 以下のような状況の場合:

                            H---I---J topicB
                           /
                  E---F---G  topicA
                 /
    A---B---C---D  master

そして、以下のコマンドを実行します

git rebase --onto master topicA topicB

そうすると結果は以下のようになります:

                 H'--I'--J'  topicB
                /
                | E---F---G  topicA
                |/
    A---B---C---D  master

これは、topicBがtopicAに依存していない場合に役立ちます。

コミットの範囲は、リベースで削除することもできます。以下の状況の場合:

    E---F---G---H---I---J  topicA

そして、以下のコマンドを実行します

git rebase --onto topicA~5 topicA~3 topicA

上記を実行すると、以下のようにコミットFとGが削除されます:

    E---H'---I'---J'  topicA

これは、 F と G に何らかの欠陥がある場合、または、topicA の一部であってはならない場合に役立ちます。注意: --onto<upstream> パラメーターの引数は、任意の有効なコミットっぽい何か(commit-ish)にすることができることに注意してください。

競合が発生した場合、 git rebase は最初の問題のあるコミットで停止し、ツリーに競合マーカーを残します。 あなたは git diff を使用して、マーカー(<<<<<<)を見つけ、編集して競合を解決できます。編集するファイルごとに、競合が解決されたことをGitに通知する必要があります。通常、これは以下の方法で行います

git add <filename>

競合を手動で解決し、あなたが望んだ解決策でインデックスを更新した後、以下のコマンドでリベースプロセスを続行できます

git rebase --continue

あるいは、以下のように git rebase を元に戻す(undo)こともできます

git rebase --abort

MODE OPTIONS

このセクションの各オプションは、このセクションのオプションを組み合わせる事も含めて、他のオプションと一緒に使うことはできません。

--continue

マージの競合を解決した後、リベースプロセスを再開します。

--skip

現在のパッチをスキップして、リベースプロセスを再開します。

--abort

リベース操作を中止(abort)し、 HEAD を元のブランチにリセットします。リベース操作の開始時に <branch> が指定された場合、HEAD<branch> にリセットされます。それ以外の場合、 HEAD はリベース操作が開始されたときの位置にリセットされます。

--quit

リベース操作を中止(abort)しますが、HEADは元のブランチにリセットされません。その結果、インデックスと作業ツリーも変更されません。 --autostash を使用して一時的なstashエントリが作成された場合、それはstashリストに保存されます。

--edit-todo

対話リベース中にToDoリストを編集します。

--show-current-patch

対話的なリベース、または、競合のためにリベースが停止されたときに、現在のパッチを表示します。 これは git show REBASE_HEAD と同等です。

OPTIONS

--onto <newbase>

新しいコミットを作成する開始点を指定します。 --onto オプションが指定されていない場合、開始点は <upstream> です。これは、既存のブランチ名だけでなく、任意の有効なコミットである可能性があります。

特別な場合として、マージベースが1つしかない場合は、あなたはAとBのマージベースのショートカットとして "A...B" を使用できます。最大でAとBのいずれかを省略できます。その場合、デフォルトでHEADになります。

--keep-base

<upstream><branch> のマージベースへの新しいコミットを作成する開始点を設定します。 git rebase --keep-base <upstream> <branch> を実行することは git rebase --reapply-cherry-picks --no-fork-point --onto <upstream>...<branch> <upstream> <branch> を実行することと同等です。

このオプションは、アップストリームブランチの先頭で機能を開発している場合に役立ちます。この機能が働いている間に、アップストリームのブランチが進むことがあり、アップストリームの先頭にリベースを続けるのは得策ではなく、ベースのコミットをそのままにしておくことがあります。基底のコミットは変更されないので、このオプションはコミットの損失を避けるために --reapply-cherry-picks を暗黙的に指定します。

このオプションと --fork-point はどちらも <upstream><branch> の間のマージベースを検索します。しかし、このオプションは新しいコミットが作成される「開始点」としてマージベースを使用します。一方 --fork-point はマージベースを使用して、リベースされる「コミットのセット」を決定します。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

<upstream>

比較するアップストリームブランチ。既存のブランチ名だけでなく、任意の有効なコミットである可能性があります。デフォルトは、現在のブランチ用に構成されたアップストリームです。

<branch>

作業するブランチ。デフォルトはHEADです。

--apply

適用戦略(applying strategies)を使用してリベースします(内部で git-am を呼び出します)。このオプションは、マージバックエンドがapplyのすべてを処理すると、将来的には動作しなくなる可能性があります。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--empty={drop,keep,ask}

任意のアップストリームコミットの、開始時は空ではなく、かつ、クリーンでは無いチェリーピックであるが、(すでにアップストリームの変更のサブセットが含まれているため、)リベース後に空になるコミットを処理する方法。dropを使用すると、空になるコミットはドロップされます(これがデフォルトです)。keepを使用すると、そのようなコミットは保持されます。 ask を使用すると、空のコミットが適用されるとリベースが停止し、ドロップするか、ファイルをさらに編集するか、空の変更をコミットするかを選択できます(--interactive の指定を含んでいます)。--exec などの他のオプションでは、 -i/--interactive が明示的に指定されていない限り、デフォルトのドロップが使用されます。

注意: (--no-keep-empty が指定されていない場合、)空で開始するコミットは保持され、(--reapply-cherry-picks または --keep-base が渡されない限り)準備ステップとして、( git log --cherry-mark ... によって決定される)クリーンなチェリーピックであるコミットが検出・ドロップされます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--no-keep-empty
--keep-empty

リベースの前に空で始まるコミット(つまり、親から何も変更していないコミット)を結果に残さないようにします。 なぜなら、そのようなコミットを作成するには git commit--allow-empty というオーバーライドするフラグを渡す必要があり、これはユーザーが意図的にそのようなコミットを作成し、それを保持したいことを意味しているからです。

対話的なリベースを起動し、不要なコミットに対応する行を削除するだけで、空で始まるコミットを取り除くことができるため、このフラグの使用はおそらくまれです。 このフラグは、外部ツールが多くの空のコミットを生成し、それらをすべて削除したい場合などの為の便利なショートカットとして存在します。

開始時は空でないが、リベース後に空になるコミットについては、 --empty フラグを参照してください。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--reapply-cherry-picks
--no-reapply-cherry-picks

我先にドロップしてしまうのではなく、アップストリームコミットのすべてのクリーンなチェリーピックを再適用します。 (これらのコミットがリベース後に空になった場合、それらにはすでにアップストリームの変更のサブセットが含まれているため、それらに対する動作は `--empty`フラグによって制御されます。)

--keep-base がない場合(または --no-reapply-cherry-picks が指定されている場合)、これらのコミットは自動的にドロップされます。これにはすべてのアップストリームコミットを読み取る必要があるため、読み取る必要のあるアップストリームコミットが多数あるリポジトリではコストがかかる可能性があります。 merge バックエンドを使用する場合、(--quiet が指定されていない限り)ドロップされたコミットごとに警告が発行されます。 advice.skippedCherryPicks がfalseに設定されていない限り、アドバイスも表示されます (git-config(1) を参照)。

--reapply-cherry-picks を使用すると、リベースはすべてのアップストリームコミットの読み取りを放棄できるため、パフォーマンスが向上する可能性があります。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--allow-empty-message

何も操作しません。空のメッセージでコミットをリベースすると失敗(fail)しますが、このオプションはその動作をオーバーライドし、空のメッセージを含むコミットをリベースできます。つまり、空のメッセージでコミットしても、リベースは停止(halt)しません。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

-m
--merge

マージ戦略(merging strategies)を使用してリベースします(デフォルト)。

リベースマージは、<upstream>ブランチの上にある作業ブランチからの各コミットをリプレイすることによって機能することに注意してください。このため、マージの競合が発生した場合、 ours として報告される側は、<upstream>で始まるこれまでのリベースされたシリーズであり、 theirs は作業ブランチです。 つまり、サイドが入れ替わっています。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

-s <strategy>
--strategy=<strategy>

デフォルトの ort の代わりに、指定のマージ戦略を使用します。 このオプションは --merge の指定を含んでいます。

git rebase は、指定された戦略を使用して<upstream>ブランチの上にある作業ブランチからの各コミットをリプレイするため、 ours 戦略を使用すると、<branch>からすべてのパッチが空になります。これはほとんど意味がありません。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

-X <strategy-option>
--strategy-option=<strategy-option>

<strategy-option>をマージ戦略に渡します。 これは --merge の指定を含んでいて、戦略が指定されていない場合は -s ort を意味します。 -m オプションにて上記で述べたように、「ours」と「theirs」が逆になっていることに注意してください。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--rerere-autoupdate
--no-rerere-autoupdate

rerere メカニズムが現在の競合で記録された解決を再利用して作業ツリー内のファイルを更新した後、解決の結果でインデックスも更新できるようにします。 --no-rerere-autoupdate は、別の git add で結果をインデックスにコミットする前に、「rerere」が行ったことを再確認し、潜在的な間違いマージ(mismerges)を捉える良い方法です。

-S[<keyid>]
--gpg-sign[=<keyid>]
--no-gpg-sign

GPG署名コミットです。 keyid 引数はオプションであり、デフォルトでコミッターIDになります。 指定する場合は、スペースなしでオプションに串刺しする必要があります。 --no-gpg-sign は、commit.gpgSign 構成変数と、それより前で指定した --gpg-sign オプションの、その両方を打ち消すのに役立ちます。

-q
--quiet

静かにします。--no-stat の指定を含みます。

-v
--verbose

おしゃべりにします。 --stat の指定を含みます。

--stat

最後のリベース以降にアップストリームで変更されたもののdiffstatを表示します。 diffstatは、構成オプション rebase.stat によっても制御されます。

-n
--no-stat

リベース処理の一部としてdiffstatを表示しないでください。

--no-verify

このオプションは、リベース前のフック(pre-rebase hook)をバイパスします。 githooks(5) も参照してください。

--verify

リベース前フック(pre-rebase hook)の実行を許可します。これがデフォルトです。このオプションは、 --no-verify をオーバーライドするために使用できます。 githooks(5) も参照してください。

-C<n>

各変更の前後で、少なくとも <n> 行の周囲のコンテキストが一致することを確認する。 周囲の文脈の行数が少ない場合は、すべて一致させなければならない。 デフォルトでは、コンテキストは無視されます。 --apply の指定を含んでいます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--no-ff
--force-rebase
-f

変更されていないコミットを早送りす(fast-forward)るのではなく、リベースされたすべてのコミットを個別にリプレイします。これにより、リベースされたブランチの履歴全体が新しいコミットで構成されることが保証されます。

トピックブランチのマージを取り消した後にこのオプションを使うと便利です。このオプションはトピックブランチを新しいコミットで再作成するので、「戻しを戻す」(revert the reversion)必要はありません (詳細は revert-a-faulty-merge How-To をご覧ください)。

--fork-point
--no-fork-point

<branch>によって導入されたコミットを計算するときに、reflogを使用して、<upstream>と<branch>の間の、より一般的な祖先を見つけます。

--fork-point がアクティブな場合、<upstream>の代わりに fork_point を使用して、リベースするコミットのセットを計算します。ここで、 fork_point は、 git merge-base --fork-point <upstream> <branch> コマンドの結果です(git-merge-base(1) 参照)。 fork_point が空になると、<upstream>がフォールバックとして使用されます。

コマンドラインで <upstream> または --keep-base が指定されている場合、デフォルトは --no-fork-point です。それ以外の場合、デフォルトは --fork-point です。 git-config(1)rebase.forkpoint も参照してください。

あなたのブランチが<upstream>に基づいていたが、<upstream>が巻き戻され、あなたのブランチにドロップされたコミットが含まれている場合、あなたのブランチからそれらのコミットをドロップするために、このオプションを --keep-base とともに使用できます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--ignore-whitespace

差分を調整しようとするときは、空白の違いを無視してください。現在、各バックエンドはこの振る舞いの近似を実装しています:

apply backend

パッチを適用するときは、コンテキスト行の空白(whitespace)の変更を無視してください。残念ながら、これは、パッチによって置き換えられる「古い」行が既存のファイルと空白(whitespace)のみが異なる場合、パッチアプリケーションが成功する代わりに、マージの競合が発生することを意味します。

merge backend

空白(whitespace)のみが変更された行は、マージ時に変更されていないものとして扱います。残念ながら、これは、反対側に競合する変更がなかったとしても、空白(whitespace)を変更することを目的としたパッチハンクがドロップされることを意味します。

--whitespace=<option>

このフラグは、パッチを適用する git apply プログラム(git-apply(1) 参照)に渡されます。 --apply の指定を含んでいます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--committer-date-is-author-date

現在の時刻をコミッターの日付として使用する代わりに、リベースされるコミットの作成者の日付をコミッターの日付として使用します。このオプションは、 --force-rebase の指定を含んでいます。

--ignore-date
--reset-author-date

元のコミットの作成者の日付を使用する代わりに、現在の時刻をリベースされたコミットの作成者の日付として使用します。 このオプションは、 --force-rebase の指定を含んでいます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--signoff

すべてのリベースされたコミットに Signed-off-by トレーラーを追加します。注意: --interactive が指定されている場合、pick または edit または reword のマークが付けられたコミットのみにトレーラーが追加されることに注意してください。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

-i
--interactive

リベースされようとしているコミットのリストを作成します。リベースする前に、ユーザーにそのリストを編集させます。このモードは、コミットの分割にも使用できます(以下の「SPLITTING COMMITS」を参照)。

コミットリストの書式は、構成オプション rebase.instructionFormat を設定することで変更できます。カスタマイズされた命令書式では、書式の前に長いコミットハッシュが自動的に追加されます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

-r
--rebase-merges[=(rebase-cousins|no-rebase-cousins)]
--no-rebase-merges

デフォルトでは、リベースはtodoリストからマージコミットを削除し、リベースされたコミットを単一の線形ブランチに配置します。 --rebase-merges を使用すると、リベースは代わりに、マージコミットを再作成することにより、リベースされるコミット内の分岐構造を保持しようとします。これらのマージコミットで解決されたマージの競合または手動の修正(amend)は、手動で 解決/再適用 する必要があります。 --no-rebase-merges は、 rebase.rebaseMerges 設定オプションと、 --no-rebase-merges より前で指定された --rebase-merges の両方を無効にするために使用できます。

マージをリベースする場合、 rebase-cousins (いとこ)と no-rebase-cousins (非いとこ)の 2 つのモードがあります。モードが指定されていない場合は、 no-rebase-cousins がデフォルトです。 no-rebase-cousins モードでは、直接の祖先として <upstream> を持たないコミットはオリジナルの分岐点を保持します。 つまり、 git-log(1)--ancestry-path オプションによって除外されるコミットは、デフォルトではオリジナルの祖先を保持します。 rebase-cousins モードでは、そのようなコミットは、 代わりに <upstream> (または指定されている場合は <onto>) にリベースされます。

現在、 ort マージ戦略を使用してのみマージコミットを再作成することが可能です。異なるマージ戦略は、明示的な exec git merge -s <strategy> [...] コマンドを介してのみ使用できます。

下記の「REBASING MERGES」と「INCOMPATIBLE OPTIONS」も参照してください。

-x <cmd>
--exec <cmd>

最終履歴にコミットを作成する各行の後に exec <cmd> を追加します。 <cmd> は、1つ以上のシェルコマンドとして解釈されます。 失敗したコマンドは、exit code 1でリベースを中断(interrupt)します。

--exec の1つのインスタンスを複数のコマンドで使用することにより、複数のコマンドを実行できます:

git rebase -i --exec "cmd1 && cmd2 && ..."

または、複数の --exec を指定します:

git rebase -i --exec "cmd1" --exec "cmd2" --exec ...

--autosquash が使用されている場合、 exec 行は中間コミットに追加されず、各 squash/fixup シリーズの最後にのみ現れます。

これは内部で --interactive 機構を使用しますが、明示的な --interactive の指定なしで実行できます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--root

<upstream>で制限するのではなく、<branch>から到達可能なすべてのコミットをリベースします。 これにより、ブランチのルートコミットをリベースできます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--autosquash
--no-autosquash

コミットログメッセージが「squash! …」または「fixup! …」または「amend! …」で始まり、同一の ... に一致するコミットがすでにtodoリストにある場合、 rebase -i のtodoリストを自動的に変更して、squashするようにマークされたコミットが、変更するコミットの直後に来るようにし、移動したコミットのアクションをそれぞれ pick から、 squash または fixup または fixup-C に変更します。 コミットの件名が一致する場合、または ... がコミットのハッシュを参照する場合、コミットは ... と一致します。フォールバックとして、コミットサブジェクトの部分一致も機能します。 fixup/amend/squash コミットを作成するための推奨される方法は、 git-commit(1) のそれぞれ --fixup または --fixup=amend: または --fixup=reword: と、--squash オプションを使用することです。

構成変数 rebase.autoSquash を使用して --autosquash オプションがデフォルトで有効になっている場合、このオプションを使用して、この設定をオーバーライドおよび無効にすることができます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

--autostash
--no-autostash

操作を開始する前に一時的なスタッシュエントリを自動的に作成し、操作の終了後に適用します。これは、汚れたワークツリー(dirty worktree)でリベースを実行できることを意味します。ただし、注意して使用してください。リベース成功後のスタッシュ適用の際、重要な競合を引き起こす可能性があります。

--reschedule-failed-exec
--no-reschedule-failed-exec

失敗した exec コマンドを自動的に再スケジュールします。 これは、対話モード(または --exec オプションが提供された場合)でのみ意味があります。

このオプションは、リベースが開始されると適用されますが、これは、 rebase.rescheduleFailedExec 構成(git-config(1) または 下記「CONFIGURATION」参照)、またはこのオプションが提供されているかどうかに基づいて、最初にリベース全体に設定されます。でなければ、開始時の明示的な --no-reschedule-failed-exec が、 rebase.rescheduleFailedExec=true 構成の存在によって上書きされます。

--update-refs
--no-update-refs

リベースされているコミットを指すブランチを自動的に強制更新します。 ワークツリーでチェックアウトされたブランチは、この方法では更新されません。

構成変数 rebase.updateRefs が設定されている場合、このオプションを使用して、この設定をオーバーライドして無効にすることができます。

下記の「INCOMPATIBLE OPTIONS」(互換性のないオプション)も参照してください。

INCOMPATIBLE OPTIONS(互換性の無いオプション)

これらのオプション:

  • --apply

  • --whitespace

  • -C

は、以下のオプションと互換性がありません:

  • --merge

  • --strategy

  • --strategy-option

  • --autosquash

  • --rebase-merges

  • --interactive

  • --exec

  • --no-keep-empty

  • --empty=

  • --[no-]reapply-cherry-picks--keep-base なしで使用した場合

  • --update-refs

  • --root--onto 無しで使用した場合

さらに、以下のオプションの組み合わせには互換性がありません:

  • --keep-base--onto

  • --keep-base--root

  • --fork-point--root

BEHAVIORAL DIFFERENCES(振る舞いの違い)

git rebaseには、 applymerge の2つの主要バックエンドがあります。 (apply バックエンドは以前は am バックエンド と呼ばれていましたが、名詞ではなく動詞のように見えるため混乱を招きました。また、 merge バックエンドは以前は interactive バックエンドと呼ばれていましたが、現在は 非対話型の場合にも使用されます。どちらも、それぞれを支える低レベルの機能に基づいて名前が変更されました。)これら2つのバックエンドの振る舞いには微妙な違いがあります:

空のコミット

apply バックエンドは、残念ながら意図的に空のコミット、つまり空で開始されたコミットを削除しますが、これらは実際にはまれです。また、空になるコミットを削除したり、その振る舞いを制御するオプションがありません。

merge バックエンドは、デフォルトで意図的に空のコミットを保持します(ただし、 -i を使用すると、todoリストエディタでemptyとしてマークされます。または、 --no-keep-empty を使用して自動的に削除できます)。

適用バックエンドと同様に、デフォルトでは、mergeバックエンドは、 -i/--interactive が指定されていない限り、空になるコミットをドロップします(この場合、mergeバックエンドは停止(stop)し、ユーザーに何をすべきかを尋ねます)。mergeバックエンドには、空になったコミットの処理動作を変更するための --empty={drop,keep,ask} オプションもあります。

ディレクトリ名変更の検知

正確なツリー情報が不足している(パッチで利用可能な限られた情報で偽の祖先を構築するために生じる)ため、 apply バックエンドでディレクトリ名変更の検出が無効になっています。 ディレクトリ名前変更の検出が無効になっているということは、 履歴の一方がディレクトリの名前を変更し、 もう一方が古いディレクトリに新しいファイルを追加した場合に、 リベース時にこれらのファイルを新しいディレクトリに移動したいという警告なしに、 新しいファイルが古いディレクトリに残されます。

ディレクトリ名変更の検出は、 merge バックエンドと連携して、このような場合に警告を出します。

Context

適用バックエンドは、(内部で format-patch を呼び出すことにより、)パッチのシーケンスを作成し、次にパッチを順番に適用することにより(内部で am を呼び出すことにより)機能します。パッチは複数のハンクで構成されており、それぞれに行番号、コンテキストリージョン、および実際の変更が含まれています。反対側がファイルの前に行を挿入または削除した可能性があるため、行番号はある程度曖昧にする必要があります。コンテキスト領域(context region)は、正しい行に変更を適用するために行番号を調整する方法を見つけるのに役立つことを目的としています。ただし、コードの複数の領域に同じ周囲のコンテキスト行がある場合、間違った領域が選択される可能性があります。これにより、競合が報告されずにコミットが誤って再適用される実際のケースがあります。 diff.context をより大きな値に設定すると、このようなタイプの問題を防ぐことができますが、誤った競合の可能性が高くなります(適用するには、一致するコンテキストの行がより多く必要になるため)。

merge バックエンドは、関連する各ファイルの完全なコピーを使って動作し、これらの種類の問題からファイルを保護します。

Labelling of conflicts markers

コンテンツの競合がある場合、マージ機構は、コンテンツが由来するコミットでそれぞれの側の競合マーカーに注釈を付けようとします。 apply バックエンドは、リベースされたコミットとその親に関する元の情報を削除するため(代わりに、生成されたパッチの限られた情報に基づいて新しい偽のコミットを生成します)、それらのコミットを識別できません。 代わりに、コミットの要約にフォールバックする必要があります。また、 merge.conflictStyle が diff3 または zdiff3 に設定されている場合、 apply バックエンドは「構築されたマージベース」を使用してマージベースのコンテンツにラベルを付けるため、マージベースのコミットに関する情報は一切提供されません。

merge バックエンドは、履歴の両側で完全なコミットで動作するため、そのような制限はありません。

フック

apply バックエンドは従来、コミット後フック(post-commit hook)を呼び出していませんでしたが、 merge バックエンドは呼び出していました。 merge バックエンドはその出力を黙らせましたが、いまだ両方ともチェックアウト後フック(post-checkout hook)を呼び出します。さらに、両方のバックエンドは、中間コミットや最終コミットではなく、リベースの開始点コミットでのみチェックアウト後フック(post-checkout hook)を呼び出します。いずれの場合も、これらのフックの呼び出しは、そう設計したのではなく、実装の偶然によるものでした(両方のバックエンドは元々シェルスクリプトとして実装されており、フックを呼び出す git checkout ` や `git commit などの他のコマンドをたまたま呼び出していました)。どちらが正しいかは完全には明らかではありませんが、両方のバックエンドの動作は同じであるべきです。将来的には、リベースがこれらのフックのいずれかを呼び出すのを停止する可能性があります。

Interruptability(割り込み可能性)

apply バックエンドには、タイミングの悪い割り込みによる安全上の問題があります。ユーザーが間違ったタイミングで Ctrl-C を押してリベースを中止しようとすると、リベースは、後続の git rebase --abort で中止できない状態になる可能性があります。 merge バックエンドには、同様の欠点は見られません。(詳細については、 https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ を参照してください。)

Commit Rewording

リベース中に競合が発生すると、リベースが停止(stop)し、ユーザーに解決を求めます。 ユーザーは競合の解決中に注目すべき変更を加える必要がある場合があるため、競合が解決され、ユーザーが git rebase --continue を実行した後、リベースはエディターを開き、ユーザーにコミットメッセージを更新するように依頼する必要があります。 merge バックエンドはこれを行いますが、 apply バックエンドは元のコミットメッセージを盲目的に適用します。

Miscellaneous differences

ほとんどの人がおそらく取るに足らないと考えるであろうが、完全性のために言及されているいくつかの振る舞いの違いがあります:

  • Reflog: 2つのバックエンドは、reflogで行われた変更を説明するときに異なる表現を使用しますが、どちらも「リベース」という単語を使用します。

  • 進行状況、情報、エラーメッセージ について: 2つのバックエンドは、わずかに異なる進行状況と情報メッセージを提供します。また、applyバックエンドはエラーメッセージ(「Your files would be overwritten…」など)をstdoutに書き込み、mergeバックエンドはそれらをstderrに書き込みます。

    • 状態ディレクトリ: 2つのバックエンドは、 .git/ の下の異なるディレクトリに状態を保持します

MERGE STRATEGIES

マージ機構(git mergegit pull コマンド)では、バックエンドの「マージ戦略」を -s オプションで選択することができます。 いくつかの戦略では、独自のオプションを指定することができます。これは、 git mergegit pull-X<option> 引数として渡すことができます。

ort

これは、1つのブランチをプルまたはマージするときのデフォルトのマージ戦略です。この戦略では、3方向マージアルゴリズムを使用して2つのヘッドのみを解決できます。3方向マージに使用できる共通の祖先が複数ある場合は、共通の祖先のマージされたツリーを作成し、それを3方向のマージの参照ツリーとして使用します。これにより、Linux 2.6カーネルの開発履歴から取得した実際のマージコミットで実行されたテストによって、誤ったマージを引き起こすことなく、マージの競合が少なくなることが報告されています。さらに、この戦略では、名前の変更を伴うマージを検出して処理できます。検出されたコピーは使用しません。このアルゴリズムの名前は "Ostensibly Recursive’s Twin" (表面上は再帰の双子)の頭文字を取ったものであり、以前のデフォルトのアルゴリズムである「recursive」の代わりとして作成されたという事実に由来しています。

ort 戦略は、以下のオプションを取ることができます:

ours

このオプションは、「our」バージョンを優先することにより、競合するハンクをクリーンに自動解決するように強制します。 our側と競合しない他のツリーからの変更は、マージ結果に反映されます。 バイナリファイルの場合、内容全体がour側から取得されます。

これを「ours」マージ戦略と混同しないでください。この戦略では、他のツリーに何が含まれているのかさえまったく調べません。それは他のツリーが行ったすべてを破棄し、「our」履歴にはその中で起こったすべてが含まれていると宣言します。

theirs

これは「ours」の反対です。 「ours」とは異なり、このmergeオプションを混同する「theirs」マージ戦略はないことに注意してください。

ignore-space-change
ignore-all-space
ignore-space-at-eol
ignore-cr-at-eol

指示されたタイプの空白(whitespace)の変更を含む行を、3方向マージのために変更されていないものとして扱います。行に対する、他の変更と空白(whitespace)の変更との混合は、無視されません。 git-diff(1)-b-w--ignore-space-at-eol--ignore-cr-at-eol も参照してください。

  • 「their」バージョンが行に空白の変更のみを導入する場合、「our」バージョンが使用されます。

  • 「our」バージョンで空白の変更が導入されたが、「their」バージョンに大幅な変更が含まれている場合は、「their」バージョンが使用されます。

  • それ以外の場合、マージは通常の方法で進行します。

renormalize

これにより、3方向マージを解決するときに、ファイルの3つのステージすべての仮想チェックアウトとチェックインが実行されます。このオプションは、ブランチをさまざまなクリーンフィルターまたは行末正規化ルールとマージするときに使用することを目的としています。詳細については、 gitattributes(5) の「Merging branches with differing checkin/checkout attributes」(チェックイン/チェックアウト属性が異なるブランチのマージ)を参照してください。

no-renormalize

renormalize オプションを無効にします。 これは、 merge.renormalize 構成変数をオーバーライドします。

find-renames[=<n>]

名前変更(rename)の検出をオンにし、オプションで類似性のしきい値(similarity threshold)を設定します。これがデフォルトです。 これは、 merge.renames 構成変数をオーバーライドします。 git-diff(1)--find-renames も参照してください。

rename-threshold=<n>

find-renames=<n> の非推奨の同義語。

subtree[=<path>]

このオプションは「subtree」戦略をさらに発展させたもので、2つの木をマージする際に、どのようにずらせば互いにマッチするかを推測するものである。その代わり、指定されたパスは、2つの木の形が一致するように前置される(または、最初から取り除かれる)。

recursive

これは、3方向マージアルゴリズムを使用して2つのヘッドのみを解決できます。3方向マージに使用できる共通の祖先が複数ある場合は、共通の祖先のマージされたツリーを作成し、それを3方向のマージの参照ツリーとして使用します。 これにより、Linux 2.6カーネルの開発履歴から取得した実際のマージコミットで実行されたテストによって、誤ったマージを引き起こすことなく、マージの競合が少なくなることが報告されています。 さらに、これにより、名前変更を含むマージを検出して処理できます。 検出されたコピーは使用しません。 これは、Git v0.99.9k 〜 v2.33.0 まで、2つのヘッドを解決するためのデフォルトの戦略でした。

「recursive」(再帰的)戦略は「ort」と同じオプションを取る。 しかし、「ort」が無視する3つのオプション(上記には書かれていない)があり、 「recursive」戦略で有用となる可能性がある:

patience

diff-algorithm=patience の非推奨の同義語。

diff-algorithm=[patience|minimal|histogram|myers]

マージ中に別の差分アルゴリズムを使用すると、重要でない一致行(異なる関数の中括弧など)が原因で発生するミスマージを回避できます。 git-diff(1) --diff-algorithm も参照してください。注意: 特に、「ort」は diff-algorithm=histogram を使用しますが、「recursive」はデフォルトで 「diff.algorithm」 設定を使う事に注意して下さい。

no-renames

名前変更(rename)の検出をオフにします。 これは、merge.renames 構成変数をオーバーライドします。 git-diff(1)--no-renames も参照してください。

resolve

これは、3方向マージアルゴリズムを使用して、2つのヘッド(つまり、現在のブランチとプルした別のブランチ)のみを解決できます。 交差マージ(criss-cross merge)のあいまいさを注意深く検出しようとします。 名前の変更は処理しません。

octopus

これにより、3つ以上のヘッドを持つケースが解決されますが、手動解決が必要な複雑なマージの実行は拒否されます。これは主に、トピックの分岐ヘッドを纏めるために使用されることを意図しています。これは、複数のブランチをプルまたはマージする場合のデフォルトのマージ戦略です。

ours

これにより、任意の数のヘッドが解決されますが、結果として得られるマージのツリーは常に現在のブランチヘッドのツリーであり、他のすべてのブランチからのすべての変更を事実上無視します。 これは、サイドブランチの古い開発履歴に取って代わるために使用されることを意図しています。 これは、「recursive」マージ戦略の -Xours オプションとは異なることに注意してください。

subtree

これは改造された「ort」戦略です。 ツリーAとBをマージするとき、BがAのサブツリーに対応する場合、同じレベルのツリーを読み取るのではなく、Bは最初にAのツリー構造に一致するように調整されます。 この調整は、共通の祖先ツリーに対しても行われます。

3方向マージ(デフォルトの「ort」を含む)を使用する戦略では、両方のブランチで変更が行われたが、後で一方のブランチで元に戻された場合、その変更はマージされた結果に表示されます。一部の人々は、この振る舞いを混乱させると感じています。これは、個々のコミットではなく、ヘッドとマージベースのみがマージの実行時に考慮されるために発生します。したがって、マージアルゴリズムは、元に戻された変更をまったく変更なしと見なし、代わりに変更されたバージョンに置き換えます。

NOTES

あなたは共有リポジトリで git rebase を使用することの意味を理解する必要があります。下記「RECOVERING FROM UPSTREAM REBASE」も参照してください。

リベースを実行すると、最初にpre-rebaseフックが存在する場合はそれが実行されます。このフックを使用して、健全性チェックを実行し、適切でない場合はリベースを拒否できます。例については、テンプレートの pre-rebase hook スクリプトを参照してください。

完了すると、<branch>が現在のブランチになります。

INTERACTIVE MODE

対話的にリベースするということは、あなたがリベースされるコミットを編集する機会があることを意味します。コミットを並べ替えたり、削除したりできます(不良パッチやその他の不要なパッチを削除します)。

対話モードは、以下のタイプの作業フローを対象としています:

  1. 素晴らしいアイデアを思いついた

  2. コードをハックハック

  3. 提出用のシリーズを準備

  4. 送信

ここで、 (2) は以下のいくつかの作業で構成されています

a) 普段

  1. コミットに値する何かを終える

  2. コミットする

b) 独立した修正

  1. 何かが機能しないことに気付く

  2. そいつを修正

  3. それをコミットする

bの(2) で修正したコミットがパッチシリーズの中に深く埋もれているために、完全ではないコミットに戻せない(amend)ことがあります。これこそが対話型リベースの目的です。たくさんの "a" と "b" の後に、コミットを並べ替えたり編集したり、複数のコミットをひとつにまとめたりするために使用します。

そのまま保持したい最後のコミットから開始します:

git rebase -i <after-this-commit>

エディターは、あなたの現在のブランチのすべてのコミット(マージコミットは無視)で起動されます。これは、指定のコミットの後に発生します。あなたは、このリストのコミットを心ゆくまで並べ替えたり、削除したりできます。そして、リストは多かれ少なかれ以下のようになります:

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

1行説明は、純粋にあなたの備忘のためです。 git rebase はそれらを参照せず、コミット名(この例では "deadbee" と "fa1afe1" )を参照するため、名前を削除または編集しないでください。

コマンド「pick」をコマンド「edit」に置き換えることで、 git rebase にそのコミットを適用した後に停止(stop)するように指示できます。これにより、あなたはファイルやコミットメッセージを編集し、コミットを修正(amend)して、リベースを続行できます。

リベースを中断するには(edit コマンドと同様、ただし最初にコミットを選択せずに)、 break コマンドを使用します。

あなたがコミットのコミットメッセージを編集したいだけの場合は、コマンド pick をコマンド reword に置き換えます。

コミットを削除するには、コマンド pickdrop に置き換えるか、あるいはマッチする行を削除します。

2つ以上のコミットを1つにまとめる場合は、2番目以降のコミットのコマンド pick を squash または fixup に置き換えます。コミットに異なる作者がいた場合、折りたたまれたコミットは最初のコミットの作者に帰属します。折りたたまれたコミットに対して推奨されるコミットメッセージは、最初のコミットのメッセージと squash コマンドで識別されるメッセージを連結したもので、 fixup -c が使用されていない限り、fixupコマンドで識別されるコミットのメッセージは省略されます。fixup -c が使用された場合、提案されたコミットメッセージは fixup -c コミットのメッセージのみであり、エディタが開いてメッセージを編集できます。 fixup -c コミットの内容(パッチ)は、折りたたまれたコミットに引き続き組み込まれます。 fixup -c コミットが複数ある場合は、最後のコミットからのメッセージが使用されます。あなたは fixup -C を使用して、エディターを開かないことを除いて fixup -c と同じ動作をさせることもできます。

「git rebase」は、 pick が edit に置き換えられたとき、またはマージエラーのためにコマンドが失敗したときに停止(stop)します。 競合の編集や解決が完了したら、 あなたは git rebase --continue で続行できます。

たとえば、最後の5つのコミットを並べ替えて、 HEAD~4 であったものが新しいHEADになるようにします。これを実現するには、以下のように「git rebase」を呼び出します:

$ git rebase -i HEAD~5

そして、最初のパッチをリストの最後に移動します。

たとえば、あなたが以下のような履歴を持っているなら、マージコミットを再作成することをお勧めします:

           X
            \
         A---M---B
        /
---o---O---P---Q

あなたは A から Q までのブランチをリベースしたいとします。現在のHEADが B であることを確認して、以下を実行します

$ git rebase -i -r --onto Q O

コミットの並べ替えと編集は通常、テストされていない中間ステップを作成します。テストを実行するか、少なくとも「exec」コマンド(ショートカット「x」)を使用して履歴の中間ポイントで再コンパイルすることにより、履歴の編集で何も壊れていないことを確認することをお勧めします。これを行うには、以下のようなToDoリストを作成します:

pick deadbee Implement feature XXX
fixup f1a5c00 Fix to feature XXX
exec make
pick c0ffeee The oneline of the next commit
edit deadbab The oneline of the commit after
exec cd subdir; make test
...

コマンドが失敗すると(つまり、0以外のステータスで終了すると)、対話的リベースが停止(stop)し、あなたには問題を修正する機会が与えられます。あなたは git rebase --continue で続行できます。

「exec」コマンドは、シェル($SHELL で指定されたもの、または $SHELL が設定されていない場合はデフォルトのシェル)でコマンドを起動するため、シェル機能("cd"、">"、";" など)を使用できます。コマンドは、作業ツリーのルートから実行されます。

$ git rebase -i --exec "make test"

このコマンドを使用すると、あなたは中間コミット(intermediate commits)がコンパイル可能であることを確認できます。ToDoリストは以下のようになります:

pick 5928aea one
exec make test
pick 04d0fda two
exec make test
pick ba46169 three
exec make test
pick f4593f9 four
exec make test

SPLITTING COMMITS

対話モードでは、アクション「edit」でコミットをマークできます。 ただし、これは必ずしも「git rebase」がこの編集の結果が正確に1つのコミットであることを期待していることを意味するわけではありません。 実際、あなたはコミットを元に戻す(undo)ことも、他のコミットを追加することもできます。そしてこれは、コミットを2つに分割するために使用できます:

  • git rebase -i <commit> ^ を使用して対話的リベースを開始します。ここで、<commit> はあなたが分割したいコミットです。 実際、そのコミットが含まれている限り、どんなコミット範囲でもかまいません。

  • あなたが分割したいコミットを、 アクション edit でマークします。

  • そのコミットを編集する場合は、 git reset HEAD^ を実行します。 その効果は、HEADが1つ巻き戻され、インデックスがそれに追随することです。 ただし、作業ツリーは同じままです。

  • 次に、最初のコミットで必要な変更をインデックスに追加します。 これを行うには、 (おそらく対話的に)git add を使うかまたは git gui を使うか(、またはこの両方を使うか)できます。

  • 最新の適切なコミットメッセージを使用して、最新の「現在のインデックス」をコミットします。

  • 作業ツリーがクリーンになるまで、最後の2つの手順を繰り返します。

  • git rebase --continue でリベースを続行します。

あなたが中間リビジョンの一貫性(コンパイル、テストスイートの合格など)が完全には分からない場合は、「git stash」を使用して、各コミット後にまだコミットされていない変更を隠し、修正が必要な場合はコミットをテストして修正する必要があります。

RECOVERING FROM UPSTREAM REBASE

他の人がベースにしているブランチをリベースする (あるいは他の形で書き換える) のは悪い考えです。そのブランチの下流の人は、自分の履歴を手動で修正することを余儀なくされます。 このセクションでは、下流側の視点から見た修正の方法を説明します。 しかし、本当の意味での修正は、そもそも上流のリベースを行わないことです。

説明のために、誰かが「subsystem」ブランチを開発し、この「subsystem」に依存する「topic」に取り組んでいる状況にあると仮定します。たぶん以下のような履歴です:

    o---o---o---o---o---o---o---o  master
         \
          o---o---o---o---o  subsystem
                           \
                            *---*---*  topic

subsystemmaster に対してリベースされる場合、以下が発生します:

    o---o---o---o---o---o---o---o  master
         \                       \
          o---o---o---o---o       o'--o'--o'--o'--o'  subsystem
                           \
                            *---*---*  topic

これで、あなたは通常どおり開発を続行し、最終的に topicsubsystem にマージすると、 以下のように、 subsystem からのコミットは永久に複製されたままになります:

    o---o---o---o---o---o---o---o  master
         \                       \
          o---o---o---o---o       o'--o'--o'--o'--o'--M  subsystem
                           \                         /
                            *---*---*-..........-*--*  topic

このような重複は、履歴が乱雑になり、追跡が困難になるため、一般的に眉をひそめられる行為です。これをクリーンアップするには、「topic」のコミットを新しい「subsystem」の先端に移植する必要があります。つまり、「topic」をリベースする必要があります。これは影響が波及します。「topic」の下流にいる人もリベースを余儀なくされます!

2種類の修正パターン(簡単な場合と難しい場合)があります。以下のサブセクションで議論します:

簡単な場合: 変更は文字通り同じ(same)

これは、 subsystem のリベースが単純なリベースであり、競合がなかった場合に発生します。

難しい場合: 変更は同じではありません

これは、「subsystem」のリベースで競合が発生した場合、または --interactive を使用してコミットを省略(omit)、edit、squash、fixupした場合に発生します。または、アップストリームで commit --amend や、 reset や、 filter-repo のような完全な履歴書き換えコマンドのいずれかを使用した場合に発生します。

簡単な場合

subsystem の変更点(diffの内容に基づくパッチID)がリベース subsystem の前と後で文字通り同じである場合にのみ動作します。

その場合、 git rebase は新しいアップストリームにすでに存在する変更をスキップすることを知っているため、修正は簡単です(--reapply-cherry-picks が指定されていない場合)。 だから(あなたが「topic」にいると仮定して、)あなたが以下のようにすれば、

    $ git rebase subsystem

あなたは修正された履歴で終わります。

    o---o---o---o---o---o---o---o  master
                                 \
                                  o'--o'--o'--o'--o'  subsystem
                                                   \
                                                    *---*---*  topic

難しい場合

subsystem の変更がリベース前の変更に正確に対応していない場合、事態はさらに複雑になります。

Note
「簡単な場合の回復」は、難しい場合でも成功するように見えることがありますが、 意図しない結果をもたらす可能性があります。 たとえば、 git rebase --interactive を介して削除されたコミットが「復活」します!

考え方としては、「git rebase」に「古いsubsystemが終了し、あなたのtopicを開始した場所」、つまり、それらの間の古いマージベースが何であったかを手動で伝えることです。 あなたは古いsubsystemの最後のコミットに名前を付ける方法を見つける必要があります。以下に例を示します:

  • subsystem reflogの場合: git fetch 後、subsystem の古い先端は subsystem@{1} にあります。それ以降にフェッチすると、その数は増えます。 (git-reflog(1) を参照してください)。

  • topic の先端に関連して: topic に3つのコミットがあることを知っているので、 subsystem の古い先端は topic~3 でなければなりません。

次に、あなたは以下のように言って、古い subsystem..topic を新しい先端に移植できます(reflogの場合、すでに topic にいると仮定します):

    $ git rebase --onto subsystem subsystem@{1}

「悪い場合」のリカバリの波及効果は特に悪いです。「topic」の下流にある「全て」で「悪い場合」のリカバリを実行する必要があります。

REBASING MERGES

対話的リベースコマンドは、元々、個々のパッチシリーズを処理するために設計されました。そのため、開発者がブランチの作業中にその時点で最新の「master」をマージした可能性があり、最終的にすべてのコミットを「master」にリベースする(マージコミットをスキップする)ため、マージコミットをtodoリストから除外することは理にかなっています。

ただし、開発者がマージコミットを再作成する正当な理由があります。それは複数の相互に関連するブランチで作業するときに、ブランチ構造(または「コミットトポロジ」)を維持するためです。

次の例では、開発者はボタンの定義方法をリファクタリングするトピックブランチと、そのリファクタリングを使用して[バグの報告]ボタンを実装する別のトピックブランチで作業します。 git log --graph --format=%s -5 の出力は以下のようになります:

*   Merge branch 'report-a-bug'
|\
| * Add the feedback button
* | Merge branch 'refactor-button'
|\ \
| |/
| * Use the Button class for all buttons
| * Extract a generic Button class from the DownloadButton one

開発者は、ブランチトポロジを維持しながら、これらのコミットを新しい master にリベースしたい場合があります。たとえば、最初のトピックブランチが2番目のブランチよりもはるかに早く master に統合されると予想される場合、たとえば、マージの競合を解決して、 master にしたDownloadButtonクラスへの変更を解決します。

このリベースは、 --rebase-merges オプションを使用して実行できます。 以下のようなToDoリストが生成されます:

label onto

# Branch: refactor-button
reset onto
pick 123456 Extract a generic Button class from the DownloadButton one
pick 654321 Use the Button class for all buttons
label refactor-button

# Branch: report-a-bug
reset refactor-button # Use the Button class for all buttons
pick abcdef Add the feedback button
label report-a-bug

reset onto
merge -C a1b2c3 refactor-button # Merge 'refactor-button'
merge -C 6f5e4d report-a-bug # Merge 'report-a-bug'

通常の対話的リベースとは対照的に、 pick コマンドに加えて labelreset と`merge` コマンドがあります。

label コマンドは、そのコマンドが実行されるときに、ラベルを現在のHEADに関連付けます。これらのラベルは、ワークツリーローカル参照(refs/rewritten/<label>)として作成され、リベースが終了すると削除されます。こうすれば、同じリポジトリにリンクされている複数のワークツリーでのリベース操作が相互に干渉することはありません。 label コマンドが失敗した場合、すぐに再スケジュールされ、続行する方法について役立つメッセージが表示されます。

reset コマンドは、HEADとインデックスとワークツリーを指定されたリビジョンにリセットします。 これは exec git reset --hard <label> に似ていますが、追跡していないファイルの上書きを拒否します。 reset コマンドが失敗すると、すぐに再スケジュールされ、todoリストを編集する方法がわかりやすく表示されます(これは通常、 reset コマンドがtodoリストに手動で挿入され、タイプミスが含まれている場合に発生します)。

merge コマンドは、指定されたリビジョンをその時点でHEADであるものにマージします。 -C <original-commit>`を使用すると、指定されたマージコミットのコミットメッセージが使用されます。 `-C が小文字の -c に変更されると、ユーザーがメッセージを編集できるように、マージが成功した後にメッセージがエディターで開かれます。

マージの競合以外の理由で merge コマンドが失敗した場合(つまり、マージ操作が開始されなかった場合)、コマンドは直ちに再スケジュールされます。

デフォルトでは、「merge」コマンドは通常のマージには「ort」マージ戦略を使用し、タコマージ(octopus merges)には「octopus」マージ戦略を使用します。リベースを呼び出すときに --strategy 引数を使用して、すべてのマージのデフォルト戦略を指定できます。または、 exec コマンドを使用して明示的に --strategy 引数を伴った git merge を呼び出すことにより、コマンドの対話リスト内の特定のマージをオーバーライドできます。注意:このように明示的に git merge を呼び出す場合、マージするブランチを参照するために、ラベルがワークツリーローカル参照であるという事実(たとえば、 ref refs/rewritten/onto はラベル onto に対応します)を利用できることに注意してください。

注意: 最初のコマンド(label onto)は、コミットがリベースされるリビジョンにラベルを付けます。 onto`という名前は単なる慣例で、 `--onto オプションにちなんでいます。

merge <merge-head> の形式のコマンドを追加することにより、完全に新しいマージコミットを最初から導入することもできます。この形式は、暫定的なコミットメッセージを生成し、常にエディターを開いてユーザーが編集できるようにします。これは便利です。例えば、トピックブランチが複数の懸念事項に対処していることが判明し、2つ以上のトピックブランチに分割したい場合です。以下のToDoリストを検討してみてください:

pick 192837 Switch from GNU Makefiles to CMake
pick 5a6c7e Document the switch to CMake
pick 918273 Fix detection of OpenSSL in CMake
pick afbecd http: add support for TLS v1.3
pick fdbaec Fix detection of cURL in CMake on Windows

CMakeに関連しないこのリストの1つのコミットは、CMakeに切り替えることによって発生したすべてのバグの修正に取り組むことによって動機付けられた可能性がありますが、しかし、それは別の懸念に対処します。このブランチを2つのトピックブランチに分割するには、ToDoリストを以下のように編集できます:

label onto

pick afbecd http: add support for TLS v1.3
label tlsv1.3

reset onto
pick 192837 Switch from GNU Makefiles to CMake
pick 918273 Fix detection of OpenSSL in CMake
pick fdbaec Fix detection of cURL in CMake on Windows
pick 5a6c7e Document the switch to CMake
label cmake

reset onto
merge tlsv1.3
merge cmake

CONFIGURATION

このセクションの以下のすべては、 git-config(1) ドキュメントの抜粋です。 内容は git-config(1) ドキュメント にあるものと同一です:

rebase.backend

リベースに使用するデフォルトのバックエンド。 可能な選択肢は、「apply」または「merge」です。 将来、mergeバックエンドがapplyバックエンドの残りのすべての機能を取得した場合、この設定は使用されなくなる可能性があります。

rebase.stat

最後のリベース以降にアップストリームで変更されたもののdiffstatを表示するかどうか。デフォルトではFalseです。

rebase.autoSquash

trueに設定されている場合、デフォルトで --autosquash オプションを有効にします。

rebase.autoStash

trueに設定すると、操作を開始する前に一時的なstashエントリを自動的に作成し、操作の終了後に適用します。これは、ダーティワークツリーでリベースを実行できることを意味します。ただし、注意して使用してください。リベースが成功した後の最後のstashアプリケーションは、重要な競合を引き起こす可能性があります。このオプションは、 git-rebase(1)--no-autostash および --autostash オプションでオーバーライドできます。 デフォルトはfalseです。

rebase.updateRefs

trueに設定されている場合、デフォルトで --update-refs オプションを有効にします。

rebase.missingCommitsCheck

「warn」に設定すると、 git rebase -i は、一部のコミットが削除された場合(たとえば、行が削除された場合)に警告を出力しますが、リベースは続行されます。 「error」に設定すると、前記の警告が出力され、リベースが停止(stop)します。 git rebase --edit-todo を使用して、エラーを修正できます。 「ignore」に設定すると、チェックは行われません。 警告やエラーなしにコミットをドロップするには、todoリストの drop コマンドを使用します。 デフォルトは「ignore」です。

rebase.instructionFormat

git-log(1) で指定されている、対話的リベース中にToDoリストに使用される書式文字列。書式では、自動的に長いコミットハッシュが書式の前に付加されます。

rebase.abbreviateCommands

trueに設定すると、 git rebase はtodoリストで省略コマンド名を使用し、以下のようになります:

        p deadbee The oneline of the commit
        p fa1afe1 The oneline of the next commit
        ...

上記は以下の省略形です:

        pick deadbee The oneline of the commit
        pick fa1afe1 The oneline of the next commit
        ...

デフォルトではfalseです。

rebase.rescheduleFailedExec

失敗した exec コマンドを自動的に再スケジュールします。 これは、対話モード (または --exec オプションが指定されている場合)でのみ意味があります。これは --reschedule-failed-exec オプションを指定するのと同じです。

rebase.forkPoint

falseに設定されている場合、デフォルトで --no-fork-point オプションを設定します。

rebase.rebaseMerges

デフォルトで --rebase-merges オプションを設定するかどうか、および設定方法。 rebase-cousins または no-rebase-cousins またはブール値を指定できます。 true または no-rebase-cousins に設定すると --rebase-merges=no-rebase-cousins と同等になり、 rebase-cousins に設定すると --rebase-merges=rebase-cousins と同等になります。 false に設定すると --no-rebase-merges と同等になります。 コマンドラインで --rebase-merges を渡すと引数の有無にかかわらず、 すべての rebase.rebaseMerges 設定がオーバーライドされます。

sequence.editor

リベース命令ファイル(rebase instruction file)を編集するために git rebase -i によって使用されるテキストエディタ。この値は、使用時にシェルによって解釈されることを意図しています。 これは、 GIT_SEQUENCE_EDITOR 環境変数によってオーバーライドできます。構成されていない場合は、代わりにデフォルトのコミットメッセージエディタが使用されます。

GIT

Part of the git(1) suite