git-rebase

Contents

コマンド名

「git-rebase」:別のベースチップの上にコミットを再適用

概要

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)

説明

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

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

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

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

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

マージが失敗すると、このプロセスが完全に自動化されなくなる可能性があります。このようなマージの失敗を解決し、git rebase --continueを実行する必要があります。もう1つのオプションは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はチェックアウトされたブランチのままになります。

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

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

このような結果となります。

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

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

まず、トピックが次のブランチに基づいていると仮定しましょう。例えば、トピックで開発された機能は次に見られるいくつかの機能に依存します。

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

ブランチマスターからトピックをフォークしたいとします。例えば、トピックが依存する機能がより安定したマスターブランチにマージされたためです。ツリーを次のように表示します。

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

または「gitrebase」を元に戻すこともできます。

git rebase --abort

構成

rebase.useBuiltin

未使用の構成変数です。Gitバージョン2.20および2.21において、リベースのレガシーシェルスクリプト実装を有効にするためのエスケープハッチとして使用されます。現在、Cでの組み込みの書き換えが常に使用されています。これを設定すると警告が表示され、残りのユーザーにこれを設定しても何も起こらないことを警告します。

rebase.backend

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

rebase.stat

最後のリベース以降にアップストリームで何が変更されたかの「diffstat」を表示するかどうかです。デフォルトでは「False」となっています。

rebase.autoSquash

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

rebase.autoStash

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

rebase.missingCommitsCheck

「warn」に設定すると、「git rebase –i」は一部のコミットが削除された場合(例えば、ラインが削除された場合)に警告を出力しますが、リベースは続行されます。「error」に設定すると前の警告が出力されてリベースが停止します。その後「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 オプションを指定するのと同じです。

sequence.editor

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

オプション

--onto <newbase>

新しいコミットを作成する開始点です。「–onto」オプションが指定されていない場合、開始点は<upstream>です。既存のブランチ名だけでなく、任意の有効なコミットである可能性があります。
特別な場合として、マージベースが1つしかない場合、AとBのマージベースのショートカットとして「A … B」を使用できます。AとBの最大1つを省略できます。その場合、デフォルトでヘッドになります。

--keep-base

<upstream> <branch>のマージベースへの新しいコミットを作成する開始点を設定します。「git rebase –keep-base <upstream> <branch>」を実行することは「git rebase –onto <upstream>…<upstream>」を実行することと同じです。

このオプションはアップストリームブランチの上で機能を開発している場合に役立ちます。この機能のワーク中、アップストリームブランチが進む可能性があり、アップストリームの上にリベースを続けるのは最善の方法ではなく、ベースコミットをそのままにしておくのが最善の方法ではない場合があります。

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

以下の互換性のないオプションも参照してください。

<upstream>

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

<branch>

ワーキングブランチです。デフォルトはヘッドです。

--continue

マージのコンフリクトを解決した後、リベースプロセスを再開します。

--abort

リベース操作を中止し、ヘッドをオリジナルブランチにリセットします。リベース操作の開始時に<branch>が指定されていた場合、ヘッドは<branch>にリセットされます。それ以外の場合、ヘッドはリベース操作が開始されたときの位置にリセットされます。

--quit

リベース操作を中止しますが、ヘッドはオリジナルブランチにリセットしません。その結果、インデックスとワークツリーも変更されません。「–autostash」を使用して一時的なスタッシュエントリが作成された場合、それはスタッシュリストに保存されます。

--apply

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

以下の互換性のないオプションも参照してください

--empty={drop,keep,ask}

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

空で開始するコミットは保持され(「–no-keep-empty」が指定されていない限り)、クリーンなチェリーピックであるコミット(git log --cherry-mark ...によって決定される)が検出され、プレリミナリーステップ(「–reapply-cherry-picks」がパスされない限り)としてドロップされることに注意してください。

以下の互換性のないオプションも参照してください。

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

