Git
英語 ▾ トピック ▾ 最新バージョン ▾ git-rebaseは2.46.1で最終更新されました

名前

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> が指定された場合、git rebase は他の処理を行う前に自動的に git switch <branch> を実行します。そうでない場合は、現在のブランチに留まります。

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

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

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

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

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

マージの失敗により、このプロセスが完全に自動化されない可能性があります。そのようなマージの失敗を解決し、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`はチェックアウトされたブランチのままになります。

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

          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オプションのもう1つの例は、ブランチの一部をリベースすることです。次の状況がある場合

                            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> パラメーターは、有効なコミット風にすることができます。

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

git add <filename>

競合を手動で解決し、目的の解決策でインデックスを更新した後、次の方法でリベースプロセスを続行できます。

git rebase --continue

または、* git rebase *を元に戻すことができます。

git rebase --abort

モードオプション

このセクションのオプションは、他のオプション(互いに含む)とは一緒に使用できません

--continue

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

--skip

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

--abort

リベース操作を中止し、HEADを元のブランチにリセットします。リベース操作の開始時に<branch>が指定されている場合、HEAD<branch>にリセットされます。そうでない場合、HEADはリベース操作の開始時の状態にリセットされます。

--quit

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

--edit-todo

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

--show-current-patch

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

オプション

--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はマージベースを使用してリベースされる_コミットのセット_を決定します。

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

<upstream>

比較対象のアップストリームブランチ。既存のブランチ名だけでなく、有効なコミットであれば何でもかまいません。デフォルトでは、現在のブランチに設定されているアップストリームになります。

<branch>

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

--apply

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

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

--empty=(drop|keep|stop)

最初は空ではなく、アップストリームコミットのクリーンなチェリーピックでもないが、リベース後に空になるコミット(既にアップストリームの変更のサブセットが含まれているため)をどのように処理するか

drop

コミットは削除されます。これはデフォルトの動作です。

keep

コミットは保持されます。--execが指定されている場合、-i/--interactiveも指定されていない限り、このオプションが暗黙的に指定されます。

stop
ask

コミットが適用されるとリベースは停止し、コミットを削除するか、ファイルをさらに編集するか、空の変更をコミットするかを選択できます。 -i/--interactiveが指定されている場合、このオプションが暗黙的に指定されます。 askstop の非推奨の同義語です。

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

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

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

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

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

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

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

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

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

--allow-empty-message

無操作。空のメッセージを持つコミットのリベースは以前は失敗していましたが、このオプションはその動作をオーバーライドし、空のメッセージを持つコミットのリベースを許可していました。現在、空のメッセージを持つコミットはリベースを停止させません。

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

-m
--merge

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

リベースマージは、作業ブランチの各コミットを<upstream>ブランチの上に再生することで機能することに注意してください。このため、マージの競合が発生した場合、_ours_として報告される側は、<upstream>で始まる、これまでにリベースされたシリーズであり、_theirs_は作業ブランチです。言い換えれば、両側が入れ替わります。

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

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

デフォルトのortではなく、指定されたマージ戦略を使用します。これは--mergeを意味します。

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

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

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

<strategy-option>をマージ戦略に渡します。これは--mergeを意味し、戦略が指定されていない場合は-s ortを意味します。 -mオプションについて上記で説明したように、_ours_と_theirs_が逆になることに注意してください。

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

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

rerereメカニズムが現在の競合で記録された解決策を再利用して作業ツリー内のファイルを更新した後、解決の結果でインデックスも更新できるようにします。 --no-rerere-autoupdateは、rerereが何をしたかを再確認し、潜在的な誤マージをキャッチしてから、別のgit addで結果をインデックスにコミットするための良い方法です。

-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ハウツーを参照)。

--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と共に使用して、ブランチからそれらのコミットを削除できます。

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

--ignore-whitespace

差分の調整を試みる際に、空白の違いを無視します。現在、各バックエンドはこの動作の近似を実装しています。

apply バックエンド

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

merge バックエンド

マージする際、空白のみが変更された行は変更されていないものとして扱います。残念ながら、これは空白のみを変更することを意図したパッチハンクは、相手側に競合する変更がない場合でも、削除されることを意味します。

--whitespace=<オプション>

このフラグは、パッチを適用するgit applyプログラム(git-apply[1]参照)に渡されます。--applyを暗黙的に指定します。

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

--committer-date-is-author-date

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

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

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

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

--signoff

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

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

-i
--interactive

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

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

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

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

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

マージをリベースする場合、rebase-cousinsno-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> [...]`コマンドを介してのみ使用できます。

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

