Esconder apenas um arquivo de vários arquivos que foram alterados com o Git?

3071

Como posso esconder apenas um dos vários arquivos alterados na minha ramificação?

Rachel
fonte
109
Não acho que a resposta aceita de @ bukzor seja a resposta correta para a pergunta, como foi feita. git stash --keep-indexmantém o índice, mas esconde tudo - tanto no índice quanto fora dele.
Raman
@Antonio Parece-me que sua recompensa deve ser uma pergunta separada, já que a pergunta original não tem nada a ver com o TortoiseGit especificamente.
JesusFreke
1
@JesusFreke Sim, dado o resultado que eu poderia ter poupado 50 repetições :) É só que essa é a pergunta para a qual você será redirecionado se tentar procurar "" stash parcial tortoisegit "". Não TortoiseGit não parece ser um tema popular aqui stackoverflow.com/questions/tagged/tortoisegit
Antonio
7
>>>>>>>>> git diff -- *filename* > ~/patchentão git checkout -- *filename*e mais tarde você pode reaplicar o patch comgit apply ~/patch
neaumusic
36
A maioria das respostas existentes abaixo está desatualizada. Desde o Git 2.13 (Q2 2017), ele é suportado git stash push [--] [<pathspec>...].
Ohad Schneider

Respostas:

1372

Isenção de responsabilidade : a resposta a seguir é para o git antes do git 2.13. Para o git 2.13 ou superior, confira outra resposta mais abaixo .


Atenção

Conforme observado nos comentários, isso coloca tudo no esconderijo, tanto em etapas quanto em etapas. O índice --keep apenas deixa o índice sozinho depois que o stash é concluído. Isso pode causar conflitos de mesclagem quando você mais tarde abrir o esconderijo.


Isso esconderá tudo o que você não adicionou anteriormente. Apenas git addas coisas que você deseja manter e execute.

git stash --keep-index

Por exemplo, se você deseja dividir um commit antigo em mais de um changeset, pode usar este procedimento:

  1. git rebase -i <last good commit>
  2. Marque algumas alterações como edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Corrija as coisas conforme necessário. Não se esqueça de git addquaisquer alterações.
  7. git commit
  8. git stash pop
  9. Repita, a partir do número 5, conforme necessário.
  10. git rebase --continue
Bukzor
fonte
47
Eu acho que esta abordagem seja muito mais simples: stackoverflow.com/a/5506483/457268
k0pernikus
561
Não sei por que isso está sendo votado. Todo mundo deve ter uma expectativa diferente da minha. A postagem original está perguntando "como faço para esconder apenas uma parte das alterações não confirmadas?" Quando uso git stash save -k, sim, o índice (verde git stat) é preservado, mas todo o conjunto de alterações (verde e vermelho) entra no esconderijo. Isso viola a solicitação do OP, "esconde apenas algumas alterações". Quero esconder apenas um pouco do vermelho (para uso futuro).
Pistas
70
Se você está mais interessado na resposta à questão colocada pelo @Pistos (como eu estava), então veja aqui: stackoverflow.com/questions/5506339/...
Raman
27
@Raman: Excelente! git stash -pé exatamente o que eu estava procurando. Gostaria de saber se esta opção foi adicionada recentemente.
Pistos
14
AVISO: git stash --keep-indexestá quebrado. Se você fizer mais alterações, tente git stash popmais tarde obter conflitos de mesclagem, porque o stash inclui os arquivos alterados que você manteve, não apenas os que não foram mantidos. Por exemplo: altero os arquivos A e B e, em seguida, escondo B, porque quero testar as alterações em A; Eu encontro um problema com A que eu conserto; Eu cometo A; Agora não consigo remover o cache porque uma versão antiga de A está no esconderijo sem um bom motivo, causando um conflito de mesclagem. Na prática, A e B podem ser muitos arquivos, talvez até mesmo imagens binárias ou algo assim, então eu basicamente tem que desistir e B. perder
rjmunro
3015

