よく、マージとリベースは基本的に異なる操作です。マージ-でいる私は、新しいマージコミット-ん確かに共通する直近のコミットのコミットグラフを通じてバック検索作成し、通常のgit merge
を意味する:
...--o--*--o--o--A <-- mainbr
\
B--C--D--E <-- sidebr
をここでは、一般的な最新のコミットは*
です。その後、マージプロセスは、とコミットA
をコミットして「私たちが行ったこと」を調べ、E
に対してdiff *
を比較して、「彼らが何をしたか」を見つけ出します(git diff
のように)。 M
対*
の差分のこと「の一つ与えるよう、2つの履歴を結合し、「彼らが何をしたか」「私たちが何をしたか」と組み合わせた
...--o--*--o--o--A---M <-- mainbr
\ /
B--C--D--E <-- sidebr
:それは、新しい単一のマージは、2人の両親と、コミットますそれぞれの変化 "。
ここでマージベースを選択することはできません.Gitはそれを把握しており、それだけです。
Rebaseは、コピーするコミットとコピーする場所を別々に指定することができます。デフォルトでは、コミットは*
です。もう一度ですが、コピーをコピーします。元のコミットは、git cherry-pick
または同等のものを使用してコミットされます。最後に、ブランチを最後にコピーされたコミットを指すように移動します。
...--o--*--o--o--A <-- mainbr
\ \
\ B'-C'-D'-E' <-- sidebr
\
B--C--D--E
(この場合B-C-D-E
)コミットの元の鎖がリポジトリにまだある、まだ検索可能:彼らは、ハッシュIDにより求めることができる、とsidebr
ためREFLOGで、及び他の任意場合ブランチまたはタグ名を使用すると、その名前で到達可能なままになります。何git merge --squash
はわずかにマージ処理を変更することです:代わりにM
をコミットマージすることで、Gitはマージベース - あなたが選ぶ、反対し得ることはありませんが差分のマージを通じていつものように機械を行きます現在のコミットと他のコミット、およびインデックスと作業ツリーの変更を組み合わせることができます。
:グラフ全体-フラグメントは次のようになりますように、それは当時のための明白な理由 -stops、あなたは結果をコミットする
git commit
を実行し、そしてあなたが行うときになり、それは、通常、非マージコミットです今
...--o--*--o--o--A--F <-- mainbr
\
B--C--D--E <-- sidebr
、内容コミットF
の私たちは本当のマージを行うときM
をコミットの内容と同じでマージされ、そして、ここで本当のキッカー、それはだもだから生ずる-the スナップショットツリー rebaseを実行したときのコミットE'
の内容と同じです。
さらに、サイドブランチsidebr
に1つのコミット(B
)があったとします。これで、すべてmerge
の3、merge --squash
、およびrebase
はあなたに私達はちょうどこのように描くかもしれない何かで終わる絵与える:
...--o--*--o--o--A--B' <-- ???
\ ?
B????????? <-- ???
と内容新しいコミットB'
、すなわちのを、最後のスナップショットは、あります3つすべての場合において同じである。しかし、git merge
の場合、新しいコミットはブランチmainbr
にあり、コミットA
とB
を指し、sidebr
はB
を指します。 git merge --squash
の場合、新しいコミットはmainbr
になり、A
に戻るだけです。そしてgit rebase
のために、新しいコミットはまったくB
に何も明らかにポインティングと、sidebr
になり、私たちは、このように描く必要があります。
...--o--*--o--o--A <-- mainbr
\ \
B B' <-- sidebr
mainbr
以来A
のコミットを指すように続けます。最後に
が、これはもう少しそれがリベースのようなよりも、マージのように見えます。 (それがすべてで、「スカッシュマージ」と呼ばれていなかった場合は、私は幸せになります。)
Gitが*
を発見する方法は多少異なっている:それは実際には単一のコミットはありません、むしろ最後の大量のコミット、つまり<upstream>
の引数からgit rebase
に到達可能なすべてのコミットのうちの最後のものです。 (紛らわしいこと、マージベースはまた、コミットのセットすることができますが、それははるかに制限されたセットです。ベストはまだ、グラフ理論に飛び込むしない。:-))
我々はを望んでいた場合、それ停止するには、--no-commit
を通常のノンスカッシュgit merge
と同じように使用できます。だからなぜがを自動的に停止するのですか?
'merge --squash'はブランチからのすべてのコミットを1つに縮めます。履歴を変更することはありません。 –
Andyが言っていることは、併合が起こる前に潰れが起こることです。そのため、ターゲットブランチの観点から見ると、まだマージが見えます。 –
私のポイントは通常のマージの後であった。グラフはマージされた2つのブランチを1つのマージノードに結合するが、マージ後に--squash&commitは2つのブランチがまだ分かれていることを示すが、現在のブランチに移動します。私には、一回のコミットに押しつぶされたrebaseのように見えます。しかし、私が求めていた本当の疑問は、私のコンセプト - スカッシュの概念が根本的に正しいのか、そして@torekによる拡張された答えから、まだ学ぶことがより複雑な詳細があると結論づけていたということでした。 – JonN