-x <コマンド>
--exec <コマンド>

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

複数のコマンドを含む1つの--execインスタンスを使用するか、

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

複数の--execを指定することで、複数のコマンドを実行できます。

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

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

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

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

--root

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

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

--autosquash
--no-autosquash

特別にフォーマットされたメッセージを持つコミットを、リベースされる前のコミットに自動的にスカッシュします。コミットメッセージが「squash!」、「fixup!」、または「amend!」で始まる場合、件名の残りの部分はコミット指定子として扱われ、件名またはそのコミットのハッシュと一致する場合、前のコミットと一致します。完全に一致するコミットがない場合、コミット件名の先頭との指定子の一致が考慮されます。

リベースtodoリストでは、スカッシュ、修正、および修正コミットのアクションは、それぞれpickからsquashfixup、またはfixup -Cに変更され、変更するコミットの直後に移動されます。 --interactiveオプションを使用して、続行する前にtodoリストを確認および編集できます。

スカッシュマーカー付きのコミットを作成するための推奨される方法は、git-commit[1]--squash--fixup--fixup=amend:、または--fixup=reword:オプションを使用することです。これらのオプションは、ターゲットコミットを引数に取り、新しいコミットの件名をそこから自動的に入力します。

設定変数rebase.autoSquashをtrueに設定すると、インタラクティブリベースでデフォルトで自動スカッシュが有効になります。 --no-autosquashオプションを使用して、その設定をオーバーライドできます。

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

--autostash
--no-autostash

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

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

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

このオプションは、リベースが開始されると一度適用されます。初期`git rebase`に提供されたコマンドラインオプション、`rebase.rescheduleFailedExec`設定(git-config[1]または以下の「設定」を参照)、またはデフォルトのfalseに基づいて、リベース全体にわたって保持されます。順序で。

リベース全体にわたってこのオプションを記録することは便利な機能です。そうでない場合、開始時の明示的な`--no-reschedule-failed-exec`は、`git rebase --continue`が呼び出されたときに`rebase.rescheduleFailedExec=true`設定が存在することでオーバーライドされます。現在、`git rebase --continue`に`--[no-]reschedule-failed-exec`を渡すことはできません。

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

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

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

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

互換性のないオプション

以下のオプションは

  • --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

動作の違い

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

空のコミット

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

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

apply バックエンドと同様に、merge バックエンドは、-i/--interactive が指定されない限り(指定された場合は停止してユーザーにどうするかを尋ねます)、空になったコミットをデフォルトで削除します。 merge バックエンドには、空になったコミットの処理方法を変更するための --empty=(drop|keep|stop) オプションもあります。

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

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

ディレクトリ名の変更検出は、*merge* バックエンドで動作し、そのような場合に警告を表示します。

コンテキスト

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

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

競合マーカーのラベル付け

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

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

フック

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

中断可能性

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

コミットメッセージの書き換え

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

その他の違い

ほとんどの人は取るに足りないと思うであろう、さらにいくつかの動作の違いがありますが、完全を期すために言及します

  • reflog:2 つのバックエンドは、reflog で行われた変更を記述する際に異なる表現を使用しますが、どちらも「rebase」という単語を使用します。

  • 進行状況、情報、およびエラーメッセージ:2 つのバックエンドは、わずかに異なる進行状況と情報メッセージを提供します。 また、apply バックエンドはエラーメッセージ(「ファイルは上書きされます…」など)を stdout に書き込みますが、merge バックエンドは stderr に書き込みます。

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