Você também pode usar git stash save -p "my commit message". Dessa forma, você pode selecionar quais blocos devem ser adicionados ao stash, arquivos inteiros também podem ser selecionados.

Você será solicitado a executar algumas ações para cada pedaço:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help
konrad.kruczynski
fonte
5
Não era. Foi emprestado da Darcs, cerca de 7 anos após o fato.
Nomen
6
Eu sou um viciado em TortoiseGit. No entanto, o TortoiseGit não suporta stash -p. Eu concedo esta resposta porque continua sendo a mais interativa / amigável.
Antonio
27
você pode querer adicionar git stash save -p my stash message:; desde o fim da argumenst não é muito intuitiva ...
Chris Maes
15
Entre isso e git log -p, acho que a -pbandeira deve significar "faça o que é legal que eu quero, mas não sei como expressar".
Kyle Strand #
2
por que diabos essa grande resposta está na 12ª posição? depois de todas as respostas 0, +1, +2 ??????
DenisFLASH
550

Como o git é fundamentalmente sobre o gerenciamento de todo o conteúdo e índice de repositório (e não um ou vários arquivos), git stashlida, sem surpresa,com o diretório all working.

Na verdade, desde o Git 2.13 (Q2 2017), você pode ocultar arquivos individuais, com git stash push:

git stash push [--] [<pathspec>...]

Quando pathspecatribuído a ' git stash push', o novo stash registra os estados modificados apenas para os arquivos que correspondem ao pathspec. Consulte " Alterações no stash para arquivos específicos " para obter mais informações.

Exemplo simplificado:

 git stash push path/to/file

O caso de teste para esse recurso mostra mais algumas opções:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

A resposta original (abaixo, junho de 2010) era sobre a seleção manual do que você deseja ocultar.

Comentários do Casebash :

Isso (a stash --patchsolução original) é legal, mas muitas vezes eu modifiquei muitos arquivos, então usar o patch é irritante

bukzor de resposta (upvoted, Novembro de 2011) sugere uma solução mais prático, com base em
git add+git stash --keep-index .
Vá ver e avalie a resposta dele, que deve ser a oficial (em vez da minha).

Sobre essa opção, chhh aponta um fluxo de trabalho alternativo nos comentários:

você deve " git reset --soft" após esse estoque para recuperar o armazenamento temporário claro: para retornar
ao estado original - que é uma área de armazenamento temporário clara e com apenas algumas modificações não preparadas, é possível redefinir suavemente o índice para obter (sem cometendo qualquer coisa como você - bukzor - fez).


(Resposta original em junho de 2010: esconderijo manual)

No entanto, o git stash save --patchpoderia permitir que você obtenha o armazenamento parcial que deseja:

Com --patch, você pode selecionar de forma interativa pedaços no diff entre HEAD e a árvore de trabalho a ser escondida.
A entrada stash é construída de modo que seu estado de índice seja o mesmo do seu repositório e sua árvore de trabalho contém apenas as alterações que você selecionou interativamente. As alterações selecionadas são revertidas da sua árvore de trabalho.

No entanto, isso salvará o índice completo (que pode não ser o que você deseja, pois pode incluir outros arquivos já indexados) e uma árvore de trabalho parcial (que pode parecer com a que você deseja ocultar).

git stash --patch --no-keep-index

pode ser um ajuste melhor.


Se --patchnão funcionar, um processo manual pode:

Para um ou vários arquivos, uma solução intermediária seria:

  • copie-os para fora do repositório Git
    (na verdade, o eleotlecram propõe uma alternativa interessante )
  • git stash
  • copie-os de volta
  • git stash # desta vez, apenas os arquivos que você deseja são escondidos
  • git stash pop stash@{1} # reaplique todas as modificações de seus arquivos
  • git checkout -- afile # redefine o arquivo para o conteúdo HEAD, antes de qualquer modificação local

No final desse processo bastante complicado, você terá apenas um ou vários arquivos armazenados.