結果におけるリベースの前に空で開始する(つまり、ペアレントから何も変更しない)コミットを保持しません。デフォルトでは空で始まるコミットを保持します。これはそのようなコミットを作成するには「-allow-empty」上書きフラグをgit commitにパスする必要があるためです。これはユーザーがそのようなコミットを非常に意図的に作成しているため、保持したいことを示します。

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

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

以下の互換性のないオプションも参照してください。

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

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

デフォルトでは(または--no-reapply-cherry-picksが指定されている場合)、これらのコミットは自動的にドロップされます。これはすべてのアップストリームコミットを読み取る必要があるため、読み取る必要のあるアップストリームコミットが多数あるリポジトリではコストがかかる可能性があります。

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

以下の互換性のないオプションも参照してください。

--allow-empty-message

ノーオペレーションとなります。空のメッセージを使用したコミットのリベースは失敗し、このオプションはその動作を上書きし、空のメッセージを使用したコミットをリベースできるようにします。空のメッセージでコミットしてもリベースが停止することはありません。

以下の互換性のないオプションも参照してください。

--skip

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

--edit-todo

インタラクティブなリベース中に「ToDo」リストを編集します。

--show-current-patch

インタラクティブなリベースでまたはコンフリクトのためにリベースが停止した時、現在のパッチを表示します。これはgit show REBASE_HEADと同等となります。

-m
--merge

マージストラテジーを使用してリベースします。再帰的(デフォルト)マージストラテジーが使用される場合、これによりリベースはアップストリーム側の名前変更を認識できます。これがデフォルトとなります。

リベースマージは<upstream>ブランチの上にあるワークブランチからの各コミットを再生することによって機能することに注意してください。このためマージのコンフリクトが発生した場合、「ours」としての報告された側は<upstream>で始まるこれまでのリベースされたシリーズのことであり、「theirs」側はワークブランチです。言い換えれば、再度が交換されるということです。

以下の互換性のないオプションも参照してください。

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

指定されたマージストラテジーを使用します。-sオプションがない場合、代わりに「gitmerge-recursive」が使用されます。これは「–merge」を意味します。

「git rebase」は指定されたストラテジーを使用して<upstream>ブランチの上にあるワークブランチから各コミットを再生するため、「ours」ストラテジーを使用すると<branch>からすべてのパッチが空になります。これはほとんど意味がありません。

以下の互換性のないオプションも参照してください。

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

<strategy-option>をマージストラテジーにパスします。これは---mergeを意味し、ストラテジーが指定されていない場合は-s recursiveとなります。-mオプションについて上で述べたように「ours」と「theirs」のリバーサルに注意してください。

以下の互換性のないオプションも参照してください。

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

可能な場合、「rerere」メカニズムが自動コンフリクト解決の結果でインデックスを更新できるようにします。

-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

このオプションはリベース前のフックをバイパスします。githooks[5]も参照してください。

--verify

プレリベースフックの実行を許可します。これがデフォルトとなります。 このオプションは「-no-verify」を上書きするために使用できます。githooks[5]も参照してください。

-C<n>

各変更の前後で周囲のコンテキストの少なくとも<n>ラインが一致することを確認します。周囲のコンテキストのラインが少ない場合、すべて一致する必要があります。デフォルトではコンテキストが無視されることはありません。「–apply」を意味します。

以下の互換性のないオプションも参照してください。

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

変更されていないコミットをファーストフォワードにするのではなく、リベースされたすべてのコミットを個別に再生します。これによりリベースされたブランチの履歴全体が新しいコミットで構成されることが保証されます。

トピックブランチのマージを元に戻した後にこれが役立つ場合があります。このオプションはトピックブランチを新しいコミットで再作成するため、「元に戻す」必要なしに正常に再マージできます( 詳細についてはrevert-a-faulty-merge How-Toを参照してください))。

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

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

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

コマンドラインで<upstream>を指定した場合、デフォルトは--no-fork-pointとなります。それ以外の場合、デフォルトは--fork-pointです。

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

以下の互換性のないオプションも参照してください。

--ignore-whitespace

違いを調整しようとする時、空白の違いを無視します。現在、各バックエンドはこの動作の概算を実装しています。

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