マージ戦略

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

ort

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

*ort* 戦略では、次のオプションを使用できます

ours

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

これは、相手ツリーに含まれるものをまったく見ない *ours* マージ戦略と混同しないでください。 相手ツリーが行ったすべてを破棄し、*自* 履歴に発生したすべてが含まれていると宣言します。

theirs

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

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 も参照してください。

  • *相手* バージョンが行に空白の変更のみを導入する場合、*自* バージョンが使用されます。

  • *自* バージョンが空白の変更を導入するが、*相手* バージョンに実質的な変更が含まれている場合、*相手* バージョンが使用されます。

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

renormalize

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

no-renormalize

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

find-renames[=<n>]

名前変更検出をオンにし、オプションで類似度のしきい値を設定します。 これがデフォルトです。 これは、*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* が無視する(上記では説明していません)、*recursive* 戦略で役立つ可能性のある 3 つの追加オプションがあります

patience

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

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

マージ中に異なるdiffアルゴリズムを使用します。これは、重要でない一致行(異なる関数の中括弧など)が原因で発生する誤ったマージを回避するのに役立ちます。git-diff[1]--diff-algorithmも参照してください。ortは特にdiff-algorithm=histogramを使用しますが、recursiveはデフォルトでdiff.algorithm設定を使用することに注意してください。

no-renames

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

resolve

これは、3-wayマージアルゴリズムを使用して2つのヘッド(つまり、現在のブランチとプル元の別のブランチ)のみを解決できます。十字型のマージのあいまいさを慎重に検出しようとします。名前変更は処理しません。

octopus

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

ours

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

subtree

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

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

注意事項

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

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

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

インタラクティブモード

インタラクティブにリベースするということは、リベースされるコミットを編集する機会があるということです。コミットの順序を変更したり、削除したりできます(不要なパッチを取り除く)。

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

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

  2. コードをハックする

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

  4. 提出する

ここで、ポイント2は、以下の複数のインスタンスで構成されます

a) 通常の使用

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

  2. commit

b) 独立した修正

  1. 何かがうまくいかないことに気付く

  2. それを修正する

  3. コミットする

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

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

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に指示できます。そのため、ファイルやコミットメッセージを編集し、コミットを修正し、リベースを続行できます。

リベースを中断するには(「edit」コマンドと同様に、最初にコミットをチェリーピックすることなく)、 "break"コマンドを使用します.

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

コミットを削除するには、コマンド「pick」を「drop」に置き換えるか、対応する行を削除します。

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

git rebaseは、「pick」が「edit」に置き換えられた場合、またはマージエラーが原因でコマンドが失敗した場合に停止します。編集や競合の解決が完了したら、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以外のステータスで終了した場合)に停止し、問題を修正する機会が与えられます。git rebase --continueで続行できます。