VonC
fonte
3
Isso é legal, mas muitas vezes eu modifiquei muitos arquivos, portanto, usar o patch é irritante #
Casebash
6
@VonC: É bom estilo ter apenas uma resposta por resposta. Além disso, copiar e colar as respostas de outras pessoas é uma má educação.
bukzor
3
@bukzor: Sinto muito se minha resposta editada parecia inadequada. Minha única intenção era dar mais visibilidade à sua resposta. Eu editei novamente meu post, a fim de tornar essa intenção mais clara.
VonC 12/12
1
@Kal: verdadeira, stackoverflow.com/a/13941132/6309 sugere um git reset(misto)
VonC
3
git is fundamentally about managing a all repository content and index and not one or several files- essa implementação está ofuscando o problema que está sendo resolvido; é uma explicação, mas não uma justificativa. Qualquer sistema de controle de origem é sobre "gerenciar vários arquivos". Veja quais comentários são mais votados.
Victor Sergienko
90

Quando git stash -p(ou git add -pcom stash --keep-index) seria demasiado pesado, eu achei mais fácil de usar diff, checkoute apply:

Para "esconder" apenas um arquivo / diretório específico:

git diff path/to/dir > stashed.diff
git checkout path/to/dir

Depois

git apply stashed.diff
azulado
fonte
1
Alternativa interessante à git add -pque mencionei na minha própria resposta acima. +1.
VonC 12/02
11
Observe que se você tiver arquivos binários (como PNGs), eles não serão exibidos no arquivo diff. Portanto, essa não é uma solução 100%.
void.pointer
1
@RobertDailey: Esse é um ponto interessante para mim, como git diff > file.diffe git applysão meus habituais ferramentas Stash parciais. Talvez eu precise considerar mudar git stash -ppara conjuntos de alterações maiores.
thekingoftruth
1
@thekingoftruth Aqui é o alias eu uso para criar arquivos de patch, e faz binários de apoio: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Observe, no entanto, isso requer que suas alterações sejam confirmadas.
void.pointer
2
Isso não estava funcionando corretamente para mim se o arquivo para esconder fosse algo parecido ../../foo/bar.txt. O patch gera OK, mas preciso ir para a raiz do repositório para aplicar o patch. Portanto, se você estiver tendo problemas com isso, verifique se está fazendo isso no diretório raiz do repositório.
Michael Anderson
86

Use git stash push, assim:

git stash push [--] [<pathspec>...]

Por exemplo:

git stash push -- my/file.sh

Está disponível desde o Git 2.13, lançado na primavera de 2017.

sandstrom
fonte
1
Mas eu git stash pushjá mencionei na minha resposta acima em março passado, há 5 meses. E eu detalhei esse novo comando do Git 2.13 aqui: stackoverflow.com/a/42963606/6309 .
VonC 15/08/19
Estou feliz que o Git esteja avançando tão rapidamente, por um longo tempo isso não foi possível e, em seguida, o 2.13 foi lançado e, de repente, existe uma solução simples disponível!
sandstrom 23/01
1
@VonC você está certo, você também mencionou a resposta correta, no entanto, entre as duas respostas, essa é mais fácil de ler (sem texto confuso e também há um exemplo). Talvez eles deveriam ter editado a sua resposta em vez
Utopik
@ Utopik Você me disse que "você está certo" ... mas sim, editei minha resposta para incluir um exemplo.
VonC
Alguém então usa git stash applypara recuperar as alterações ocultas?
Chad
49

Digamos que você tenha 3 arquivos

a.rb
b.rb
c.rb

e você deseja ocultar apenas b.rb e c.rb, mas não a.rb

você pode fazer algo assim

# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp" 

# then stash the other files
git stash save "stash message"

# then undo the previous temp commit
git reset --soft HEAD^
git reset

E você está pronto! HTH.

venkatareddy
fonte
29

Outra maneira de fazer isso:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}

git checkout <"files you put in your stash">

Eu vim com isso depois que (mais uma vez) cheguei a esta página e não gostei das duas primeiras respostas (a primeira resposta simplesmente não responde à pergunta e não gostei muito de trabalhar com o -pmodo interativo).