バックエンドのマージ:マージ時に空白のみが変更されたラインを変更なしとして扱います。残念ながら、これは反対側にコンフリクトする変更がなかったとしても、空白を変更することを目的としたパッチハンクがドロップされることを意味します。

--whitespace=<option>

このフラグはパッチを適用する「git apply」プログラム(git-apply[1]を参照)にパスされます。「–apply」を意味します。

以下の互換性のないオプションも参照してください。

--committer-date-is-author-date

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

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

オリジナルコミットの作成者の日付を使用する代わりに、現在の時刻をリベースされたコミットの作成者の日付として使用します。このオプションは--force-rebaseを意味します。
以下の互換性のないオプションも参照してください。

--signoff

すべてのリベースされたコミットに「Signed-off-by: trailer」を追加します。--interactive が指定されている場合、選択、編集、または言い換えのマークが付けられたコミットのみにトレーラーが追加されることに注意してください。

以下の互換性のないオプションも参照してください。

-i
--interactive

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

コミットリストのフォーマットは構成オプション「rebase.instructionFormat」を設定することで変更できます。カスタマイズされたインストラクションフォーマットでは自動的に長いコミットハッシュがフォーマットの前に付加されます。

以下の互換性のないオプションも参照してください。

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

デフォルトではリベースは「todo」リストからマージコミットを削除し、リベースされたコミットをシングル線形ブランチに配置します。--rebase-mergesを使用すると、代わりにリベースはマージコミットを再作成することにより、リベースされるコミット内の分岐構造を保持しようとします。これらのマージコミットで解決されたマージのコンフリクトまたは手動の修正は手動で解決もしくは再適用する必要があります。

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

--rebase-merges モードは非推奨の--preserve-mergesと似ていますが、インタラクティブなリベースで機能し、コミットを自由に並べ替えたり、挿入したり、削除したりできます。

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

下記のマージのリベースと互換性のないオプションも参照してください。

-p
--preserve-merges

[非推奨:--rebase-merges を使用]マージコミットによって導入されたコミットを再生して履歴をフラット化する代わりにマージコミットを再作成します。マージのコンフリクト解決またはマージコミットの手動修正は保持されません。

これは内部で--interactive機構を使用しますが、それを--interactiveオプションと明示的に組み合わせることは何をしているのかを理解していない限り、一般的には良い考えではありません(以下のバグを参照)。

以下の互換性のないオプションも参照してください。

-x <cmd>
--exec <cmd>

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

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

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

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

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

--autosquash が使用されている場合、「exec」ラインは中間コミットに追加されず、各スカッシュ/修正シリーズの最後にのみ表示されます。

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

以下の互換性のないオプションも参照してください。

--root

<upstream>で制限するのではなく、<branch>から到達可能なすべてのコミットをリベースします。 これによりブランチのルートコミットをリベースできます。「–onto」と一緒に使用すると、(<upstream>ではなく)<newbase>にすでに含まれている変更をスキップしますが、「-onto」を指定しないと、すべての変更に対して機能します。「–onto」と「–preserve-merges」の両方と一緒に使用すると、すべてのルートコミットは代わりに<newbase>をペアレントとして持つように書き直されます。

以下の互換性のないオプションも参照してください。

--autosquash
--no-autosquash

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

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

以下の互換性のないオプションも参照してください。

--autostash
--no-autostash

操作を開始する前に一時的なスタッシュエントリを自動的に作成し、操作の終了後に適用します。これはダーティなワークツリーでリベースを実行できることを意味します。ただし注意して使用してください。リベースが成功した後の最後のスタッシュアプリケーションは重要なコンフリクトを引き起こす可能性があります。

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

失敗したexecコマンドを自動的に再スケジュールします。これはインタラクティブモード(または--execオプションが指定された場合)でのみ意味があります。

互換性のないオプション

次のオプションです。

  • --apply
  • --whitespace
  • -C

