セットアップと設定
プロジェクトの取得と作成
基本的なスナップショット
ブランチとマージ
プロジェクトの共有と更新
検査と比較
パッチ適用
デバッグ
メール
外部システム
サーバー管理
- 2.50.1 変更なし
-
2.50.0
2025-06-16
- 2.49.1 変更なし
-
2.49.0
2025-03-14
- 2.46.2 → 2.48.2 変更なし
-
2.46.1
2024-09-13
- 2.45.1 → 2.46.0 変更なし
-
2.45.0
2024-04-29
- 2.44.1 → 2.44.4 変更なし
-
2.44.0
2024-02-23
- 2.43.3 → 2.43.7 変更なし
-
2.43.2
2024-02-13
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.42.2 → 2.42.4 変更なし
-
2.42.1
2023-11-02
- 2.41.1 → 2.42.0 変更なし
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 変更なし
-
2.40.0
2023-03-12
- 2.39.4 → 2.39.5 変更なし
-
2.39.3
2023-04-17
- 2.39.1 → 2.39.2 変更なし
-
2.39.0
2022-12-12
- 2.38.1 → 2.38.5 変更なし
-
2.38.0
2022-10-02
- 2.37.3 → 2.37.7 変更なし
-
2.37.2
2022-08-11
- 2.36.3 → 2.37.1 変更なし
-
2.36.2
2022-06-23
- 2.35.1 → 2.36.1 変更なし
-
2.35.0
2022-01-24
- 2.34.1 → 2.34.8 変更なし
-
2.34.0
2021-11-15
- 2.33.2 → 2.33.8 変更なし
-
2.33.1
2021-10-12
- 2.32.1 → 2.33.0 変更なし
-
2.32.0
2021-06-06
- 2.31.1 → 2.31.8 変更なし
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 変更なし
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 変更なし
-
2.29.0
2020-10-19
- 2.28.1 変更なし
-
2.28.0
2020-07-27
- 2.27.1 変更なし
-
2.27.0
2020-06-01
- 2.26.1 → 2.26.3 変更なし
-
2.26.0
2020-03-22
- 2.25.1 → 2.25.5 変更なし
-
2.25.0
2020-01-13
- 2.24.1 → 2.24.4 変更なし
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 変更なし
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 変更なし
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 変更なし
-
2.21.0
2019-02-24
- 2.20.1 → 2.20.5 変更なし
-
2.20.0
2018-12-09
- 2.19.3 → 2.19.6 変更なし
-
2.19.2
2018-11-21
- 2.19.1 変更なし
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 変更なし
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 変更なし
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
-
2.15.4
2019-12-06
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
- 2.10.5 → 2.11.4 変更なし
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
- 2.7.6 変更なし
-
2.6.7
2017-05-05
- 2.5.6 変更なし
-
2.4.12
2017-05-05
-
2.3.10
2015-09-28
-
2.2.3
2015-09-04
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
概要
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>.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
で表示されるコミットのセットと同じです。
--onto
オプションが指定された場合、現在のブランチは <upstream> または <newbase> にリセットされます。これは git
reset
--hard
<upstream> (または <newbase>) とまったく同じ効果があります。ORIG_HEAD
はリセット前のブランチの先端を指すように設定されます。
注
|
リベース中にその擬似参照を書き込む他のコマンド (例: git reset ) が使用された場合、ORIG_HEAD がリベースの終了時に以前のブランチチップを指している保証はありません。ただし、以前のブランチチップは、現在のブランチのリフロッグ (つまり @{1} 、gitrevisions[7] を参照) を使用してアクセスできます。 |
一時領域に以前保存されたコミットは、現在のブランチに一つずつ順番に再適用されます。注: 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> パラメータは、任意の有効なコミット指定子であることに注意してください。
競合が発生した場合、git
rebase
は最初のエラーのあるコミットで停止し、ツリーに競合マーカーを残します。git
diff
を使用してマーカー (<<<<<<) を見つけ、競合を解決するために編集することができます。編集する各ファイルについて、競合が解決されたことを Git に伝える必要があります。通常は次の方法で行います。
git add <filename>
競合を手動で解決し、目的の解決策でインデックスを更新した後、git
rebase
--continue
でリベースプロセスを続行できます。
git rebase --continue
あるいは、git rebase を元に戻すには、次のコマンドを使用します。
git rebase --abort
モードオプション
このセクションのオプションは、相互を含む他のオプションと一緒に使用することはできません
- --continue
-
マージコンフリクトを解決した後、リベースプロセスを再開します。
- --skip
-
現在のパッチをスキップしてリベースプロセスを再開します。
- --abort
-
リベース操作を中止し、HEAD を元のブランチにリセットします。リベース操作開始時に <branch> が提供された場合、
HEAD
は <branch> にリセットされます。それ以外の場合、HEAD
はリベース操作開始時の位置にリセットされます。 - --quit
-
リベース操作を中止しますが、
HEAD
は元のブランチにリセットされません。インデックスと作業ツリーもその結果変更されずに残ります。--autostash
を使用して一時的なスタッシュエントリが作成された場合、それはスタッシュリストに保存されます。 - --edit-todo
-
インタラクティブなリベース中にtodoリストを編集します。
- --show-current-patch
-
インタラクティブなリベース中、または競合によりリベースが停止している場合に、現在のパッチを表示します。これは
git
show
REBASE_HEAD
と同等です。
オプション
- --onto <newbase>
-
新しいコミットを作成する開始点。
--onto
オプションが指定されていない場合、開始点は <upstream> です。既存のブランチ名だけでなく、任意の有効なコミットであることができます。特殊なケースとして、A と B のマージベースがちょうど 1 つだけ存在する場合、「A...B」をそのショートカットとして使用できます。A と B のうち、最大 1 つを省略でき、その場合は 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)
-
元々は空ではなく、どのアップストリームコミットのクリーンなチェリーピックでもないが、リベース後に空になるコミット (すでにアップストリームにある変更のサブセットを含むため) をどう処理するか
元々空であるコミットは保持され (
--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
は、個別のgit
add
で結果をインデックスにコミットする前に、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
-
このオプションは pre-rebase フックをバイパスします。githooks[5] も参照してください。
- --verify
-
pre-rebase フックの実行を許可します。これがデフォルトです。このオプションは
--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> のより良い共通の祖先を見つけるために reflog を使用します。
--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
-
違いを調整しようとするときに、空白の違いを無視します。現在、各バックエンドはこの動作のおおよその実装を提供しています。
- --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
トレーラーを追加します。--interactive
が指定されている場合、ピック、編集、またはリワードとマークされたコミットにのみトレーラーが追加されることに注意してください。以下の「互換性のないオプション」も参照してください。
- -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-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> [...] コマンドでのみ使用できます。以下のマージのリベースと互換性のないオプションも参照してください。
- -x <cmd>
- --exec <cmd>
-
最終履歴にコミットを作成する各行の後に "exec <cmd>" を追加します。<cmd> は1つ以上のシェルコマンドとして解釈されます。失敗したコマンドはリベースを中断し、終了コード1で終了します。
複数のコマンドを1つの
--exec
で使用するかgit rebase -i --exec "cmd1 && cmd2 && ..."
または、複数の
--exec
を指定することで、複数のコマンドを実行できます。git rebase -i --exec "cmd1" --exec "cmd2" --exec ...
--autosquash
が使用されている場合、中間コミットにexec
行は追加されず、各 squash/fixup シリーズの最後にのみ表示されます。これは内部的に
--interactive
機構を使用しますが、明示的な--interactive
なしで実行できます。以下の「互換性のないオプション」も参照してください。
- --root
-
<upstream> で制限する代わりに、<branch> から到達可能なすべてのコミットをリベースします。これにより、ブランチのルートコミットをリベースできます。
以下の「互換性のないオプション」も参照してください。
- --autosquash
- --no-autosquash
-
特殊な形式のメッセージを持つコミットを、リベース中の以前のコミットに自動的にスカッシュします。コミットメッセージが「squash! 」、「fixup! 」または「amend! 」で始まる場合、タイトルの残りはコミット指定子として解釈され、以前のコミットのタイトルまたはハッシュに一致する場合に一致します。完全に一致するコミットがない場合は、指定子のコミットタイトルの開始との一致が考慮されます。
リベースのtodoリストでは、squash、fixup、amendコミットのアクションが
pick
からそれぞれsquash
、fixup
、または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] または以下の「CONFIGURATION」を参照) の順序で、リベース全体にわたって保持されます。または、デフォルトは 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=
-
--keep-base なしで使用した場合の --[no-]reapply-cherry-picks
-
--update-refs
-
--onto なしで使用した場合の --root
さらに、以下のオプションのペアは互換性がありません
-
--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
で自動的に削除できます)。
適用バックエンドと同様に、デフォルトではマージバックエンドは、-i
/--interactive
が指定されていない限り、空になるコミットを削除します (この場合、停止してユーザーに何をすべきか尋ねます)。マージバックエンドには、空になるコミットの処理動作を変更するための --empty=
(drop
|keep
|stop
) オプションもあります。
ディレクトリのリネーム検出
正確なツリー情報の欠如 (パッチで利用可能な限られた情報で偽の祖先を構築することに起因) のため、apply バックエンドではディレクトリのリネーム検出が無効になっています。ディレクトリのリネーム検出が無効になっているということは、履歴の片側がディレクトリ名を変更し、もう片側が古いディレクトリに新しいファイルを追加した場合、リベース時にこれらのファイルを新しいディレクトリに移動したいという警告なしに、新しいファイルが古いディレクトリに残されることを意味します。
ディレクトリのリネーム検出は、merge バックエンドで機能し、そのような場合に警告を提供します。
コンテキスト
apply バックエンドは、一連のパッチを作成し (内部的に format-patch
を呼び出して)、その後、パッチを順次適用することによって機能します (内部的に am
を呼び出して)。パッチは複数のハンクで構成され、各ハンクには行番号、コンテキスト領域、および実際の変更が含まれます。行番号は、ファイル内で以前に他の側が挿入または削除した行があるため、ある程度のオフセットを考慮する必要があります。コンテキスト領域は、変更を正しい行に適用するために行番号を調整する方法を見つけるのに役立つことを意図しています。しかし、コードの複数の領域が同じ周辺コンテキスト行を持っている場合、間違った領域が選択される可能性があります。実際に、これにより、競合が報告されずにコミットが誤って再適用されたケースがあります。diff.context
をより大きな値に設定すると、そのような種類の問題を防止できる可能性がありますが、偽の競合の可能性が高まります (適用するためにより多くのコンテキスト行の一致が必要になるため)。
merge バックエンドは、関連する各ファイルの完全なコピーで機能するため、これらの種類の問題から保護されています。
競合マーカーのラベリング
内容の競合がある場合、マージ機構は、内容がどこから来たかを示すコミットで各側の競合マーカーに注釈を付けようとします。apply バックエンドは、リベースされたコミットとその親に関する元の情報 (生成されたパッチの限られた情報に基づいて新しい偽のコミットを生成する代わりに) を破棄するため、それらのコミットを識別できません。代わりに、コミットサマリーにフォールバックする必要があります。また、merge.conflictStyle
が diff3
または zdiff3
に設定されている場合、apply バックエンドは「構築されたマージベース」を使用してマージベースからの内容にラベルを付けるため、マージベースコミットに関する情報はまったく提供されません。
merge バックエンドは履歴の両側の完全なコミットで機能するため、そのような制限はありません。
フック
apply バックエンドは伝統的に post-commit フックを呼び出しませんでしたが、merge バックエンドは呼び出していました。どちらも post-checkout フックを呼び出していましたが、merge バックエンドはその出力を抑制していました。さらに、どちらのバックエンドも、リベースの開始点コミットに対してのみ post-checkout フックを呼び出し、中間コミットや最終コミットに対しては呼び出しません。いずれの場合も、これらのフックの呼び出しは設計によるものではなく、実装の偶然によるものでした (どちらのバックエンドも元々はシェルスクリプトとして実装されており、たまたま git
checkout
や git
commit
のようなフックを呼び出す他のコマンドを呼び出していました)。どちらのバックエンドも同じ動作をするべきですが、どちらが正しいか、または正しいものがあるのかは完全に明確ではありません。将来、リベースがこれらのフックのいずれも呼び出すのを停止する可能性が高いです。
中断可能性
apply バックエンドは、タイミングの悪い割り込みに対して安全性の問題があります。ユーザーが誤ったタイミングで Ctrl-C を押してリベースを中止しようとすると、リベースはその後の git
rebase
--abort
で中止できなくなる状態に陥る可能性があります。merge バックエンドは同じ欠点に苦しむことはないようです。(詳細は https://lore.kernel.org/git/20200207132152.GC2868@szeder.dev/ を参照してください。)
コミットの再記述
リベース中に競合が発生すると、リベースは停止し、ユーザーに解決を求めます。ユーザーが競合解決中に顕著な変更を加える必要がある場合があるため、競合が解決され、ユーザーが git
rebase
--continue
を実行した後、リベースはエディタを開き、ユーザーにコミットメッセージを更新するよう求めます。merge バックエンドはこれを行いますが、apply バックエンドは元のコミットメッセージを盲目的に適用します。
その他の違い
ほとんどの人には取るに足らないと思われるかもしれませんが、完全を期すためにいくつかの動作の違いを挙げます。
-
Reflog: 両方のバックエンドは、reflog で行われた変更を記述する際に異なる表現を使用しますが、どちらも「rebase」という単語を使用します。
-
進行状況、情報、およびエラーメッセージ: 2つのバックエンドはわずかに異なる進行状況および情報メッセージを提供します。また、apply バックエンドはエラーメッセージ (「Your files would be overwritten…」など) を標準出力に書き込みますが、merge バックエンドは標準エラーに書き込みます。
-
状態ディレクトリ: 2つのバックエンドは、
.git/
の異なるディレクトリに状態を保持します。
マージ戦略
マージ機構 (git
merge
および git
pull
コマンド) は、-s
オプションでバックエンドの マージ戦略 を選択できるようにします。いくつかの戦略は独自のオプションも受け取ることができ、これらは git
merge
および/または git
pull
に -X
<option> 引数を指定することで渡すことができます。
ort
-
これは、1つのブランチをプルまたはマージするときのデフォルトのマージ戦略です。この戦略は、3ウェイマージアルゴリズムを使用して2つのヘッドのみを解決できます。3ウェイマージに使用できる共通の祖先が複数ある場合、共通の祖先のマージされたツリーを作成し、それを3ウェイマージの参照ツリーとして使用します。これにより、Linux 2.6 カーネル開発履歴から取得した実際のマージコミットでテストした結果、マージ競合が少なくなり、誤ったマージが発生しないことが報告されています。さらに、この戦略は名前変更を含むマージを検出して処理できます。検出されたコピーは使用しません。このアルゴリズムの名前は頭字語 ("Ostensibly Recursive’s Twin") であり、以前のデフォルトアルゴリズムである
recursive
の代替として書かれたという事実から来ています。パスがサブモジュールである場合、マージの片側で使用されるサブモジュールコミットがマージのもう一方の側で使用されるサブモジュールコミットの子孫である場合、Git は子孫にファストフォワードしようとします。そうでない場合、Git はこのケースを競合として扱い、競合するコミットの子孫であるサブモジュールコミットが存在する場合は、それを解決策として提案します。
ort
戦略は以下のオプションを受け取ることができますours
-
このオプションは、競合するハンクを ours バージョンを優先してきれいに自動解決することを強制します。私たちの側と競合しない他のツリーからの変更は、マージ結果に反映されます。バイナリファイルの場合、内容全体が私たちの側から取得されます。
これは、他のツリーの内容をまったく見ない
ours
マージ戦略と混同しないでください。他のツリーが行ったすべてを破棄し、our の履歴にはその中で起こったすべてが含まれていると宣言します。 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> の非推奨の同義語です。 no-renames
-
名前変更検出を無効にします。これは
merge.renames
設定変数を上書きします。git-diff[1]--no-renames
も参照してください。 histogram
-
diff-algorithm=histogram
の非推奨の同義語です。 patience
-
diff-algorithm=patience
の非推奨の同義語です。 diff-algorithm=
(histogram
|minimal
|myers
|patience
)-
マージ中に異なる diff アルゴリズムを使用します。これにより、重要でない一致行 (異なる関数の中括弧など) による誤ったマージを回避できます。git-diff[1] の
--diff-algorithm
も参照してください。ort
はデフォルトでdiff-algorithm=histogram
を使用しますが、通常の diff は現在diff.algorithm
設定値にデフォルト設定されることに注意してください。 subtree
[=
<path>]-
このオプションは subtree 戦略のより高度な形式で、マージ時に2つのツリーが互いに一致するようにどの程度シフトされるべきかを戦略が推測します。代わりに、指定されたパスが接頭辞として追加されるか (または先頭から削除されるか) され、2つのツリーの形状を一致させます。
recursive
-
これは現在
ort
の同義語です。v2.49.0 までは代替実装でしたが、v2.50.0 でort
を意味するようにリダイレクトされました。以前の recursive 戦略は、Git v0.99.9k から v2.33.0 まで、2つのヘッドを解決するデフォルト戦略でした。 resolve
-
これは、3ウェイマージアルゴリズムを使用して2つのヘッド (つまり、現在のブランチとプルした別のブランチ) のみを解決できます。交差マージの曖昧さを慎重に検出しようとします。名前変更は処理しません。
octopus
-
これは2つ以上のヘッドを持つケースを解決しますが、手動での解決が必要な複雑なマージを拒否します。主に、トピックブランチのヘッドをまとめてバンドルするために使用されます。これは、複数のブランチをプルまたはマージするときのデフォルトのマージ戦略です。
ours
-
これは任意の数のヘッドを解決しますが、マージの結果のツリーは常に現在のブランチヘッドのものであり、他のすべてのブランチからのすべての変更を事実上無視します。これは、サイドブランチの古い開発履歴を置き換えるために使用することを意図しています。これは、
ort
マージ戦略の-Xours
オプションとは異なることに注意してください。 subtree
-
これは変更された
ort
戦略です。ツリーAとBをマージするとき、BがAのサブツリーに対応する場合、同じレベルでツリーを読み取るのではなく、まずBをAのツリー構造と一致するように調整します。この調整は共通の祖先ツリーにも行われます。
3ウェイマージを使用する戦略 (デフォルトの ort
を含む) では、両方のブランチで変更が行われたが、その後いずれかのブランチで元に戻された場合、その変更はマージ結果に残ります。この動作に混乱を感じる人もいます。これは、マージを実行する際にヘッドとマージベースのみが考慮され、個々のコミットは考慮されないために発生します。したがって、マージアルゴリズムは元に戻された変更をまったく変更がないものとみなし、代わりに変更されたバージョンを置き換えます。
注記
共有するリポジトリで git
rebase
を使用することの意味を理解する必要があります。以下の「アップストリームのリベースからの回復」も参照してください。
リベースが実行されると、まず pre-rebase
フックが存在すればそれが実行されます。このフックを使用して健全性チェックを行い、不適切な場合はリベースを拒否できます。例についてはテンプレートの pre-rebase
フックスクリプトを参照してください。
完了後、<branch> が現在のブランチになります。
対話モード
インタラクティブにリベースするとは、リベースされるコミットを編集する機会があることを意味します。コミットを並べ替えたり、削除したり (悪いパッチや不要なパッチを取り除く) できます。
インタラクティブモードは、次のワークフローを意図しています。
-
素晴らしいアイデアを思いつく
-
コードをハックする
-
提出用の一連の準備をする
-
提出する
ここで、2.は次の複数のインスタンスで構成されます。
a) 通常の使用
-
コミットに値する何かを完了する
-
commit
b) 独立した修正
-
何か機能しないことに気づく
-
それを修正する
-
コミットする
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」コマンドで識別されたコミットのメッセージは省略されます。ただし、「fixup -c」が使用された場合は除きます。その場合、推奨されるコミットメッセージは「fixup -c」コミットのメッセージのみであり、エディタが開かれ、メッセージを編集できます。「fixup -c」コミットの内容 (パッチ) は、依然として統合されたコミットに組み込まれます。「fixup -c」コミットが複数ある場合は、最後のコミットのメッセージが使用されます。「fixup -C」を使用すると、「fixup -c」と同じ動作をエディタを開かずに得ることができます。
"pick" が "edit" に置き換えられた場合、またはマージエラーのためにコマンドが失敗した場合、git
rebase
は停止します。編集および/または競合の解決が完了したら、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つに分割するために使用できます。
-
分割したいコミットが <commit> の場合、
git
rebase
-i
<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 のリベースが単純なリベースであり、競合がなかった場合に発生します。
- 難しいケース: 変更が同じではない。
-
これは、サブシステムのリベースでコンフリクトが発生した場合、またはコミットを省略、編集、スカッシュ、修正するために
--interactive
を使用したか、あるいは上流がcommit
--amend
、reset
、またはfilter-repo
のような完全な履歴書き換えコマンドのいずれかを使用した場合に発生します。
簡単なケース
サブシステムが行ったリベースの前後で、サブシステムの変更(差分コンテンツに基づくパッチID)が文字通り同じである場合にのみ機能します。
その場合、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
に「古いサブシステムがどこで終わり、あなたのtopicがどこで始まったか」、つまり、それらの間の古いマージベースが何であったかを手動で伝えるという考え方です。古いサブシステムの最後のコミットを特定する方法を見つける必要があります。例えば、
-
サブシステムのリファレンスログを使用:
git
fetch
の後、サブシステムの古い先端はsubsystem@{1}
にあります。後続のフェッチは数値が増加します。( git-reflog[1]を参照してください。) -
topicの先端からの相対位置: あなたのtopicに3つのコミットがあることを知っていれば、サブシステムの古い先端は
topic~3
であるはずです。
その後、(リファレンスログのケースで、すでにtopicにいると仮定して)次のようにして、古いsubsystem..topic
を新しい先端に移植できます。
$ git rebase --onto subsystem subsystem@{1}
「難しいケース」の復旧による波及効果は特に深刻です。topicの下流にあるすべてのユーザーも、「難しいケース」の復旧を実行する必要があります。
マージのリベース
インタラクティブなリベースコマンドは、元々個々のパッチシリーズを処理するように設計されていました。そのため、開発者がブランチで作業中にその時点の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
コマンドに加えて、label
、reset
、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
を使用します。リベースを呼び出すときに--strategy
引数を使用してすべてのマージのデフォルト戦略を指定することも、exec
コマンドを使用してgit
merge
を--strategy
引数で明示的に呼び出すことで、インタラクティブなコマンドリスト内の特定のマージを上書きすることもできます。このように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とは関係のないコミットは、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
設定
このセクションのこの行より下のすべての内容は、git-config[1] ドキュメントから選択的に含まれています。内容はそちらで見られるものと同じです。
- rebase.backend
-
リベースに使用するデフォルトのバックエンド。選択肢はapplyまたはmergeです。将来的に、マージバックエンドがapplyバックエンドの残りのすべての機能を獲得した場合、この設定は使用されなくなる可能性があります。
- rebase.stat
-
最後のリベース以降に上流で何が変更されたかのdiffstatを表示するかどうか。デフォルトはFalseです。
- rebase.autoSquash
-
trueに設定すると、git-rebase[1]の
--autosquash
オプションが対話モードでデフォルトで有効になります。これは--no-autosquash
オプションで上書きできます。 - rebase.autoStash
-
trueに設定すると、操作が始まる前に一時的なスタッシュエントリーを自動的に作成し、操作が終了した後にそれを適用します。これにより、ダーティな作業ツリーでリベースを実行できます。ただし、注意して使用してください。リベースが成功した後の最終的なスタッシュ適用は、単純ではない競合を引き起こす可能性があります。このオプションは、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
-
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
設定が上書きされます。 - rebase.maxLabelLength
-
コミット件名からラベル名を生成する際、名前をこの長さに切り詰めます。デフォルトでは、名前は
NAME_MAX
より少し短い長さに切り詰められます(例えば、対応するルーズな参照のために.lock
ファイルが書き込まれることを許可するため)。 - sequence.editor
-
git
rebase
-i
がリベース命令ファイルを編集するために使用するテキストエディタ。この値は、使用時にシェルによって解釈されることを意図しています。これはGIT_SEQUENCE_EDITOR
環境変数によって上書きできます。設定されていない場合、デフォルトのコミットメッセージエディタが代わりに使用されます。
GIT
git[1]スイートの一部