A idéia é a mesma que o @VonC sugeriu usar arquivos fora do repositório, você salva as alterações desejadas em algum lugar, remove as alterações que não deseja no seu stash e, em seguida, aplica novamente as alterações que você removeu. No entanto, eu usei o git stash como o "algum lugar" (e, como resultado, há uma etapa extra no final: remover as alterações que você coloca na esconderijo, porque você as removeu também do caminho).

Jaspe
fonte
1
Eu prefiro essa abordagem mais. Ele fornece um fluxo de trabalho fácil no tortoisegit usando apenas comandos stash e reverso.
Mark Ch
Não é recomendável consultar respostas sobre o uso de posições de SO. As posições mudam conforme as classificações mudam.
Bryan Ash
2
@BryanAsh Bem, não é como se isso importasse aqui. Estou dando uma anedota, em vez de realmente me referir às outras respostas. A mensagem é que eu não gostei das respostas que a comunidade gostou e não do que essas respostas realmente contêm. Além disso, a diferença de 900 votos entre a segunda e a terceira resposta torna improvável que isso mude no futuro próximo, e se alguma vez mudar, sempre posso editá-lo para dizer "o melhor para as respostas da época". Realmente, não vejo como isso é algum tipo de problema nessa situação.
Jasper
23

Atualização (14/2/2015) - Reescrevi o script um pouco, para lidar melhor com o caso de conflitos, que agora devem ser apresentados como conflitos não imersos em vez de arquivos .rej.


Costumo achar mais intuitivo fazer o inverso da abordagem de @ bukzor. Ou seja, para organizar algumas alterações e, em seguida, ocultar apenas as alterações em etapas.

Infelizmente, o git não oferece um stash git --only-index ou similar, então criei um script para fazer isso.

#!/bin/sh

# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`

# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`

# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`

# get back to a clean state with no changes, staged or otherwise
git reset -q --hard

# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash

# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT

CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
    # If there are no conflicts, it's safe to reset, so that
    # any previously unstaged changes remain unstaged
    #
    # However, if there are conflicts, then we don't want to reset the files
    # and lose the merge/conflict info.
    git reset -q
fi

Você pode salvar o script acima como git-stash-indexem algum lugar do seu caminho e invocá-lo como git stash-index

# <hack hack hack>
git add <files that you want to stash>
git stash-index

Agora, o stash contém uma nova entrada que contém apenas as alterações que você organizou e sua árvore de trabalho ainda contém alterações não organizadas.

Em alguns casos, as alterações na árvore de trabalho podem depender das alterações no índice; portanto, quando você armazena as alterações no índice, as alterações na árvore de trabalho apresentam um conflito. Nesse caso, você obterá os conflitos comuns não resolvidos que você pode resolver com o git merge / git mergetool / etc.

JesusFreke
fonte
Recomende em pushdvez de cde popdno final do script, para que, se o script for bem-sucedido, o usuário acabe no mesmo diretório que antes de executá-lo.
Nate
1
@ Nate: até onde eu sei, ele só deve alterar o diretório do usuário se ele originou o script. Se você executar o script normalmente (~ / bin / git-stash-index) ou via git (git stash-index), ele será executado em uma sessão de terminal separada e qualquer alteração de diretório de trabalho nessa sessão não afetará o diretório de trabalho na sessão do terminal do usuário. Você conhece um caso de uso comum quando isso não é verdade? (excepto que adquirem o roteiro, que eu não iria considerar "comum")
JesusFreke
20

Se você não deseja especificar uma mensagem com suas alterações ocultas, passe o nome do arquivo após um traço duplo.

$ git stash -- filename.ext

Se for um arquivo não rastreado / novo, será necessário prepará-lo primeiro.

Este método funciona nas versões git 2.13+

sealocal
fonte
Essa resposta é detalhada, é concisa. Se isso ajudar alguém, eu deixarei. Ninguém nesta página menciona esta sintaxe e resultado - eles mencionam `git stash push`.
precisa saber é
Esta é a resposta que eu estava procurando. Obrigado! +1
nicodp 27/03
19

