Como você esconde um arquivo não rastreado?

1437

Tenho alterações em um arquivo, mais um novo arquivo, e gostaria de usar o git stash para guardá-los enquanto eu alterno para outra tarefa. Mas o git stash, por si só, oculta apenas as alterações no arquivo existente; o novo arquivo permanece na minha árvore de trabalho, bagunçando meu trabalho futuro. Como esconder esse arquivo não rastreado?

skiphoppy
fonte
27
Esteja ciente de que, se você tiver apenas arquivos não rastreados no seu esconderijo, ele parecerá vazio, pois git stash shownão retorna nada e você pode ficar tentado a descartá-lo (como eu acabei de fazer enquanto continha um script útil que escrevi há alguns meses atrás) → como recuperar um estoque caiu )
Maxime R.

Respostas:

1925

Para ocultar seu diretório de trabalho, incluindo arquivos não rastreados (especialmente aqueles que estão no .gitignore), provavelmente você deseja usar este cmd:

git stash --include-untracked

Mais detalhes:

Atualização 17 de maio de 2018:

Novas versões do git agora têm o git stash --allque oculta todos os arquivos, incluindo arquivos não rastreados e ignorados.
git stash --include-untrackednão toca mais nos arquivos ignorados (testado no git 2.16.2).

Resposta original abaixo:

Atenção, isso excluirá permanentemente seus arquivos se você tiver alguma entrada de diretório / * no seu arquivo gitignore.

A partir da versão 1.7.7, você pode usar git stash --include-untrackedou git stash save -uocultar arquivos não rastreados sem prepará-los.

Adicione ( git add) o arquivo e comece a rastreá-lo. Então esconda. Como todo o conteúdo do arquivo é novo, eles serão ocultados e você poderá manipulá-lo conforme necessário.

sykora
fonte
4
Por que o stash ainda esconde os arquivos existentes alterados, mesmo que essas alterações não tenham sido testadas?
Alan Christensen
6
@ alan-christensen Leia a DESCRIÇÃO do kernel.org/pub/software/scm/git/docs/git-stash.html . O objetivo é ter uma árvore de trabalho limpa depois de guardar.
Kelvin
3
@ Kelvin, o que eu quis dizer no meu comentário foi que ele não esconde novos arquivos, a menos que tenham sido encenados, no entanto, oculta arquivos existentes, mesmo que não tenham sido encenados. Parece inconsistente para mim.
Alan Christensen
11
@AlanChristensen o ponto é esconder coisas que podem ser substituídas pelo checkout de um ramo diferente.
GTC
3
Como você tem a resposta principal aqui, solicitei que você liste git stash --include-untrackedantes git stash --allna sua resposta por dois motivos. Primeiro ele responde a pergunta do OP melhor agora em 2019 e segundo porque --all faz algo que a maioria dos usuários provavelmente não quer em um que remove todos os arquivos que são .gitignored
Daniel Flippance
411

A partir do git 1.7.7, git stashaceita a --include-untrackedopção (ou mão curta -u). Para incluir arquivos não rastreados no seu esconderijo, use um dos seguintes comandos:

git stash --include-untracked
git stash -u

Atenção, isso excluirá permanentemente seus arquivos se você tiver alguma entrada de diretório / * no seu arquivo gitignore.

