Git stash sem cache: como eliminar todas as alterações não planejadas?

96

Suponha que dois conjuntos de mudanças sejam feitos em um projeto com versão do git. Um cenário é encenado e o outro não.

Eu gostaria de verificar novamente as mudanças em estágios executando meu projeto neste estado (antes do commit). Qual é uma maneira simples de descartar todas as alterações não encenadas e deixar apenas encenadas? Portanto, preciso que as alterações não testadas desapareçam do meu projeto, mas que sejam armazenadas em algum lugar para trabalhos futuros.

Isso soa muito como um git stashcomando. Mas git stashcolocaria as alterações não planejadas e planejadas longe do meu projeto. E não consigo encontrar algo parecido git stash uncached.

klm123
fonte
A partir de hoje com meu git 2.21, ainda não há uma boa resposta para isso. Todas as respostas abaixo estão incorretas ( -kopção) ou complicadas de usar.
Penghe Geng

Respostas:

98

Atualização 2:
Não sei por que as pessoas estão reclamando desta resposta, parece estar funcionando perfeitamente comigo, para os arquivos não extraídos, você pode adicionar a -usinalização

O comando completo torna-se git stash --keep-index -u

E aqui está um trecho da git-stashajuda

Se a opção --keep-index for usada, todas as mudanças já adicionadas ao índice permanecem intactas.

Se a opção --include-untracked for usada, todos os arquivos não rastreados também serão armazenados e então limpos com git clean, deixando o diretório de trabalho em um estado muito limpo. Se a opção --all for usada em vez disso, os arquivos ignorados serão armazenados e limpos, além dos arquivos não rastreados.

E este é um gif de sua aparência:

insira a descrição da imagem aqui

Atualizar:

Mesmo sendo esta a resposta selecionada, muitos têm apontado que a [resposta abaixo] (https://stackoverflow.com/a/34681302/292408) é a correta, recomendo dar uma olhada.

Testei minha resposta novamente hoje (31/01/2020) contra a versão git 2.24.0, e ainda acredito que está correta, adicionei uma pequena observação acima sobre os arquivos não rastreados. Se você acha que não está funcionando, mencione também sua versão git.

Resposta antiga :
Se a --keep-indexopção for usada, todas as alterações já adicionadas ao índice permanecem intactas:

git stash --keep-index

Da documentação degit-stash :

Testando commits parciais

Você pode usar git stash save --keep-indexquando quiser fazer dois ou mais commits das mudanças na árvore de trabalho e quiser testar cada mudança antes de fazer commit:

# ... hack hack hack ...
$ git add --patch foo            # add just first part to the index
$ git stash save --keep-index    # save all other changes to the stash
$ edit/build/test first part
$ git commit -m 'First part'     # commit fully tested change
$ git stash pop                  # prepare to work on all other changes
# ... repeat above five steps until one commit remains ...
$ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'

Mas, se você deseja apenas verificar visualmente apenas as alterações em estágios, você pode tentar difftool:

git difftool --cached
Mohammad AbuShady
fonte
4
veja também o git stash [-p|--patch]que parece armazenamento interativo. Em man git stash"Com --patch, você pode selecionar interativamente blocos do diff entre o HEAD e a árvore de trabalho a serem armazenados."
aqui
1
Eu normalmente add -p, checkout -pe reset -pnunca tentei stash -p, obrigado pela dica: D
Mohammad AbuShady 01 de
18
Observe que essa resposta também esconderá as mudanças que você testou.
Ben Flynn
Esta resposta não é realmente útil, pois pode resultar em confusão. Essa resposta é melhor stackoverflow.com/a/34681302/292408 .
Elijah Lynn
1
@ElijahLynn Eu vinculei a outra resposta, pois encontrei muitas pessoas dizendo que é a melhor resposta, obrigado pelo seu comentário
Mohammad AbuShady
100

A resposta aceita também esconde mudanças encenadas, como alguns apontaram. Esta é uma maneira de fazer isso sem colocar suas alterações em estágios no estoque.

A ideia é fazer um commit temporário de suas alterações testadas, em seguida, esconder as mudanças não testadas e, em seguida, cancelar o commit do commit temporário:

# temp commit of your staged changes:
$ git commit --message "WIP"

# -u option so you also stash untracked files
$ git stash -u

# now un-commit your WIP commit:
$ git reset --soft HEAD^

Neste ponto, você terá um estoque de suas mudanças não planejadas e somente as suas mudanças planejadas estarão presentes em sua cópia de trabalho.

stephen.hanson
fonte
21
Esta é realmente a resposta correta da IMO. A --keep-indexopção na resposta aceita atual ainda esconde o que está no índice, mas também o mantém no índice. Então ele é duplicado e a hilaridade começa.
Ken Williams,
3
@KenWilliams <del> hilarity </del> <ins> tragédia </ins>
tuespetre
@KenWilliams Isso realmente me irritou. OP, você pode ajustar a resposta selecionada?
MikeMurko
2
A git add .etapa pode ser melhorada git add --allporque também deve pegar os arquivos em um diretório acima do diretório de trabalho atual.
Elijah Lynn
1
Esta é a melhor resposta até agora, já que a opção --keep-index na resposta aceita é enganosa. Esta deve ser a resposta aceita.
Elijah Lynn
21

Eu descobri que a resposta marcada não funcionou para mim, já que eu precisava de algo que realmente escondia apenas minhas mudanças não encenadas. A resposta marcada git stash --keep-index,, armazena as mudanças encenadas e não encenadas. A --keep-indexparte simplesmente deixa o índice intacto na cópia de trabalho também. Isso funciona para OP, mas apenas porque ele fez uma pergunta ligeiramente diferente daquela para a qual ele realmente queria a resposta.

A única maneira verdadeira que encontrei de esconder mudanças não planejadas é não usar o esconderijo:

git diff > unstaged.diff
git apply -R unstaged.diff

git checkout -- .também funcionará em vez de apply -R.

Trabalho Trabalho trabalho...

git apply unstaged.diff
rm unstaged.diff
Binary Phile
fonte
1
Aqui em diante git version 2.6.1.windows.1, git stash -kfuncionou conforme descrito.
koppor
Esta deve ser a resposta aceita! É o único em vários threads de stackoverflow que faz o que afirma e não depende de fazer commits temporários!
user643011
1
@ user643011: commits temporários não são uma coisa ruim no git. Eles não custam nada e não fazem mal a ninguém.
Fritz
1
@Fritz: Nenhum commit temporário não é possível em alguns cenários. Ele pode falhar se você tiver um gancho de pré-confirmação que verifica o código de trabalho atual. Se suas mudanças em estágios forem boas, mas suas mudanças não em estágio, não, essa abordagem falhará em confirmar as mudanças em estágios.
Penghe Geng
1
Isso não inclui arquivos não rastreados. Você precisa usar "git ls-files" para encontrar e incluí-los no patch diff
ACyclic
5

Git: Stash mudanças não planejadas

Isso irá esconder todas as modificações que você não adicionou com git:

git stash -k

Observe que os arquivos recém-criados (e não adicionados) permanecerão em seu diretório de trabalho, a menos que você também use a -uopção.

git stash -k -u 

Além disso, seu diretório de trabalho deve estar limpo (ou seja, todas as alterações precisam ser adicionadas) quando você git stash pop mais tarde.

http://makandracards.com/makandra/853-git-stash-unstaged-changes

Cory Danielson
fonte
13
Isso é equivalente a git stash --keep-index. Os arquivos preparados são incluídos no stash.
Benjamin Cheah,