Como criar ramificações no Git é trivial, você pode simplesmente criar uma ramificação temporária e verificar os arquivos individuais nela.

shangxiao
fonte
2
Você não pode criar uma ramificação com edições sem etapas. Você pode mover todas as edições com facilidade para uma nova ramificação (stash / stash pop), mas volta à estaca zero: como você testa sua ramificação apenas com algumas dessas edições, sem perder as outras?
precisa saber é o seguinte
7
Você não pode mudar de ramificação se tiver alterações locais. No entanto, você pode criar uma nova ramificação e adicionar / confirmar arquivos seletivamente e, em seguida, criar outra ramificação e fazer o mesmo recursivamente ... então faça o check-out da ramificação original e volte a fundir-se seletivamente. Acabei de fazê-lo. Na verdade, parece a maneira natural de fazer as coisas, pois você essencialmente cria ramos de recursos.
iain 17/02/12
3
@iain, você pode mudar de ramificação se tiver alterações locais, desde que não exijam uma mesclagem. Veja Exemplo Gist . Isso é verdade a partir do Git v2.7.0, pelo menos.
Colin D Bennett
18

Você pode simplesmente fazer isso:

git stash push "filename"

ou com uma mensagem opcional

git stash push -m "Some message" "filename"
vinodsaluja
fonte
1
Isso não acrescenta nada de novo. Git push esconderijo já é mencionado em respostas múltiplas
JesusFreke
12

Salve o código a seguir em um arquivo, por exemplo, nomeado stash. O uso é stash <filename_regex>. O argumento é a expressão regular para o caminho completo do arquivo. Por exemplo, para esconder a / b / c.txt, stash a/b/c.txtou stash .*/c.txtetc.

$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml

Código para copiar no arquivo:

#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]

spawn git stash -p

for {} 1 {} {
  expect {
    -re "diff --git a/($filename_regexp) " {
      set filename $expect_out(1,string)
    }
    "diff --git a/" {
      set filename ""
    }
    "Stash this hunk " {
      if {$filename == ""} {
        send "n\n"
      } else {
        send "a\n"
        send_user "$filename\n"
      }
    }
    "Stash deletion " {
      send "n\n"
    }
    eof {
      exit
    }
  }
}
Damasco
fonte
2
Ótimo método. Eu teria escolhido isso como resposta. Dica para futuros leitores: você precisa corresponder no caminho completo. Por exemplo, stash subdir / foo.c
er0 21/10
12

Apenas no caso de você realmente querer descartar as alterações sempre que usar git stash(e não usar o git stash para esconder temporariamente), nesse caso, você pode usar

git checkout -- <file>

[ NOTA ]

Essa git stashé apenas uma alternativa mais rápida e simples para ramificar e fazer coisas.

Devesh
fonte
8

O problema com a solução intermediária do VonC de copiar arquivos para fora do repositório Git é que você perde as informações do caminho, o que torna a cópia de vários arquivos posteriormente mais tarde.

Um achado mais fácil de usar tar (provavelmente ferramentas semelhantes o farão) em vez de copiar:

  • caminho do cvf tar /tmp/stash.tar / para / some / caminho do arquivo / para / some / other / file (... etc.)
  • caminho de saída do git / para / some / caminho do arquivo / para / some / other / file
  • esconderijo
  • tar xvf /tmp/stash.tar
  • etc. (consulte a sugestão intermediária do VonC)
eleotlecram
fonte
checkout -fnão é necessário, checkout(sem -f) é suficiente, eu atualizei a resposta.
eleotlecram
8

Às vezes, fiz uma alteração não relacionada em minha ramificação antes de executá-la e quero movê-la para outra ramificação e executá-la separadamente (como mestre). Eu faço isso:

git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...

Observe o primeiro stashe stash poppode ser eliminado, você pode levar todas as alterações até omaster filial quando efetuar o pagamento, mas somente se não houver conflitos. Além disso, se você estiver criando uma nova ramificação para as alterações parciais, precisará do stash.

