Pergunta

Eu tenho um pequeno patch salvo no meu estoque git. Eu apliquei à minha cópia de trabalho usando git stash apply. Agora, eu gostaria de recuar essas mudanças, aplicando o patch (como o que git revert faria não ser contra o estoque).

Alguém sabe como fazer isso?

Esclarecimento: Existem outras mudanças na minha cópia de trabalho. Meu caso em particular é difícil de descrever, mas você pode imaginar algum código experimental ou de depuração que está no estoque. Agora ele está misturado na minha cópia de trabalho com outras alterações e eu gostaria de ver o efeito com e sem as alterações do esconderijo.

Não parece que o Stash suporta isso atualmente, mas um git stash apply --reverse seria um bom recurso.

Foi útil?

Solução

De acordo com Manpágina do Git-STASH, "Um esconderijo é representado como um compromisso cuja árvore registra o estado do diretório de trabalho, e seu primeiro pai é o compromisso em HEAD Quando o estoque foi criado "e git stash show -p nos dá "as alterações registradas no estoque como um diferencial entre o estado de esconderijo e seu pai original.

Para manter suas outras mudanças intactas, use git stash show -p | patch --reverse Como no seguinte:

$ 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

Editar:

Uma melhoria de luz para isso é usar git apply no lugar do patch:

git stash show -p | git apply --reverse

Como alternativa, você também pode usar git apply -R Como uma abreviação de git apply --reverse.

Eu tenho encontrado isso realmente útil ultimamente ...

Outras dicas

git stash[save] leva seu estado de diretório de trabalho e seu estado de índice e os esconde, definindo índice e área de trabalho para HEAD versão.

git stash apply traz de volta essas mudanças, então git reset --hard removeria -os novamente.

git stash pop traz de volta essas mudanças e remove a mudança de tesouro, então git stash [save] retornaria ao estado anterior (pré-pop) neste caso.

git checkout -f

removerá quaisquer alterações que não sejam de compromisso.

Corte direto n pasta do Página do homem gitÉ claramente redigido e até inclui um pseudônimo;

Não aplicar um estoqueEm alguns cenários de caso de uso, você pode querer aplicar alterações escondidas, fazer algum trabalho, mas, em seguida, não aplique as alterações que originalmente vieram do estoque. O Git não fornece um comando tão angado, mas é possível alcançar o efeito simplesmente recuperando o patch associado a um estoque e aplicando -o ao contrário:

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

Novamente, se você não especificar um esconderijo, o Git assume o estoque mais recente:

$ git stash show -p | git apply -R

Você pode criar um alias e adicionar efetivamente um comando stash-unapply ao seu git. Por exemplo:

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

Isso é devido há muito tempo, mas se eu interpretar o problema corretamente, encontrei uma solução simples, observe que esta é uma explicação em minha própria terminologia:

git stash [save] salvará as mudanças atuais e defina sua filial atual para o "estado limpo"

git stash list dá algo como: stash@{0}: On develop: saved testing-stuff

git apply stash@{0} definirá o ramo atual como antes da stash [save]

git checkout . Definirá a filial atual como depois stash [save]

O código que é salvo no estoque não está perdido, pode ser encontrado por git apply stash@{0} novamente.

De qualquer forma, isso funcionou para mim!

Além da resposta @Greg Bacon, caso os arquivos binários tenham sido adicionados ao índice e fizeram parte do esconderijo usando

git stash show -p | git apply --reverse

pode resultar em

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

Adicionando --binary Resolve o problema, mas infelizmente ainda não descobriu o porquê.

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

Isso é um acréscimo às respostas acima, mas adiciona pesquisa pelo esconderijo Git com base na mensagem, pois o número do STASH pode mudar quando novos scahes forem salvos. Eu escrevi algumas funções de 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. Crie Stash com nome (mensagem) $ git stash save "my stash"
  2. Para nomeado Appply $ apply "my stash"
  3. Para remover o tolo nomeado $ remove "my stash"
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top