9

私は好奇心からこれを尋ねているだけです。実生活でこの種の状況に対処する方法は他にもありますが、次の git の動作は少し奇妙に感じます。

概要:隠蔽は、カーテンの後ろに 2 つのコミットを作成します。1 つはインデックスを含み、もう 1 つは追加されていない編集を含みます。後者をチェックアウトしてリベースしようとすると、どういうわけかインデックスからの変更しか取得できません。何故ですか?

詳細な例は次のとおりです。

最初に 1 つのコミットでレポを作成し、次にインデックスに追加された編集をもう 1 つ、インデックスに追加されていない編集をもう 1 つ、そしてスタッシュします。

git init
echo 1 > a.txt
git add a.txt
git commit -m"First commit"
echo 2 >> a.txt
git add a.txt
echo 3 >> a.txt
git stash
git log --all --graph --oneline

  *   5c00fc0 WIP on master: c8af537 First commit
  |\  
  | * 965c986 index on master: c8af537 First commit
  |/  
  * c8af537 First commit

したがってgit stash、インデックスと追加されていない編集の両方を、独自のハッシュを持つコミットとして保存するようです (私の場合、インデックスの場合は 965c986、追加されていない編集の場合は 5c00fc0)。

新しいファイルを編集してコミットします。

echo x >> b.txt
git add b.txt
git commit -m"Second commit"

したがって、すべてのコミットは次のようになります。

git log --all --graph --oneline

  * b589f50 Second commit
  | *   5c00fc0 WIP on master: c8af537 First commit
  | |\  
  |/ /  
  | * 965c986 index on master: c8af537 First commit
  |/  
  * c8af537 First commit

たとえば、隠した編集を取得して、2 番目のコミットと結合したいとします。これを行うには他にも方法があります ( のようgit stash applyに、すでにスタッシュを消去してから reflog からコミットを掘り出した場合はどうなるでしょうか)、次の方法で試してみましょう:

git checkout 5c00fc0
[warning message here]
cat a.txt
  1
  2
  3
git rebase master
  First, rewinding head to replay your work on top of it...
  Applying: index on master: c8af537 First commit

しかし今、結果のファイルa.txtは次のとおりです。

cat a.txt 
  1
  2

これは全体のグラフです:

git log --all --graph --oneline
  * 5fc3ade index on master: c8af537 First commit
  * b589f50 Second commit
  | *   5c00fc0 WIP on master: c8af537 First commit
  | |\  
  |/ /  
  | * 965c986 index on master: c8af537 First commit
  |/  
  * c8af537 First commit

つまり、コミット 5c00fc0 をチェックアウトしたにもかかわらず、リベースはコミット 965c986 からの変更、つまり隠したときにインデックスにあった編集のみを適用したようです。しかし、5c00fc0 にあったものは無視されています。

質問:それはなぜですか? この動作について何らかの合理的な説明はありますか? それとも、これはバグと見なすべきですか?

4

3 に答える 3

1

git just (デフォルト) は、リベース時にマージコミットを無視します。また、スタッシングによって WIP コミットとインデックス コミットが作成されます。WIP コミットは、インデックス コミットと c8af537 の両方を親として持つため、マージです。

そのような隠し事とは何の関係もありません。

于 2013-07-26T00:52:26.000 に答える
0

今朝、GUI アプリで誤ってスタッシュをドロップした後、この問題に遭遇しました。最初は、他の人が行ったようにリベースを試みました。これは自然なことだからです。次に、duckduckgo を使用して検索し、これを見つけましたが、実際の解決策はありませんでした。そこで、もう少し頑張ってみた結果、次のようになりました。

次のブランチ/参照があると仮定します。

  • 目的のコンテンツを含む人為的なマージ コミットを指すdroppedStash
  • この ex-stash ブランチの元のベース コミットを指すparentOfStash

次に、次のように簡単に実行できます。

  1. git チェックアウトのparentOfStash
  2. git cherry-pick -m 1 ドロップスタッシュ

-m 1 は、祖先の 1 つをメインラインと見なすように git に指示します。タダ!楽しみ :-)

于 2014-12-07T23:19:31.040 に答える