Você pode simplificá-lo assumindo que não há conflitos nem nova ramificação:

git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...

Stash nem mesmo necessário ...

void.pointer
fonte
8

Isso pode ser feito facilmente em 3 etapas, usando o SourceTree.

  1. Confirme temporariamente tudo o que você não deseja esconder.
  2. O Git adiciona todo o resto e depois o esconde.
  3. Pop seu commit temporário executando git reset, visando o commit antes do seu temporário.

Tudo isso pode ser feito em questão de segundos no SourceTree, onde você pode simplesmente clicar nos arquivos (ou mesmo nas linhas individuais) que deseja adicionar. Uma vez adicionado, basta enviá-los para um commit temporário. Em seguida, clique na caixa de seleção para adicionar todas as alterações e clique em esconderijo para esconder tudo. Com as alterações ocultas fora do caminho, olhe para a lista de confirmação e observe o hash da confirmação antes da confirmação temporária e execute 'git reset hash_b4_temp_commit', que é basicamente como "popping" a confirmação, redefinindo sua ramificação para o comprometer-se diante dele. Agora, você fica com apenas as coisas que você não quer esconder.

Triynko
fonte
8

Eu usaria git stash save --patch. Não acho a interatividade irritante porque existem opções para aplicar a operação desejada a arquivos inteiros.

Raffi Khatchadourian
fonte
3
Espantado, há tão pouco apoio para essa resposta que é a melhor solução sem a necessidade de um ensaio.
Robertbuck # 4/17
Definitivamente, a boa resposta git stash -ppermite que você armazene um arquivo inteiro rapidamente e saia depois.
precisa
7

Toda resposta aqui é tão complicada ...

Que tal isso para "esconderijo":

git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash

Isso para exibir o arquivo novamente:

git apply /tmp/stash.patch

Exatamente o mesmo comportamento de esconder um arquivo e inseri-lo novamente.

Christophe Fondacci
fonte
Eu tentei, mas nada acontece. Quando eu git applytenho nenhum erro, mas as alterações não são trazidos de volta nem
ClementWalter
O arquivo de correção que você gerou em / tmp provavelmente foi excluído. Você pode ter reiniciado entre o diff e o apply. Tente outro local mais permanente. Isso funciona. Verifique também o conteúdo do arquivo de correção.
Christophe Fondacci
4

Analisei respostas e comentários para esse e vários tópicos semelhantes. Esteja ciente de que nenhum dos comandos a seguir está correto com o objetivo de poder ocultar arquivos específicos rastreados / não rastreados :

  • git stash -p (--patch): selecione blocos manualmente, excluindo arquivos não rastreados
  • git stash -k (--keep-index): esconda todos os arquivos rastreados / não rastreados e mantenha-os no diretório de trabalho
  • git stash -u (--include-untracked): esconda todos os arquivos rastreados / não rastreados
  • git stash -p (--patch) -u (--include-untracked): comando inválido

Atualmente, o método mais razoável para ocultar arquivos específicos rastreados / não rastreados é:

  • Confirme temporariamente os arquivos que você não deseja ocultar
  • Adicionar e esconder
  • Pop a confirmação temporária

Eu escrevi um script simples para este procedimento em uma resposta a outra pergunta , e há etapas para executar o procedimento no SourceTree aqui .

ZimbiX
fonte
4

Solução

Alterações locais:

  • file_A (modificado) não preparado
  • file_B (modificado) não preparado
  • file_C (modificado) não preparado

Para criar um stash "my_stash" apenas com as alterações no arquivo_C :

1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop stash@#{1}

Feito.


Explicação

  1. adicionar arquivo_C à área de preparação
  2. crie um stash temporário chamado "temp_stash" e mantenha as alterações em file_C
  3. crie o stash desejado ("my_stash") com apenas as alterações no arquivo_C
  4. aplique as alterações em "temp_stash" (file_A e file_B) no seu código local e exclua o stash

Você pode usar o status git entre as etapas para ver o que está acontecendo.

Alex 75
fonte
3

Quando você tenta alternar entre dois ramos, essa situação ocorre.

