web-dev-qa-db-ja.com

スタッシュを逆に適用する方法は?

Git stashに小さなパッチが保存されています。 git stash applyを使用して作業コピーに適用しました。ここで、パッチを逆に適用してこれらの変更をバックアウトしたいと思います(git revertが行うことと似ていますが、隠し場所に反します)。

誰もこれを行う方法を知っていますか?

説明:作業コピーには他の変更点があります。私の特定のケースを説明するのは困難ですが、スタッシュにあるデバッグまたは実験的なコードを想像できます。今、それは私の作業コピーに他のいくつかの変更と混合されており、スタッシュからの変更の有無にかかわらず効果を確認したいと思います。

Stashは現在これをサポートしているようには見えませんが、git stash apply --reverseは素晴らしい機能です。

195
Pat Notz

git-stash manpage によれば、「stashは、ツリーが作業ディレクトリの状態を記録するコミットとして表され、その最初の親は、stashが作成されたときのHEADでのコミットです」 git stash show -pは、「隠された状態と元の親の間の差分として、隠された場所に記録された変更を提供します。

他の変更をそのまま保持するには、次のようにgit stash show -p | patch --reverseを使用します。

$ git init
Initialized empty Git repository in /tmp/repo/.git/

$ echo Hello, world >messages

$ git add messages

$ git commit -am 'Initial commit'
[master (root-commit)]: created 1ff2478: "Initial commit"
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 messages

$ echo Hello again >>messages

$ git stash

$ git status
# On branch master
nothing to commit (working directory clean)

$ git stash apply
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   messages
#
no changes added to commit (use "git add" and/or "git commit -a")

$ echo Howdy all >>messages

$ git diff
diff --git a/messages b/messages
index a5c1966..eade523 100644
--- a/messages
+++ b/messages
@@ -1 +1,3 @@
 Hello, world
+Hello again
+Howdy all

$ git stash show -p | patch --reverse
patching file messages
Hunk #1 succeeded at 1 with fuzz 1.

$ git diff
diff --git a/messages b/messages
index a5c1966..364fc91 100644
--- a/messages
+++ b/messages
@@ -1 +1,2 @@
 Hello, world
+Howdy all

編集:

これに対する軽い改善は、パッチの代わりにgit applyを使用することです:

git stash show -p | git apply --reverse

または、git apply -Rgit apply --reverseの短縮形として使用することもできます。

私は最近、これが本当に便利だと感じています...

164
Greg Bacon

git stash[save]は、作業ディレクトリの状態とインデックスの状態を取得し、それらを隠して、インデックスと作業領域をHEADバージョンに設定します。

git stash applyはこれらの変更を戻すため、git reset --hardは再びそれらを削除します。

git stash popはこれらの変更を戻し、トップの隠された変更を削除するため、この場合git stash [save]は以前の(ポップ前)状態に戻ります。

71
Jakub Narębski
git checkout -f

コミットされていない変更は削除されます。

55
salman

git man page からの直接カットnペースト

Stashの適用解除いくつかのユースケースシナリオでは、隠された変更を適用し、いくつかの作業を行いますが、その後、元々Stashから発生した変更を適用解除します。 Gitはそのようなstash unapplyコマンドを提供しませんが、stashに関連付けられたパッチを単に取得し、逆に適用するだけで効果を達成することができます。

$ git stash show -p stash@{0} | git apply -R

繰り返しますが、スタッシュを指定しない場合、Gitは最新のスタッシュを想定します。

$ git stash show -p | git apply -R

エイリアスを作成し、stash-unapplyコマンドをGitに効果的に追加することができます。例えば:

$ git config --global alias.stash-unapply '!git stash show -p | git apply -R'
$ git stash apply
$ #... work work work
$ git stash-unapply
18
Choco Smith

これはもう長いことですが、問題を正しく解釈する場合、簡単な解決策を見つけた場合、これは私自身の用語の説明です:

git stash [save]は、現在の変更を保存し、現在のブランチを「クリーンな状態」に設定します

git stash listは次のようなものを提供します:stash@{0}: On develop: saved testing-stuff

git apply stash@{0}は、現在のブランチをbeforestash [save]として設定します

git checkout .現在のブランチをafterstash [save]に設定します

Stashに保存されたコードは失われません。再びgit apply stash@{0}で見つけることができます。

Anywhay、これは私のために働いた!

12
Slim Sim

@Greg Baconの答えに加えて、バイナリファイルがインデックスに追加され、以下を使用してスタッシュの一部であった場合

git stash show -p | git apply --reverse

結果として

error: cannot apply binary patch to '<YOUR_NEW_FILE>' without full index line
error: <YOUR_NEW_FILE>: patch does not apply

--binaryを追加すると問題は解決しますが、残念ながらまだ理由がわかりません。

 git stash show -p --binary | git apply --reverse
1
MHosafy

これは上記の回答に追加されますが、新しいスタッシュが保存されるとスタッシュ番号が変更される可能性があるため、メッセージに基づいてgitスタッシュの検索を追加します。いくつかのbash関数を作成しました。

apply(){
  if [ "$1" ]; then
    git stash apply `git stash list | grep -oPm1 "(.*)(?=:.*:.*$1.*)"`
  fi
}
remove(){
  if [ "$1" ]; then
    git stash show -p `git stash list | grep -oPm1 "(.*)(?=:.*:.*$1.*)"` | git apply -R
    git status
  fi
}
  1. 名前(メッセージ)$ git stash save "my stash"でスタッシュを作成します
  2. $ apply "my stash"という名前を付けるには
  3. 名前付きスタッシュを削除するには$ remove "my stash"
0
lifesoordinary