次のオプションと互換性がありません。

  • --merge
  • --strategy
  • --strategy-option
  • --allow-empty-message
  • --[no-]autosquash
  • --rebase-merges
  • --preserve-merges
  • --interactive
  • --exec
  • --no-keep-empty
  • --empty=
  • --reapply-cherry-picks
  • --edit-todo
  • --root when used in combination with --onto

さらに次のオプションのペアには互換性がありません。

  • --preserve-merges and --interactive
  • --preserve-merges and --signoff
  • --preserve-merges and --rebase-merges
  • --preserve-merges and --empty=
  • --preserve-merges and --ignore-whitespace
  • --preserve-merges and --committer-date-is-author-date
  • --preserve-merges and --ignore-date
  • --keep-base and --onto
  • --keep-base and --root
  • --fork-point and --root

動作の違い

「git rebase」には「apply」と「merge」の2つの主要なバックエンドがあります。(「apply」バックエンドは以前は「am」バックエンドと呼ばれていましたが、名前は名詞ではなく動詞のように見えるため混乱を招きました。また「merge」バックエンドは以前はインタラクティブバックエンドと呼ばれていましたが、現在は 非インタラクティブモードの場合も同様です。どちらもそれぞれを支えている低レベルの機能に基づいて名前が変更されます。これら2つのバックエンドの動作には微妙な違いがいくつかあります。

空のコミット

残念ながら、適用バックエンドは意図的に空のコミット、つまり空で開始されたコミットを削除しますが、これらは実際にはまれなケースとなっています。また空になり、この動作をコントロールするオプションがないコミットも削除されます。

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

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

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

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

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

環境

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

マージバックエンドは関連する各ファイルの完全なコピーで機能し、これらのタイプの問題からファイルを保護します。

コンフリクトマーカーのラベル付け

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

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

フック

適用バックエンドはポストコミットフックを呼び出していませんが、マージバックエンドは呼び出します。マージバックエンドがその出力をスケルチしますが、両方ともチェックアウト後のフックを呼び出します。さらに両方のバックエンドは中間コミットや最終コミットではなく、リベースの開始点コミットでチェックアウト後フックを呼び出すだけです。いずれの場合もこれらのフックの呼び出しは設計ではなく実装の偶然によるものでした(両方のバックエンドは元々シェルスクリプトとして実装され、フックを呼び出す「gitcheckout」や「gitcommit」などの他のコマンドをたまたま呼び出します)。どちらが正しいかは完全には明らかではありませんが、両方のバックエンドの動作は同じである必要があります。将来的にはリベースがこれらのフックのいずれかを呼び出すのを停止する可能性があります。

中断可能性

適用バックエンドにはタイミングの悪い割り込みによる安全上の問題があります。ユーザーが間違ったタイミングで「Ctrl-C」を押してリベースを中止しようとすると、リベースはそれに続くgit rebase –abortで中止できない状態になる可能性があります。マージバックエンドは同じ問題に影響を受けてはいないようです。(詳細についてはhttps://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ を参照してください。)

コミットの言い換え

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

その他の違い

ほとんどの人がおそらく取るに足らないと考えるでしょうが、完全を期すために言及されている動作の違いがさらにいくつかあります。

  • 参照ログ:2つのバックエンドは参照ログで行われた変更を説明するときに異なる表現を使用しますが、どちらも「リベース」という単語を使用します。
  • 進行状況、情報、およびエラーメッセージ:2つのバックエンドはわずかに異なる進行状況と情報メッセージを提供します。また適用バックエンドはエラーメッセージ(「ファイルが上書きされます…」など)を「stdout」に書き込み、マージバックエンドはそれらを「stderr」に書き込みます。
  • 状態ディレクトリ:2つのバックエンドは「.git /」の下の異なるディレクトリに状態を保持します。

マージストラテジー

マージメカニズム(git merge およびgit pull コマンド)を使用すると、-sオプションを使用してバックエンドのマージストラテジーを選択できます。一部のストラテジーでは独自のオプションを使用することもできます。これはgit merge および/もしくは git pull-X<option> 引数を指定することでパスすることができます。

resolve

これは3方向マージアルゴリズムを使用して、2つのヘッド(つまり現在のブランチとプルした別のブランチ)のみを解決できます。交差するマージのあいまいさを注意深く検出しようとし、一般的に安全で高速であると見なされています。

recursive

これは3方向マージアルゴリズムを使用して2つのヘッドのみを解決できます。3方向マージに使用できる共通の祖先が複数ある場合、共通の祖先のマージされたツリーを作成し、それを3方向マージの参照ツリーとして使用します。これによりLinux 2.6カーネル開発履歴から取得した実際のマージコミットで実行されたテストによって、ミスマージを引き起こすことなく、マージのコンフリクトが少なくなることが報告されています。さらにこれは名前変更を含むマージを検出して処理できますが、現在、検出されたコピーを利用することはできません。これは1つのブランチをプルまたはマージするときのデフォルトのマージストラテジーです。
再帰的ストラテジーでは次のオプションを選択できます。

ours

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

これを他のツリーに何が含まれているのかをまったく調べないマージストラテジーと混同すべきではありません。それは他のツリーが行ったすべてを破棄し、「ours」履歴にはその中で起こったすべてが含まれていると宣言しています。

theirs

これは「ours」の反対のことです。「ours」 とは異なり、このマージオプションは「theirs」のマージストラテジーはないことに注意してください。

patience

このオプションを使用すると「merge-recursive」は重要でない一致するライン(例えば、別個の関数からの中括弧)が原因で発生することがある誤マージを回避するために、時間を使います。マージするブランチが大きく分岐している場合に使用します。git-diff[1] --patienceも参照してください。

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

異なる差分アルゴリズムを使用するように「merge-recursive」に指示します。これにより重要でない一致するライン(個別の関数からの中括弧など)が原因で発生するミスマージを回避できます。git-diff[1] の--diff-algorithmも参照してください。

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

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

  • 「their」バージョンが行に空白の変更のみを導入する場合、「our」のバージョンが使用されます。
  • 「our」バージョンで空白の変更が導入されていますが、「their」バージョンに大幅な変更が含まれている場合、「their」バージョンが使用されます。
  • それ以外の場合、マージは通常の方法で進行します。

renormalize

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

no-renormalize

renormalizeオプションを無効にします。これはmerge.renormalize構成変数を上書きします。

no-renames

名前変更の検出をオフにします。これはmerge.renames 構成変数を上書きします。git-diff[1]の --no-renamesも参照してください。

find-renames[=<n>]

名前変更検出をオンにし、オプションで類似性のしきい値を設定します。これがデフォルトとなります。これは「merge.renames」構成変数を上書きします。git-diff[1]の--find-renamesも参照してください。

rename-threshold=<n>

find-renames=<n>の非推奨の同義語となります。

subtree[=<path>]

このオプションはサブツリーストラテジーのより高度な形式であり、このストラテジーはマージ時に2つのツリーを互いに一致させるためにどのようにシフトする必要があるかを推測します。代わりに指定されたパスにプレフィックスが付けられ(または最初から削除され)、2つのツリーの形状が一致するようになります。

octopus

これにより3つ以上のヘッドがあるケースは解決されますが、手動で解決する必要がある複雑なマージを行うことはできません。 これは主にトピックのブランチヘッドをまとめることに使用することを目的としています。これは複数のブランチをプルまたはマージする場合のデフォルトのマージストラテジーです。

ours

これにより任意の数のヘッドが解決されますが、マージの結果のツリーは常に現在のブランチヘッドのツリーになり、他のすべてのブランチからのすべての変更が事実上無視されます。これはサイドブランチの古い開発履歴を置き換えるために使用することを目的としています。これは再帰的マージストラテジーの「-Xours」オプションとは異なることに注意してください。

subtree

これは修正された再帰的ストラテジーです。ツリーAとBをマージする時、BがAのサブツリーに対応する場合、Bは同じレベルのツリーを読み取るのではなく、最初にAのツリー構造に一致するように調整されます。この調整は共通の祖先ツリーに対しても行われます。

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

注記

共有するリポジトリで「gitrebase」を使用することの意味を理解する必要があります。下記のアップストリームリベースからのリカバリーも参照してください。

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

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

インタラクティブモード

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

インタラクティブモードはこのタイプのワークフローを対象としています。

  1. 良い考えを持つ
  2. コードをハックする
  3. 提出のためのシリーズを準備する
  4. 提出

ここでポイント2はのいくつかの例で構成されています。

a)通常のルール

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

b) 独立した修正

  1. 動作しない何かを認識する
  2. それを修正
  3. それをコミット