Tente adicionar os arquivos usando " git add filepath".

Mais tarde, execute esta linha

git stash --keep-index

Sireesh Yarlagadda
fonte
3

Para esconder um único arquivo, use git stash --patch [file].

Isso vai prompt: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Basta digitar a(esconder esse pedaço e todos os pedaços posteriores no arquivo) e você estará bem.

Vinicius Brasil
fonte
Faltando pushcomo emgit stash push --patch [file]
Filipe Esperandio 02/10
O @FilipeEsperandio pushsó funciona nas versões mais recentes do Git save. Em ambos os casos pushou saveestão implícitas chamando stash: "Chamando git stash sem nenhum argumento é equivalente a empurrar git stash", docs
patrick
2

Situação similar. Comprometi e percebi que não está tudo bem.

git commit -a -m "message"
git log -p

Com base nas respostas, isso me ajudou.

# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push
David Hrbáč
fonte
2

Nesta situação, eu git add -p(interativo), git commit -m blahe então escondo o que resta, se necessário.

J0hnG4lt
fonte
2

Não sei como fazer isso na linha de comando, apenas usando o SourceTree. Digamos que você alterou o arquivo A e tem dois trechos no arquivo B. Se você deseja ocultar apenas o segundo pedaço no arquivo B e deixar tudo intocado, faça o seguinte:

  1. Encenar tudo
  2. Execute alterações em sua cópia de trabalho que desfaz todas as alterações no arquivo A. (por exemplo, inicie a ferramenta diff externa e faça com que os arquivos correspondam.)
  3. Faça com que o arquivo B tenha a aparência de apenas uma segunda alteração aplicada. (por exemplo, inicie a ferramenta diff externa e desfaça a primeira alteração.)
  4. Crie uma ocultação usando "Manter alterações faseadas".
  5. Unstage everything
  6. Feito!
Juozas Kontvainis
fonte
2
git add .                           //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash                           //stash the file(s)
git reset .                         // unstage all staged files
git stash pop                       // unstash file(s)
celikz
fonte
1
Bem, você não deve fazer isso. A resposta deve fornecer uma solução para a pergunta. Você poderia apenas fazer sua própria pergunta.
21718 LJJ
Esta solução é uma das respostas mais fáceis para a pergunta ESTA. Leia a pergunta, compare todas as respostas e as minhas. Se você tiver alguma dúvida de que essa resposta não seja uma solução aplicável nem informações insuficientes sobre a pergunta, poderemos conversar novamente.
22718 Celikz
Isso não funcionará, porque o terceiro comando, "git stash", não honrará os arquivos escalonados. Os arquivos em estágios e não em estágio vão para o stash. As perguntas perguntam especificamente como esconder apenas um arquivo.
CyberProdigy 27/02/19
0

Uma maneira complicada seria primeiro comprometer tudo:

git add -u
git commit // creates commit with sha-1 A

Redefina de volta para o commit original, mas faça o check-out do arquivo_do_one no novo commit:

git reset --hard HEAD^
git checkout A path/to/the_one_file

Agora você pode esconder o_one_arquivo:

git stash

Para limpar, salve o conteúdo confirmado em seu sistema de arquivos e redefina a confirmação original:

git reset --hard A
git reset --soft HEAD^

Sim, um pouco estranho ...

Martin G
fonte
0

Não encontrei resposta para ser o que eu precisava e é tão fácil quanto:

git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash

Isso esconde exatamente um arquivo.

SCBuergel.eth
fonte
0

Resposta rápida


Para reverter um arquivo alterado específico no git, você pode fazer a seguinte linha:

git checkout <branch-name> -- <file-path>

Aqui está um exemplo real:

git checkout master -- battery_monitoring/msg_passing.py

Benyamin Jafari
fonte
0

Se você deseja esconder alguns arquivos alterados, basta apenas

Adicione os arquivos que você não deseja esconder, no Stage , e executegit stash save --keep-index

Esconderá todos os arquivos alterados em estágios

Amin Shojaei
fonte