なぜGitのstashコミットには2つの親が必要なのですか?
でGitのハッカーの手引き、私はスタッシュのために、このメンタルモデルを参照してください。
ガイドによると、stash @ {0}にはAとBの両方が親として必要です。どうして?stashがCの必要性をなくしてBを指しているのはなぜですか?Gitの理解に何か欠けていると思います。
なぜGitのstashコミットには2つの親が必要なのですか?
でGitのハッカーの手引き、私はスタッシュのために、このメンタルモデルを参照してください。
ガイドによると、stash @ {0}にはAとBの両方が親として必要です。どうして?stashがCの必要性をなくしてBを指しているのはなぜですか?Gitの理解に何か欠けていると思います。
回答:
2つのものが隠されているため:インデックス付きコンテンツとワークツリーコンテンツ。どちらもチェックアウトされたコミットから派生しています。隠し場所をポップすると、両方を復元できます。
git add
。
常に 2つの親が必要なわけではなく、実際には3つ必要な場合もあります。
次の図は、2つの親を持つ最も単純なシナリオを示しています。
.----S
/ /
-----H----I
ここでH
は、現在のヘッド(例ではマスターブランチ)を表し、を実行すると2つの子コミットが作成されますgit-stash
。
1つ目はI
であり、格納時のインデックスを表します。つまり、このコミットには、格納する前にステージングされた変更が含まれています。HEADがポイントしたコミットである単一の親があります。2番目の(S
)はstashコミットであり、stashする前に変更されたファイルが含まれています。変更がIの変更とHの変更の上位にある可能性があるため、2つのコミットがあります。つまり、ステージングされたファイルかそうでないファイルに影響する可能性があります。
他のシナリオは、Gitに追跡されていないファイルも隠しておくようにコマンドに-u
切り替えるスイッチを指定した場合に発生しstash
ます。ダイアグラムは次のようになります。
.----S----.
/ / /
-----H----I U
新しいU
コミットには、追跡されていないファイルによって導入されたすべての変更が含まれています。これらのファイルは現在のに存在しないため、このコミットに親が存在しても意味がないことに注意してくださいHEAD
。スタッシュはコミットS
今3つの親を持っていますH
、I
とU
スタッシュを適用する場合、今Gitはまた、人跡未踏の変更を適用しますコミット。
git log --graph stash@{0}
またはのようなものを実行することで、これらの図と差分をはっきりと見ることができますgitk stash@{0}
。