b.2で修正されたもののことがあります。そのコミットはパッチシリーズに深く埋め込まれているため、修正された完全ではないコミットに修正することはできません。それがまさにインタラクティブリベースの目的です。コミットを再配置して編集し、複数のコミットを1つにまとめることで、多くの「a」と「b」の後に使用します。

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

git rebase -i <after-this-commit>

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

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

ワンラインの説明はあなたのためです。「git rebase」はそれらを確認しませんが、コミット名(この例では「deadbee」と「fa1afe1」)を確認するため、名前を削除または編集しません。

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

リベースを中断するには(「編集」コマンドと同じようにただし最初にコミットを選択せずに)、「ブレーク」コマンドを使用します。

コミットのコミットメッセージを編集するだけの場合、コマンド「pick」をコマンド「reword」に置き換えます。

コミットを削除するにはコマンド「pick」を「drop」に置き換えるか、一致するラインを削除します。

2つ以上のコミットを1つにフォールドする場合、2番目以降のコミットのコマンド「pick」を「squash」または「fixup」に置き換えます。コミットに異なる作成者がいた場合、フォールドされたコミットは最初のコミットの作成者に帰属します。フォールドされたコミットに対して推奨されるコミットメッセージは最初のコミットのコミットメッセージと「squash」コマンドを使用したコミットメッセージを連結したものですが、「fixup」コマンドを使用したコミットのコミットメッセージは省略されています。