John Kary
fonte
15
Legal - finalmente funciona como descrito na página de manual. Não esconder (e limpar) novos arquivos é um comportamento quebrado.
21312 Steve Bennett
1
minha versão do git é 1.9.1 e, mesmo que o que eu tenho se .gitignorepareça com isto ignoredDirectorye não, ignoredDirectory/*ele ainda exclui aqueles não rastreados. Mesmo arquivos não rastreados, não apenas diretórios.
precisa saber é o seguinte
22
Você pode explicar o aviso? Por que ele excluiria esses arquivos? Exclui-os e não os esconde? Eu uso o Git há algum tempo e não encontrei esse problema.
Aleksandr Dubinsky
O aviso também se aplica às *.extensionentradas?
arekolek
3
@ aleksandr-Dubinsky, @arekolek - git1.8.3 -u( --include-untracked) opção pode esconder e pop arquivos untracked bem, mas git stash shownão lista os arquivos untracked que estão no estoque
xilef
77

Adicione o arquivo ao índice:

git add path/to/untracked-file
git stash

Todo o conteúdo do índice, além de qualquer alteração não faseada nos arquivos existentes, todos entrarão no stash.

skiphoppy
fonte
E se você não quiser ocultar as alterações que já estão no índice? Ainda é possível esconder o novo arquivo?
allyourcode
Confirme o índice, esconda o novo arquivo e, em seguida, reverta o commit e / ou faça check-out dos arquivos no commit. É uma solução superficial, mas deve funcionar.
Gdalya
git add .não estava levando isso em consideração, por algum motivo
TheBilTheory
53

No git bash, o armazenamento em cache de arquivos não rastreados é obtido usando o comando

git stash --include-untracked

ou

git stash -u

http://git-scm.com/docs/git-stash

O git stash remove todos os arquivos não acompanhados ou não acompanhados do seu espaço de trabalho. E você pode reverter o git stash usando os seguintes comandos

git stash pop

Isso colocará o arquivo de volta no espaço de trabalho local.

Minha experiência

Eu tive que fazer uma modificação no meu arquivo gitIgnore para evitar a movimentação dos arquivos .classpath e .project no repositório remoto. Não tenho permissão para mover este .gitIgnore modificado no repositório remoto a partir de agora.

Os arquivos .classpath e .project são importantes para o eclipse - que é o meu editor java.

Em primeiro lugar, adicionei seletivamente o restante dos arquivos e me comprometi com a preparação. No entanto, o envio final não pode ser executado, a menos que o arquivo .gitIgnore modificado seja exibido e os arquivos não rastreados viz. .project e .classpath não são escondidos.

eu usei

 git stash 

para ocultar o arquivo .gitIgnore modificado.

Para armazenar arquivos .classpath e .project, usei

git stash --include-untracked

e removeu os arquivos do meu espaço de trabalho. A ausência desses arquivos diminui minha capacidade de trabalhar em meu local de trabalho no eclipse. Continuei concluindo o procedimento para enviar os arquivos confirmados para o remoto. Feito isso com sucesso, usei

git stash pop

Isso colou os mesmos arquivos de volta no meu espaço de trabalho. Isso me devolveu minha capacidade de trabalhar no mesmo projeto no eclipse. Espero que isso elimine os equívocos.

DolphinJava
fonte
2
Por que você não usa o gitignore global para arquivos IDE? Ou seja. use ~/.gitignore.
Antti Pihlaja
20

Como já foi dito em outros lugares, a resposta está git addno arquivo. por exemplo:

git add path/to/untracked-file
git stash

No entanto, a questão também é levantada em outra resposta: E se você realmente não quiser adicionar o arquivo? Bem, até onde eu sei, você precisa. E o seguinte NÃO funcionará:

git add -N path/to/untracked/file     # note: -N is short for --intent-to-add
git stash

isso falhará, da seguinte maneira:

path/to/untracked-file: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state

Então o que você pode fazer? Bem, você precisa realmente adicionar o arquivo, no entanto , pode efetivamente descompactá-lo posteriormente, com git rm --cached:

git add path/to/untracked-file
git stash save "don't forget to un-add path/to/untracked-file" # stash w/reminder
# do some other work
git stash list
# shows:
# stash@{0}: On master: don't forget to un-add path/to/untracked-file
git stash pop   # or apply instead of pop, to keep the stash available
git rm --cached path/to/untracked-file

E então você pode continuar trabalhando, no mesmo estado em que estava antes do git add(ou seja, com um arquivo path/to/untracked-filenão rastreado chamado ; além de outras alterações que você possa ter tido nos arquivos rastreados).

Outra possibilidade para um fluxo de trabalho sobre isso seria algo como:

git ls-files -o > files-to-untrack
git add `cat files-to-untrack` # note: files-to-untrack will be listed, itself!
git stash
# do some work
git stash pop
git rm --cached `cat files-to-untrack`
rm files-to-untrack

[Nota: Como mencionado em um comentário de @mancocapac, você pode adicionar --exclude-standardum git ls-filescomando (assim, git ls-files -o --exclude-standard).]

... que também poderia ser facilmente roteirizado - até mesmo os aliases (apresentados na sintaxe zsh; ajustam conforme necessário) [também reduzi o nome do arquivo para que ele caiba na tela sem rolar nesta resposta; fique à vontade para substituir um nome de arquivo alternativo de sua escolha]:

alias stashall='git ls-files -o > .gftu; git add `cat .gftu`; git stash'
alias unstashall='git stash pop; git rm --cached `cat .gftu`; rm .gftu'

Observe que o último pode ser melhor como um script ou função de shell, para permitir que os parâmetros sejam fornecidos git stash, caso você não queira , popmas apply/ ou queira especificar um stash específico, em vez de apenas assumir o topo 1. Talvez este (em vez do segundo apelido acima) [espaço em branco tenha sido ajustado para caber sem rolagem; adicione novamente para maior legibilidade]:

function unstashall(){git stash "${@:-pop}";git rm --cached `cat .gftu`;rm .gftu}

Nota : Neste formulário, você precisa fornecer um argumento de ação e o identificador se for fornecer um identificador de stash, por exemplo, unstashall apply stash@{1}ouunstashall pop stash@{1}

Qual, é claro, você colocaria no seu .zshrc ou equivalente para que exista a longo prazo.

Espero que esta resposta seja útil para alguém, reunindo tudo em uma única resposta.

lindes
fonte
1
git ls-files -o mostra muito mais arquivos do que aqueles em que estou interessado. A partir do seguinte status do git , encontrei adicionando trabalhos --exclude-standard. git ls-files -o - exclui-padrão. Minha opinião sobre isso é apenas "inclui" os arquivos untracked você normalmente não-ignorar, ou seja, apenas mostrar arquivos untracked seu .gitignore não filtram
mancocapac
20

No git versão 2.8.1: o seguinte funciona para mim.

Para salvar arquivos modificados e não rastreados no stash sem um nome

git stash save -u

Para salvar arquivos modificados e não rastreados no stash com um nome

git stash save -u <name_of_stash>

Você pode usar pop ou aplicar mais tarde, como a seguir.

git stash pop

git stash apply stash@{0}
user1012513
fonte
Isso não removeu os arquivos não rastreados do meu computador, embora eles não estivessem mais listados como não rastreados. git stash shownão os mostrou. Quando tentei git stash apply, recebi "erro: não foi possível restaurar arquivos não rastreados do stash". No entanto, os arquivos foram listados novamente como não rastreados, mas as alterações nos arquivos rastreados não foram restauradas. Acho que esses arquivos podem ser restaurados individualmente, verificando-os fora do estoque, mas essa solução não era o que eu esperava.
hBrent 17/04
9

Consegui esconder apenas os arquivos não rastreados, fazendo:

git stash save "tracked files I'm working on"
git stash save -u "untracked files I'm trying to stash"
git stash pop stash@{1}

O último exibe o estoque dos arquivos rastreados, deixando apenas os arquivos não rastreados.

Oded
fonte
git stash save -unão apenas salvar os untrackedarquivos, ele economiza tanto o trackede untracked. Acho que a primeira salva que você está fazendo não é necessária neste caso. Existe um bom diagrama em atlassian.com/git/tutorials/saving-changes/… #
Drenai
2
A questão é como esconder apenas os arquivos não rastreados. Se você pular o primeiro esconderijo, o que irá aparecer? A idéia é: 1) Stash rastreado. 2) Esconderijo não rastreado. 3) Pop rastreado. Resultado: Não rastreado permanece oculto.
Oded
3

Se você deseja ocultar arquivos não rastreados, mas manter os arquivos indexados (aqueles que você está prestes a confirmar por exemplo), basta adicionar a opção -k(manter o índice) à opção-u

git stash -u -k
Tdy
fonte
2

Você pode simplesmente fazê-lo com o comando abaixo

git stash save --include-untracked

ou

git stash save -u

Para obter mais informações sobre o git stash, visite este post (clique aqui)

shubham mishra
fonte
2

vamos supor que o arquivo novo e não rastreado seja chamado: "views.json". se você deseja alterar a ramificação ocultando o estado do seu aplicativo, geralmente digito:

git add views.json

Então:

git stash

E seria escondido. Então eu posso mudar de ramo com

git checkout other-nice-branch
martline1
fonte
1

Existem várias respostas corretas aqui, mas eu queria salientar que para os novos diretórios inteiros, 'git add path'vai NOT trabalho. Portanto, se você tiver um monte de novos arquivos no caminho não rastreado e faça o seguinte:

git add untracked-path
git stash "temp stash"

isso ficará oculto com a seguinte mensagem:

Saved working directory and index state On master: temp stash
warning: unable to rmdir untracked-path: Directory not empty

e se o caminho não rastreado for o único caminho que você está escondendo, o "esconderijo temporário" será um esconderijo vazio. A maneira correta é adicionar o caminho inteiro, não apenas o nome do diretório (por exemplo, finalize o caminho com um '/'):

git add untracked-path/
git stash "temp stash"
DrStrangepork
fonte
Pelo menos no meu sistema, sua suposição está errada. Funciona sem a barra! Diretórios vazios são ignorados de qualquer maneira. (macos git 2.6.2)
phobie
0

Eu pensei que isso poderia ser resolvido informando ao git que o arquivo existe, em vez de enviar todo o conteúdo para a área de teste e depois chamar git stash. Araqnid descreve como fazer o primeiro.

git add --intent-to-add path/to/untracked-file

ou

git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 path/to/untracked-file

No entanto, o último não funciona:

$ git stash
b.rb: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state
Andrew Grimm
fonte
1
Até onde eu sei, o primeiro também não funciona. Veja minha resposta para uma solução para este problema.
Lindes
0
git stash --include-untracked

meu favorito, pois também salva os arquivos que você adicionou e não os preparou.

Hovhannes Babayan
fonte
0

Encontrei um problema semelhante ao usar o Sourcetree com arquivos recém-criados (eles também não seriam incluídos no stash).

Quando eu escolhi 'encenar tudo' pela primeira vez e, em seguida, escondi os componentes recém-adicionados onde foram rastreados e, portanto, incluídos no esconderijo.

Ivo van Leeuwen
fonte
Esta pergunta tem 11 anos e já tem 14 respostas. Você os leu antes de postar?
Mickael B.
-7

Eu costumava ponderar e desejar o mesmo recurso. Mas com o tempo, notei que realmente não é necessário. Quando você esconde, não há problema em deixar os novos arquivos. Nada de "ruim" pode acontecer com eles (quando você verifica outra coisa, o git irá erro e não substituirá o arquivo não rastreado existente)

E, como geralmente o período entre o git stashe o git stash popé bastante pequeno, você precisará do arquivo não rastreado rapidamente novamente. Então, eu diria que o inconveniente do arquivo aparecendo git statusenquanto você está trabalhando em outra coisa (entre o git stashe o git stash pop) é menor que o inconveniente causado pelo trabalho e a atenção necessária, caso contrário custaria tentar adicionar o arquivo não rastreado ao seu esconderijo.

Dieter_be
fonte
15
Depende do projeto. Digamos que o arquivo não rastreado seja um teste de unidade (semi-gravado) e o equipamento de teste execute todos os testes de unidade no diretório. Etc.
Steve Bennett
1
Outro exemplo é se você trabalha em dois computadores e tem permissão para mover dados de A para B, mas não de B para A. Se você criar um novo código para resolver um problema que ocorre primeiro em B, mas que você deseja tanto em A quanto em B, você deseja poder esconder o arquivo em B para que, quando você recriar esse arquivo em A e depois trazê-lo em um pacote, possa git diff na versão oculta para verificar se não cometer um erro.
Gdalya
7
Só porque um arquivo não é rastreado em uma ramificação, não significa que não entrará em conflito com um arquivo rastreado em outra ramificação.
GTC
3
contra-exemplo simples: arquivo de configuração no diretório .conf.d ou qualquer outro que apenas por estar lá modifique o comportamento do software.
Fotanus 13/05/2014
Claro que a funcionalidade é necessária. Como exemplo adicional, não é possível alternar de uma ramificação para outra se você tiver arquivos localmente não rastreados que deseja ocultar.
Demitrian 26/10/2015