Por engano, adicionei arquivos ao Git usando o comando:
git add myfile.txt
Ainda não corri git commit
. Existe uma maneira de desfazer isso, para que esses arquivos não sejam incluídos no commit?
git
version-control
git-commit
git-stage
paxos1977
fonte
fonte
HEAD
ouhead
agora pode usar@
no lugar deHEAD
vez. Veja esta resposta (última seção) para saber por que você pode fazer isso.git checkout
não remove as alterações faseadas do índice de confirmação. Ele apenas reverte as alterações não organizadas para a última revisão confirmada - que, a propósito, também não é o que eu quero, quero essas alterações, apenas as desejo em uma consolidação posterior.Respostas:
Você pode desfazer
git add
antes de confirmar comque o removerá do índice atual (a lista "prestes a ser confirmada") sem alterar mais nada.
Você pode usar
sem qualquer nome de arquivo para desestabilizar todas as alterações devidas. Isso pode ser útil quando houver muitos arquivos a serem listados um por um em um período de tempo razoável.
Nas versões antigas do Git, os comandos acima são equivalentes
git reset HEAD <file>
egit reset HEAD
, respectivamente, e falharão seHEAD
for indefinido (porque você ainda não fez nenhum commit no seu repositório) ou ambíguo (porque você criou um ramo chamadoHEAD
, o que é uma coisa estúpida que você não deveria fazer). Isto foi mudado em Git 1.8.2 , embora, por isso em versões modernas de Git você pode usar os comandos acima, mesmo antes de fazer sua primeira cometer:fonte
git add
substituir uma versão faseada anterior, não podemos recuperá-la. Tentei esclarecer isso na minha resposta abaixo.git reset HEAD *.ext
Ondeext
estão os arquivos da extensão especificada que você deseja remover. Para mim, foi*.bmp
e*.zip
git rm --cached
), significa que você está se preparando para fazer uma confirmação que exclui esse arquivo.git reset HEAD <filename>
por outro lado, copiará o arquivo de HEAD para o índice, para que o próximo commit não mostre as alterações feitas nesse arquivo.git reset -p
igualgit add -p
. Isso é incrível!git add
que deseja recuperar (61/3AF3...
- > identificação do objeto613AF3...
), entãogit cat-file -p <object-id>
(pode valer a pena para recuperar várias horas de trabalho, mas também uma lição para cometer mais vezes ...)Você quer:
Raciocínio:
Quando eu era novo nisso, tentei pela primeira vez
(para desfazer toda a minha adição inicial), apenas para receber esta (não tão) mensagem útil:
Acontece que isso ocorre porque a referência HEAD (ramificação?) Não existe até depois do primeiro commit. Ou seja, você terá o mesmo problema de iniciante que eu, se o seu fluxo de trabalho, como o meu, fosse algo como:
git init
git add .
git status
... muitos rolos de porcaria por ...
=> Porra, eu não queria adicionar tudo isso.
google "desfazer git add"
=> encontrar estouro de pilha - yay
git reset .
=> fatal: falha ao resolver 'HEAD' como uma referência válida.
Acontece ainda que há um bug registrado contra a imprudência disso na lista de discussão.
E que a solução correta estava lá na saída de status do Git (que, sim, encarei como 'porcaria)
E a solução é realmente usar
git rm --cached FILE
.Observe os avisos em outros lugares aqui -
git rm
exclui sua cópia de trabalho local do arquivo, mas não se você usar --cached . Aqui está o resultado degit help rm
:Eu uso
para remover tudo e começar de novo. No entanto, não funcionou, porque, embora
add .
seja recursivo, acaba sendorm
necessário-r
recuperar. Suspiro.Ok, agora voltei para onde comecei. Da próxima vez, vou
-n
fazer uma corrida a seco e ver o que será adicionado:Eu fechei tudo em um lugar seguro antes de confiar
git help rm
em--cached
não destruir nada (e se eu escrevesse errado).fonte
rm -rf .git
,git init
porque não confiavagit rm --cached
em manter minha cópia de trabalho. Diz um pouco sobre como o git ainda é excessivamente complexo em alguns lugares.git unstage
deve ser apenas um comando padrão de estoque, não me importo se posso adicioná-lo como um alias.git reset HEAD <File>...
git add
comando adicionou novos arquivos, mas não altera os arquivos existentes.Se você digitar:
O Git lhe dirá o que está sendo preparado etc., incluindo instruções sobre como desestágio:
Acho que o Git faz um bom trabalho em me convencer a fazer a coisa certa em situações como essa.
Nota: As versões recentes do Git (1.8.4.x) alteraram esta mensagem:
fonte
add
arquivo ed já estava sendo rastreado (aadd
única salva foi uma nova versão no cache - aqui será exibida sua mensagem). Em outros lugares, se o arquivo não foi previamente encenado, ele irá mostraruse "git rm --cached <file>..." to unstage
git reset HEAD <file>
um é o único que vai funcionar no caso de você querer unstage um arquivo de exclusãogit reset HEAD
para o palco.Para esclarecer:
git add
move as alterações do diretório de trabalho atual para a área intermediária (índice).Esse processo é chamado de preparação . Portanto, o comando mais natural para preparar as alterações (arquivos alterados) é o óbvio:
git add
é apenas um alias mais fácil de digitar paragit stage
Pena que não há
git unstage
nemgit unadd
comandos. O relevante é mais difícil de adivinhar ou lembrar, mas é bastante óbvio:Podemos facilmente criar um alias para isso:
E, finalmente, temos novos comandos:
Pessoalmente, uso apelidos ainda mais curtos:
fonte
git stage
é o alias paragit add
, que é o comando histórico, tanto no Git quanto em outro SCM. Foi adicionado em dezembro de 2008 com o commit 11920d28da no "repositório git do git", se posso dizer.Além da resposta aceita, se o arquivo adicionado por engano for enorme, você provavelmente perceberá que, mesmo depois de removê-lo do índice com '
git reset
', ele ainda parece ocupar espaço no.git
diretório.Isso não é nada para se preocupar; o arquivo ainda está no repositório, mas apenas como um "objeto solto". Ele não será copiado para outros repositórios (via clone, push) e o espaço será recuperado eventualmente - embora talvez não em breve. Se você estiver ansioso, você pode executar:
Atualização (a seguir, é minha tentativa de esclarecer algumas confusões que podem surgir das respostas mais votadas):
Então, qual é o verdadeiro desfazer de
git add
?git reset HEAD <file>
?ou
git rm --cached <file>
?A rigor, e se não me engano: nenhum .
git add
não pode ser desfeito - com segurança, em geral.Vamos lembrar primeiro o que
git add <file>
realmente faz:Se não
<file>
foi rastreado anteriormente , ogit add
adiciona ao cache , com seu conteúdo atual.Se já
<file>
foi rastreado ,git add
salva o conteúdo atual (instantâneo, versão) no cache. No Git, essa ação ainda é chamada de adição (não apenas uma atualização ), porque duas versões diferentes (instantâneos) de um arquivo são consideradas como dois itens diferentes: portanto, estamos realmente adicionando um novo item ao cache, para ser eventualmente cometido mais tarde.À luz disso, a questão é um pouco ambígua:
O cenário do OP parece ser o primeiro (arquivo não rastreado), queremos que o "desfazer" remova o arquivo (não apenas o conteúdo atual) dos itens rastreados. Se for esse o caso, não há problema em executar
git rm --cached <file>
.E também poderíamos correr
git reset HEAD <file>
. Geralmente, isso é preferível, porque funciona nos dois cenários: ele também desfaz quando adicionamos erroneamente uma versão de um item já rastreado.Mas existem duas advertências.
Primeiro: existe (como indicado na resposta) apenas um cenário em que
git reset HEAD
não funciona, masgit rm --cached
funciona: um novo repositório (sem confirmação). Mas, realmente, este é um caso praticamente irrelevante.Segundo: esteja ciente de que
git reset HEAD
não é possível recuperar magicamente o conteúdo do arquivo em cache anteriormente, apenas o ressincroniza a partir do HEAD. Se nossosgit add
erros de orientação substituíram uma versão não confirmada em etapas anterior, não podemos recuperá-la. É por isso que, estritamente falando, não podemos desfazer [*].Exemplo:
Obviamente, isso não é muito crítico se apenas seguirmos o fluxo de trabalho preguiçoso usual de fazer 'git add' apenas para adicionar novos arquivos (caso 1) e atualizarmos novos conteúdos por meio do
git commit -a
comando commit,* (Editar: o acima exposto está praticamente correto, mas ainda pode haver algumas maneiras levianas / complicadas de recuperar as mudanças que foram encenadas, mas não confirmadas e depois substituídas - veja os comentários de Johannes Matokic e iolsmit)
fonte
git cat-file
poderá ser usado para recuperar seu conteúdo.git add
é a viagit fsck --unreachable
que listará todos os objetos inacessíveis, que você poderá inspecionargit show SHA-1_ID
ougit fsck --lost-found
que irá> Escrever objetos pendentes em.git/lost-found/commit/
ou.git/lost-found/other/
, dependendo do tipo. Veja tambémgit fsck --help
Desfazer um arquivo que já foi adicionado é bastante fácil usando o Git. Para redefinir
myfile.txt
, que já foram adicionados, use:Explicação:
Depois de preparar os arquivos indesejados, para desfazer, você pode fazer
git reset
.Head
é o chefe do seu arquivo no local e o último parâmetro é o nome do seu arquivo.Eu criei as etapas na imagem abaixo em mais detalhes para você, incluindo todas as etapas que podem ocorrer nesses casos:
fonte
irá "un-add" tudo que você adicionou do seu diretório atual recursivamente
fonte
git reset HEAD <file>
diriafatal: Failed to resolve 'HEAD' as a valid ref.
Corre
e remova todos os arquivos manualmente ou selecionando todos eles e clicando no botão unstage from commit .
fonte
git-gui
...." :)O Git possui comandos para todas as ações imagináveis, mas precisa de amplo conhecimento para acertar as coisas e, por isso, é contra-intuitivo na melhor das hipóteses ...
O que você fez antes:
git add .
, ougit add <file>
.O que você quer:
Remova o arquivo do índice, mas mantenha-o com versão e com alterações não confirmadas na cópia de trabalho:
Redefina o arquivo para o último estado do HEAD, desfazendo as alterações e removendo-as do índice:
Isso é necessário, pois
git reset --hard HEAD
não funcionará com arquivos únicos.Remova
<file>
do índice e controle de versão, mantendo o arquivo sem versão com alterações na cópia de trabalho:Remova
<file>
completamente a cópia de trabalho e o controle de versão:fonte
reset head
desfaz suas alterações atuais, mas o arquivo ainda está sendo monitorado pelo git.rm --cached
remove o arquivo do controle de versão, para que o git não o verifique mais em busca de alterações (e também remove as alterações atuais eventualmente indexadas, informadas ao git pelo anterioradd
), mas o arquivo alterado será mantido na sua cópia de trabalho, que está na sua pasta de arquivos no disco rígido.git reset HEAD <file>
temporária - o comando será aplicado apenas ao próximo commit, masgit rm --cached <file>
será instável até que seja adicionado novamentegit add <file>
. Além disso,git rm --cached <file>
significa que se você enviar essa ramificação para o controle remoto, qualquer pessoa que puxe a ramificação receberá o arquivo REALMENTE excluído de sua pasta.A questão não está claramente colocada. A razão é que
git add
tem dois significados:git rm --cached file
.git reset HEAD file
.Em caso de dúvida, use
Porque faz a coisa esperada nos dois casos.
Aviso: se você fizer
git rm --cached file
um arquivo que foi modificado (um arquivo que existia anteriormente no repositório), o arquivo será removidogit commit
! Ele ainda existirá no seu sistema de arquivos, mas se alguém puxar sua confirmação, o arquivo será excluído da árvore de trabalho.git status
dirá se o arquivo foi um novo arquivo ou foi modificado :fonte
git rm --cached somefile
. Espero que esta resposta suba a página para uma posição de destaque, onde possa proteger os novatos de serem enganados por todas as falsas alegações.Se você está no seu commit inicial e não pode usá-lo
git reset
, basta declarar "Git bankruptcy", excluir a.git
pasta e começar de novofonte
git add -A && git rm --cached EXCLUDEFILE && git commit -m 'awesome commit'
(Isto também funciona quando não há commits anteriores, reFailed to resolve 'HEAD'
problema)Conforme muitas das outras respostas, você pode usar
git reset
MAS:
Eu encontrei este ótimo post que realmente adiciona o comando Git (bem, um apelido) para
git unadd
: veja git unadd para obter detalhes ou ..Simplesmente,
Agora você pode
fonte
Use
git add -i
para remover arquivos recém-adicionados do seu próximo commit. Exemplo:Adicionando o arquivo que você não queria:
Entrar em add interativo para desfazer seu add (os comandos digitados no git aqui são "r" (reverter), "1" (primeira entrada na lista mostra shows de reversão), 'return' para sair do modo de reversão e "q" (Sair):
É isso aí! Aqui está sua prova, mostrando que "foo" está de volta à lista não rastreada:
fonte
git remove
ougit rm
pode ser usado para isso, com a--cached
bandeira. Tentar:fonte
git rm --cached ...
irá remover arquivos de um repositório git. Eles ainda existirão no seu computador, mas isso é MUITO diferente das alterações desatualizadas em um arquivo. Para quem se deparar com isso, não é uma resposta válida para a pergunta.Aqui está uma maneira de evitar esse problema irritante quando você inicia um novo projeto:
git init
.O Git torna muito difícil fazer isso
git reset
se você não tiver nenhum commit. Se você criar um pequeno commit inicial apenas para ter um, depois disso, você podegit add -A
egit reset
quantas vezes quiser para obter tudo certo.Outra vantagem desse método é que, se você enfrentar problemas de final de linha posteriormente e precisar atualizar todos os seus arquivos, é fácil:
fonte
autocrlf
valor ... Isso não funcionará em todos os projetos, dependendo das configurações.git reset somefile
egit reset
ambos trabalham antes de fazer o primeiro commit, agora. Este tem sido o caso desde que vários Git são lançados de volta.Talvez o Git tenha evoluído desde que você postou sua pergunta.
Agora você pode tentar:
Deve ser o que você está procurando.
fonte
Observe que, se você não especificar uma revisão, precisará incluir um separador. Exemplo do meu console:
(Git versão 1.7.5.4)
fonte
git reset <path>
e funciona muito bem sem um separador. Também estou usando o git 1.9.0. Talvez não funcione em versões mais antigas?Para remover novos arquivos da área de preparação (e apenas no caso de um novo arquivo), conforme sugerido acima:
Use rm --cached apenas para novos arquivos adicionados acidentalmente.
fonte
--cached
é uma parte realmente importante aqui.Para redefinir todos os arquivos em uma pasta específica (e suas subpastas), você pode usar o seguinte comando:
fonte
git status
para ver qualquer coisa restante e redefini-lo manualmente, ou sejagit reset file
.Use o
*
comando para manipular vários arquivos por vez:etc.
fonte
.*
ou.*.prj
Basta digitar
git reset
que irá reverter e é como se você nunca tivesse digitadogit add .
desde o seu último commit. Verifique se você se comprometeu antes.fonte
Suponha que eu crie um novo arquivo
newFile.txt
:Suponha que eu adicione o arquivo acidentalmente
git add newFile.txt
:Agora eu quero desfazer este complemento, antes de confirmar
git reset newFile.txt
:fonte
Para um arquivo específico:
Para todos os arquivos adicionados:
Nota: o checkout altera o código nos arquivos e passa para o último estado atualizado (confirmado). reset não altera os códigos; apenas redefine o cabeçalho.
fonte
git reset <file>
egit checkout <file>
.Este comando irá descompactar suas alterações:
Você também pode usar
para adicionar partes de arquivos.
fonte
Há também o modo interativo:
Escolha a opção 3 para adicionar arquivos. No meu caso, geralmente quero adicionar mais de um arquivo e, no modo interativo, você pode usar números como este para adicionar arquivos. Isso levará tudo, exceto 4: 1, 2, 3 e 5
Para escolher uma sequência, basta digitar 1-5 para obter todos de 1 a 5.
Arquivos de teste do Git
fonte
Para desfazer
git add
, use:fonte
Removerá um arquivo chamado filename.txt do índice atual, a área "prestes a ser confirmada", sem alterar mais nada.
fonte
git add myfile.txt
# Isso adicionará seu arquivo à lista a ser confirmadaBem oposto a este comando,
então, você estará no estado anterior. O especificado estará novamente na lista não rastreada (estado anterior).
Ele redefinirá sua cabeça com o arquivo especificado. então, se sua cabeça não tiver, significa que ela será redefinida.
fonte
No Sourcetree, você pode fazer isso facilmente através da GUI. Você pode verificar qual comando o Sourcetree usa para desfazer um arquivo.
Criei um novo arquivo e o adicionei ao Git. Em seguida, desfiz o estágio usando a GUI do Sourcetree. Este é o resultado:
O Sourcetree usa
reset
para desfazer novos arquivos.fonte
fonte