「pick」が「edit」に置き換えられた場合、またはマージエラーが原因でコマンドが失敗した場合、「gitrebase」は停止します。 コンフリクトの編集や解決が完了したら、git rebase --continueを続行できます。例えば、最後の5つのコミットを並べ替えて、「HEAD〜4」であったものが新しいヘッドになるようにする場合です。これを実現するには次のように「gitrebase」を呼び出します。

$ git rebase -i HEAD~5

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

例えば、そのような履歴があれば、マージコミットを再作成することをお勧めします。

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

「A」から「Q」までのサイドブランチをリベースするとします。現在のヘッドが「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以外のステータスで終了すると)、インタラクティブリベースが停止し、問題を修正する機会が与えられます。git rebase --continueを続行できます。

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

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

このコマンドを使用すると、中間コミットがコンパイル可能であることを確認できます。「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

分割コミット

インタラクティブモードではアクション「編集」でコミットをマークできます。ただしこれは必ずしも「gitrebase」がこの編集の結果が正確に1つのコミットであることを期待していることを意味するわけではありません。実際、コミットを元に戻すことも、他のコミットを追加することもできます。これはコミットを2つに分割するために使用できます。

  • git rebase -i <commit>^を使用してインタラクティブなリベースを開始します。ここで<commit>は分割するコミットです。実際、そのコミットが含まれている限り、どのコミット範囲でもかまいません。
  • アクション「編集」で分割するコミットをマークします。
  • そのコミットの編集に関してはgit reset HEAD^を実行します。その効果はヘッドが1つ巻き戻され、インデックスがそれに追従することです。ただしワークツリーは同じままです。
  • ここで、最初のコミットで必要な変更をインデックスに追加します。これを行うにはgit add(おそらくインタラクティブ)または「git gui」(またはその両方)を使用できます。
  • 現在適切なコミットメッセージを使用して、現在のインデックスをコミットします。
  • ワークツリーがきれいになるまで、最後の2つの手順を繰り返します。
  • git rebase –continueを使用してリベースを続行します。

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

アップストリームリベースからのリカバリー

