Como desinstalar apenas certos arquivos?

386

Eu escondi minhas alterações. Agora, quero remover apenas alguns arquivos do stash. Como posso fazer isso?

morfeu
fonte
4
Eu acho que você precisa aplicar todo o estoque, mas pode reestocar seletivamente.
Richard
4
@AbdouTahiri O que há de errado com o estoque?
alex
32
@AbdouTahiri Uhhhh .. git stash é um recurso legítimo e extremamente útil. Eu uso diariamente. Digamos, um colega de trabalho precisa que eu revise algo, mas estou no meio de um conjunto de alterações complexo. Não vou cometer uma pilha de código quebrado apenas para poder trocar de ramificação. Vou esconder, trocar de galho, revisar, voltar, descolar. Você quer saber quem ou por que o git stash é supostamente "não recomendado"? Só porque o seu histórico de stash do Git está confuso e difícil de ler não significa que todo mundo está. Um conjunto de stash bagunçado do Git é apenas um fluxo de trabalho ruim, não uma falha do Git.
Dudewad
6
@alex Nothing. Nada está errado com o git stash. Continue usando.
Dudewad

Respostas:

461

Conforme mencionado abaixo e detalhado em " Como eu extrairia um único arquivo (ou alterações em um arquivo) de um stash git? ", Você pode aplicar o uso git checkoutou git showrestaurar um arquivo específico.

git checkout stash@{0} -- <filename>

Isso sobrescreve filename : verifique se você não teve modificações locais, ou você pode mesclar o arquivo oculto .

(Como comentado por Jaime M. , com certeza shell como tcsh onde você precisa escapar os caracteres especiais, a sintaxe seria: git checkout 'stash@{0}' -- <filename>)

ou para salvá-lo com outro nome de arquivo:

git show stash@{0}:<full filename>  >  <newfile>

(observe que aqui <full filename>está o nome do caminho completo de um arquivo em relação ao diretório superior de um projeto (pense em: relativo a stash@{0})).

yucer sugere nos comentários :

Se você deseja selecionar manualmente quais alterações deseja aplicar nesse arquivo:

git difftool stash@{0}..HEAD -- <filename>

Vivek acrescenta nos comentários :

Parece que " git checkout stash@{0} -- <filename>" restaura a versão do arquivo no momento em que a ocultação foi realizada - NÃO aplica (apenas) as alterações ocultas para esse arquivo.
Para fazer o último:

git diff stash@{0}^1 stash@{0} -- <filename> | git apply

(como comentado por peterflynn , | git apply -p1em alguns casos, talvez seja necessário remover uma ( p1) barra principal dos caminhos de diferenças tradicionais)


Como comentado: "unstash" ( git stash pop), então:

  • adicione o que você deseja manter no índice ( git add)
  • esconder o resto: git stash --keep-index

O último ponto é o que permite manter um arquivo enquanto oculta outros.
Está ilustrado em " Como esconder apenas um arquivo de vários arquivos que foram alterados ".

VonC
fonte
5
Isso não funciona se você não puder git stash popdevido a conflitos de arquivo. A resposta de Balamurugan A fez o truque para mim nesse caso.
22714 Andrey
11
De se você quiser selecionar manualmente quais as mudanças que você deseja aplicar a partir desse arquivo você pode usar git difftool esconderijo @ {0} .. HEAD - <filename>
yucer
5
Parece que "git checkout stash @ {0} - <nome do arquivo>" restaura a versão do arquivo a partir do momento em que o stash foi executado - NÃO aplica (apenas) as alterações armazenadas no arquivo. Para fazer o último: "git diff stash @ {0} ^ 1 stash @ {0} - <nome do arquivo> | git apply"
Vivek
11
@JaimeM. Obrigado. Incluímos seu comentário na resposta para obter mais visibilidade.
VonC 4/17/17
11
Supondo que isso unstashsignifique pop, como me parece que provavelmente aconteceria na maioria dos casos, isso apenas responde parcialmente à pergunta. Como você remove as peças aplicadas seletivamente do esconderijo para evitar conflitos e / ou confusão posteriores ao fazer as alterações restantes?
DylanYoung
115
git checkout stash@{N} <File(s)/Folder(s) path> 

Por exemplo. Para restaurar apenas o arquivo ./test.c e a pasta ./include da última armazenada,

