gitの1.9 / 2.0 2014年第1四半期以降では、で説明したように、書き換え上流の枝にそれをリベースする前に、あなたの前のブランチの起源をマークする必要はありませんアリストテレスPagaltzisさんの答え:
参照は07d406bをコミットしてd96855fをコミット:
でtopic
作成されたブランチで作業した後git checkout -b topic origin/master
、リモートトラッキングブランチの履歴origin/master
が巻き戻されて再構築された可能性があり、この形状の履歴につながります。
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
\
B3
\
Derived (topic)
どこをorigin/master
コミット点まで使用B3
、B2
、B1
今ではで指しB
て、あなたのtopic
とき分岐が戻ってそれの上に開始されたorigin/master
時でしたB3
。
このモードでは、のreflogを使用してフォークポイントとしてorigin/master
検索するため、次の方法で更新さB3
topic
origin/master
れたものに基づいてをリベースできます。
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
これが、git merge-base
コマンドに新しいオプションがある理由です。
--fork-point::
ブランチ(またはにつながる履歴<commit>
)が別のブランチ(または参照)から分岐したポイントを見つけます<ref>
。
これは、2つのコミットの共通の祖先を探すだけでなく、ブランチの以前の化身から分岐した履歴につながるかどうかを確認するためのreflogも考慮に入れます<ref>
<commit>
<ref>
。
" git pull --rebase
"コマンドbase
は、 "ベース"の場合に対処するために、ブランチの作業の基となった " "ブランチ(通常はリモート追跡ブランチ)のreflogエントリを使用して、リベースされるブランチのフォークポイントを計算します。ブランチが巻き戻され、再構築されました。
たとえば、履歴が次のようになっている場合:
- 「現在の先端
base
」ブランチはであるB
が、先にその先端がために使用することが観察フェッチB3
し、その後B2
、その後、B1
現在に入る前にコミットし、
- 最新の「ベース」の上にリベースされているブランチは、コミット
B3
に基づいています。
それが見つけようとするB3
「の出力を経てgit rev-list --reflog base
」(すなわちB
、B1
、B2
、B3
それはそれは、現在の先端の祖先であるコミット見つけるまで)「Derived (topic)
」。
内部的には、get_merge_bases_many()
これを1回で計算できるものがあります。「」のすべての歴史的なヒントをマージすることによって生じる架空のマージコミットとの
間のマージベースが必要になります。
このようなコミットが存在する場合、「」のreflogエントリの1つと完全に一致する単一の結果を取得する必要があります。Derived
base (origin/master)
base
Git 2.1(2014年第3四半期)では、この機能がさらに堅牢になります。JohnKeepingによるcommit 1e0dacd ()を参照してください。johnkeeping
次のトポロジがあるシナリオを正しく処理します。
C --- D --- E <- dev
/
B <- master@{1}
/
o --- B' --- C* --- D* <- master
どこ:
B'
は、;B
とパッチが同一ではない修正バージョンB
です。
C*
およびD*
はそれぞれおよびC
とパッチが同一D
であり、間違った順序で適用された場合はテキストで競合します。
E
テキストに依存しD
ます。
正しい結果git rebase master dev
ISB
の分岐点として識別されるdev
と、master
その結果、C
、D
、E
必要に再生することをコミットしていますmaster
。しかしC
とD
してパッチ同一であるC*
とD*
し、従って最終的な結果であるように、ドロップすることができます。
o --- B' --- C* --- D* --- E <- dev
フォークポイントが識別されない場合、B
を含むブランチを選択B'
すると競合が発生し、パッチが同一のコミットが正しく識別されない場合、C
を含むD
(または同等にD*
)ブランチを選択すると競合が発生します。
「--fork-point
」の「」モードはgit rebase
、コマンドが2.20時代にCで書き直されたときに後退しました。これは、Git 2.27(2020年第2四半期)で修正されました。
Junio C Hamano()によるcommit f08132f(2019年12月9日)を参照してください。(合併によりJunio C浜野- -でfb4175bをコミットする、2020年3月27日)gitster
gitster
rebase
:--fork-point
回帰修正
サインオフ:Alex Torok
[jc:修正を刷新し、Alexのテストを使用]
サインオフ:Junio C Hamano
「git rebase --fork-point master
」それは内部的に呼び出されるよう、作業OKに使用される「git merge-base --fork-point
短いもしrefnameを処理し、それが根底にある呼び出す前に、フルもしrefnameにDWIMする方法を知っていた」get_fork_point()
の機能を。
コマンドがCで書き直された後、これはもはや当てはまりません。これは、に直接行われた内部呼び出しがget_fork_point()
短い参照を無効にしないためです。
「gitmerge-base」で使用されている「dwimtherefname引数を完全なrefnameに」ロジックを基になるget_fork_point()
関数に移動し、「gitrebase」の実装で関数の他の呼び出し元が同じように動作して修正するようにします。この回帰。