他の人のワークに基づいているブランチのリベース(または他の形式の書き換え)は悪い考えです。その下流にいる人は手動で履歴を修正する必要が出てきます。このセクションではダウンストリームの観点から修正を行う方法について説明します。ただし、実際の修正はそもそもアップストリームのリベースを回避することです。

説明のために誰かがサブシステムブランチを開発していて、このサブシステムに依存するトピックに取り組んでいると仮定します。次のような履歴が表示されるとします。

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

サブシステムがマスターに対してリベースされる場合、以下が発生します。

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

これで通常どおり開発を続行し、最終的にトピックをサブシステムにマージすると、サブシステムからのコミットは永久に複製されたままになります。

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

このような重複は履歴が乱雑になり、追跡が困難になるため、一般的に嫌われます。クリーンアップするにはトピックのコミットを新しいサブシステムのヒントに移植する必要があります。つまり、トピックをリベースする必要があります。これは波及効果になります。トピックの下流にいる人もリベースを余儀なくされます。

次のサブセクションで説明するように2種類の修正があります。
簡単なケース:変更は文字通り同じです。

これはサブシステムのリベースが単純なリベースであり、コンフリクトがない場合です。

困難なケース:変更は同じではありません。

これはサブシステムのリベースにコンフリクトがあった場合、または--interactiveを使用してコミットを省略、編集、スカッシュ、または修正した場合に発生します。またはアップストリームがcommit –amendreset、またはfilter-repoなどの完全な履歴書き換えコマンドのいずれかを使用した場合です。

簡単なケース

サブシステムの変更(差分の内容に基づくパッチID)がリベースサブシステムの前後で文字通り同じである場合にのみ機能します。

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

$ git rebase subsystem

あなたは固定された履歴を終了させます。

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

困難なケース

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

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

アイデアとしては「古いサブシステムが終了し、トピックが開始した場所」、つまりそれらの間の古いマージベースが何であったかを「gitrebase」に手動で伝えることです。例えば、古いサブシステムの最後のコミットに名前を付ける方法を見つける必要があります。

  • サブシステム参照ログの場合:「git fetch」の後、サブシステムの古いヒントはsubsystem@{1}にあります。後続のフェッチにより数が増加します(git-reflog[1]を参照してください)。
  • トピックのヒントに関連:トピックに3つのコミットがあることを知っているので、サブシステムの古いヒントはtopic~3でなければなりません。

次のように言って、古いsubsystem..topicを新しいヒントに移植できます(参照ログの場合、すでにトピックに取り組んでいると仮定します)。

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

「困難なケース」のリカバリーの波及効果は特に悪いです。ピックの下流にいる全員が「困難なケース」のリカバリーを実行する必要があります。

リバスマージ

インタラクティブなリベースコマンドは元々、個々のパッチシリーズを処理するために設計されました。そのため開発者がブランチでのワーク中にその時点で最新の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コマンドに加えて、labelresetmerge コマンドがあります

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

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

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

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

現時点ではmergeコマンドは通常のマージには常にrecursiveマージストラテジーを使用し、オクトパスマージにはoctopus を使用します。別の方法を選択することはありません。これを回避するにはラベルが「worktree-local ref」であるという事実を使用して、execコマンドを使用してgit mergeを明示的に呼び出すことができます(例えば、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

バグ

非推奨の–preserve-merges –interactiveによって提示される「ToDo」リストはリビジョングラフのトポロジを表していません(代わりに–rebase-mergesを使用してください)。コミットの編集とコミットメッセージの言い換えは問題なく機能するはずですが、コミットを並べ替えようとすると、直感に反する結果になる傾向があります。代わりにそのようなシナリオでは–rebase-mergesを使用してください。

たとえば、次のような再配置の試みの場合です。

1 --- 2 --- 3 --- 4 --- 5

から

1 --- 2 --- 4 --- 3 --- 5

「ピック4」のラインを移動すると、次の履歴が表示されます。

            3
          /
1 --- 2 --- 4 --- 5

GIT

git[1]パッケージソフトの一部

git公式ドキュメント

rebase