「exec」コマンドは、シェル(デフォルトのシェル、通常は/ bin / sh)でコマンドを起動するため、シェル機能(「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

コミットの分割

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

  • git rebase -i <commit>^でインタラクティブリベースを開始します。ここで、<commit>は分割するコミットです。実際には、そのコミットが含まれている限り、任意のコミット範囲でかまいません。

  • 分割するコミットにアクション「edit」をマークします。

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

  • 最初のコミットに含めたい変更をインデックスに追加します。そのためには、git add(インタラクティブに使用することもできます)またはgit gui(またはその両方)を使用できます。

  • 現在のインデックスを、現在適切なコミットメッセージでコミットします。

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

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

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

アップストリームリベースからの回復

他の人が作業の基礎としているブランチをリベースする(または書き換える)のは悪い考えです。下流の誰もが手動で履歴を修正することを余儀なくされます。このセクションでは、下流の観点から修正を行う方法について説明します。ただし、本当の修正は、そもそもアップストリームのリベースを回避することです.

たとえば、誰かが*subsystem*ブランチを開発し、あなたがこの*subsystem*に依存する*topic*で作業しているとします。最終的に、次のような履歴になる可能性があります

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

*subsystem*が*master*に対してリベースされると、次のようになります

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

通常どおりに開発を続け、最終的に*topic*を*subsystem*にマージすると、*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種類の修正があります

簡単なケース:変更は文字通り同じです。

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

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

これは、*subsystem*リベースに競合があった場合、または--interactiveを使用してコミットを省略、編集、スカッシュ、または修正した場合。または、アップストリームがcommit --amendreset、または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

難しいケース

サブシステムの変更がリベース前の変更と完全に一致しない場合、事態はより複雑になります。

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

その考え方は、git rebase に「古いサブシステムがどこで終わり、あなたのトピックがどこで始まったか」、つまり、それらの間の古いマージベースが何であったかを手動で指示することです。たとえば、古いサブシステムの最後のコミットを指定する方法を見つける必要があります。

  • サブシステムのreflogを使用する場合:git fetch 後、サブシステムの古い先端は subsystem@{1} にあります。以降のフェッチでは、数字が増加します。(git-reflog[1] を参照してください。)

  • トピックの先端からの相対位置を使用する場合:トピックに3つのコミットがあることがわかっている場合、サブシステムの古い先端は topic~3 でなければなりません。

その後、(reflogのケースで、既にトピックにいると仮定すると)次のように言って、古い subsystem..topic を新しい先端にトランスプラントできます。

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

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

「難しいケース」のリカバリの波及効果は特に悪いです。トピックのダウンストリームの全員が「難しいケース」のリカバリを実行する必要が生じます!

マージのリベース

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

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

*   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

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

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

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'

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

通常インタラクティブリベースとは対照的に、pickに加えて、labelreset、およびmergeコマンドがあります。

labelコマンドは、そのコマンドが実行されたときに現在のHEADにラベルを関連付けます。これらのラベルは、リベースの完了時に削除されるワークツリーローカルref(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を使用します。リベースを呼び出すときに--strategy引数を使用してすべてのジのデフォルト戦略を指定するか、execコマンドを使用してgit merge--strategy引数で明示的に呼び出すことにより、インタラクティブなコマンドリストで特定のジをオーバーライドできます。このようにgit mergeを明示的に呼び出す場合、ラベルがワークツリーローカルrefであるという事実を利用できます(たとえば、ref refs/rewritten/ontoはラベルontoに対応します)。ジしたいブランチを参照するためです。

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

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

merge <merge-head> 形式のコマンドを追加することにより、完全に新しいマージコミットを最初から導入することもできます。この形式は、暫定的なコミットメッセージを生成し、常にエディターを開いてユーザーがそれを編集できるようにします。これは、たとえば、トピックブランチが単一の懸念事項以上のものを扱うことが判明し、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

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

設定

このセクションのこの行より下のすべては、git-config[1]ドキュメントから選択的に含まれています。内容は、そこで見つかったものと同じです。

rebase.backend

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

rebase.stat

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

rebase.autoSquash

trueに設定すると、インタラクティブモードでデフォルトでgit-rebase[1]--autosquashオプションが有効になります。これは、--no-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」に設定すると、前の警告を出力してリベースを停止します。その後、*git rebase --edit-todo*を使用してエラーを修正できます。「ignore」に設定すると、チェックは行われません。警告やエラーなしでコミットを削除するには、todoリストのdropコマンドを使用します。デフォルトは「ignore」です。

rebase.instructionFormat

git-log[1]で指定されているように、インタラクティブリベース中にtodoリストに使用されるフォーマット文字列。フォーマットには、コミットハッシュが自動的にプレペンドされます。

rebase.abbreviateCommands

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

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

	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-cousinsno-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設定がオーバーライドされます。

rebase.maxLabelLength

コミットの件名からラベル名を生成するときに、名前をこの長さに切り詰めます。デフォルトでは、名前はNAME_MAXより少し短く切り詰められます(たとえば、対応するloose ref用に.lockファイルが書き込まれるようにするため)。

sequence.editor

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

GIT

scroll-to-top