git checkout stash@{0} ./test.c ./include
Balamurugan A
fonte
12
Essa é a resposta correta! Comando de linha única para aplicar apenas alterações ocultas de arquivos específicos, funciona como um encanto!
4levels
11
Para aplicar (apenas) as alterações ocultas para o arquivo: "git diff stash @ {N} ^ 1 stash @ {N} - <nome do arquivo> | git apply"
Vivek
Isso funciona para mim também. Apenas faça check-out seletivamente os arquivos necessários para usar no stash e pronto. Eu estava preso nisso e usei a -abandeira ao criar o esconderijo.
Rajeev Ranjan 17/10
11
@ 4nevels Acho que "aplicar alterações ocultas" não é o que acontece, certo? Eu acho que "sobrescreva o que você tiver com a cópia do stash" é o que acontece.
msouth
35

Acho que a resposta do VonC é provavelmente o que você deseja, mas aqui está uma maneira de fazer um "git apply" seletivo:

git show stash@{0}:MyFile.txt > MyFile.txt
Mike Monkiewicz
fonte
4
Isso pode ser o que você deseja em alguns casos, mas tenha cuidado para que esse comando substitua, em vez de se fundir, com quaisquer alterações no diretório de trabalho.
Rhubbarb
Isso funciona para mim, já que eu só queria copiar um arquivo que existe apenas no stash e não ligava para checkoutnada.
Tom Russell
11
Para o Windows PowerShell: git show stash@`{0`}:Path/To/MyFile.txt |sc Path/To/MyFile.txt- os backticks são necessários para o PS não interpretar os aparelhos especialmente, e isso scé necessário porque o >operador do PS usa como padrão UTF-16 (na verdade UCS-2), o que provavelmente não é o que você deseja. A resposta de @Balamurugan A não sofre com esses problemas.
Ian Kemp
19

Primeira lista de todos os esconderijos

git stash list

stash@{0}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{1}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{2}: WIP on master: 7e450c81 Merge branch 'Offlineseite'

Em seguida, mostre quais arquivos estão no stash (vamos escolher o stash 1):

git stash show 1 --name-only

//Hint: you can also write
//git stash show stash@{1} --name-only

 ajax/product.php
 ajax/productPrice.php
 errors/Company/js/offlineMain.phtml
 errors/Company/mage.php
 errors/Company/page.phtml
 js/konfigurator/konfigurator.js

Aplique o arquivo que você deseja:

git checkout stash@{1} -- <filename>

ou pasta inteira:

git checkout stash@{1} /errors

Também funciona sem, --mas é recomendável usá-los. Veja este post.

Também é convencional reconhecer um hífen duplo como um sinal para interromper a interpretação das opções e tratar todos os argumentos a seguir literalmente.

Preto
fonte
11
Isso é mais claro com esta edição. +1
VonC
11
Eu tentei de várias maneiras e dessa maneira era a que eu precisava. Fui confrontado com um problema que git stash popgerou um erro para arquivos não rastreados. obrigado.
Ramin Firooz
10

Se você git stash pop(sem conflitos) removerá o esconderijo depois de aplicado. Mas se você git stash applyaplicar o patch sem removê-lo da lista de stash. Em seguida, você pode reverter as alterações indesejadas comgit checkout -- files...

Ben Jackson
fonte
2
Para esclarecer os conflitos parte desta postagem, se você git stash pope houver conflitos, precisará corrigi-los manualmente e o stash NÃO será removido.
Thomas McCabe
6

Mais uma maneira:

git diff stash@{N}^! -- path/to/file1 path/to/file2  | git apply -R
Lacho Tomov
fonte
2
Esta é a única resposta correta IMO. Usar checkoutou showsubstituirá cegamente seu arquivo em vez de apenas aplicar alterações. "Mais uma maneira" é um eufemismo.
cambunctious
11
Não estou obtendo o path/to/file2que você deseja diferenciar no mesmo arquivo no seu espaço de trabalho. Deixar o segundo caminho funciona bem para mim. - E recebo uma mensagem de erro usando a -Ropção ("aplicar o patch ao contrário", tentando corrigir a versão escondida ?!). Então, minha versão de trabalho se parece git diff stash@{N}^! -- path/to/file | git apply -.
ThomasH
"patch falhou"? Experimente uma mesclagem de 3 vias. ...| git apply -3 -
John Mee
6

Para usuários do Windows: chaves entre dentes têm um significado especial no PowerShell. Você pode cercar com aspas simples ou escapar com backtick. Por exemplo:

git checkout 'stash@{0}' YourFile

Sem ele, você pode receber um erro:

Unknown switch 'e'

Janac Meena
fonte
3
Marcas completas no PowerShell para a mensagem de usuário menos útil que eu vi este mês.
holdenweb