Mudanças sem etapas deixadas após a redefinição do git --hard

275

Depois git reset --hard, git statusme fornece arquivos dentro da Changes not staged for commit:seção.

Eu também tentei git reset ., git checkout -- .e git checkout-index -f -a, sem sucesso.

Então, como posso me livrar dessas mudanças sem etapas?

Isso parece atingir apenas os arquivos de projeto do Visual Studio. Esquisito. Veja este colar: http://pastebin.com/eFZwPn9Z . O que é especial nesses arquivos é que, em .gitattributes, tenho:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

Além disso, autocrlfestá definido como false no meu global .gitconfig. Isso poderia ser de alguma forma relevante?

Norswap
fonte
Você aplicou esses comandos a partir da raiz do repositório? Aviso .significa diretório não diretório raiz atual
Alexander
1
Eu realmente fiz isso no repositório raiz.
Norswap 08/07
Qual é a sua gitversão? Ou você está cometendo um erro bobo ou você tem uma versão antiga com erros?
Shahbaz
É git 1.7.4 msysgit. Pode ser um erro, mas os comandos parecem bastante simples, e eu não consegui identificar um erro.
Norswap 08/07
Para o registro, tentei usar a versão mais recente do msysgit (1.7.11), mas o problema persiste.
Norswap 08/07

Respostas:

361

Eu tive o mesmo problema e estava relacionado ao .gitattributesarquivo. No entanto, o tipo de arquivo que causou o problema não foi especificado no .gitattributes.

Consegui resolver o problema simplesmente executando

git rm .gitattributes
git add -A
git reset --hard
GameScripting
fonte
7
É a diretiva * text = auto no arquivo gitattributes. Ele altera automaticamente as terminações dos arquivos, para que os arquivos sejam automaticamente marcados como "modificados" quando você verificar o status.
Cody Django
3
Isso funciona, mas eu não entendo exatamente o porquê. Alguém quer explicar cada comando?
Edwin Stoteler
18
@NLwino, git rm .gitattributesremove os atributos .gitat do índice. git add -Aadiciona tudo (incluindo a remoção de .gitattributes) ao índice, que deveria ser apenas a remoção de .gitattributes, se esse era realmente o problema. git reset --hardredefine todas as alterações não confirmadas, incluindo a remoção de atributos .gitat. Essencialmente, isso ignora .gitattributes (e a * text=autodiretiva) de um commit excluindo-o e redefinindo o índice enquanto é excluído, colocando-o de volta, mas retornando-o, mas depois que você já redefiniu os outros arquivos, eles não foram modificados novamente.
cloudworks
4
@ GameScripting, esta solução não funciona para mim. Não há nenhum arquivo, tais como .gitattributes: "fatal: pathspec' .gitattributes' não encontrou nenhum arquivos"
Pacerier
4
Eu faço isso e diz fatal: pathspec '.gitattributes' did not match any files . O que estou fazendo de errado?
Mel
136

RESOLVIDO!!!

Resolvi esse problema usando as seguintes etapas

1) Remova todos os arquivos do índice do Git.

git rm --cached -r .

2) Reescreva o índice Git para selecionar todas as novas terminações de linha.

git reset --hard

A solução fez parte das etapas descritas no site git https://help.github.com/articles/dealing-with-line-endings/

Jacek Szybisz
fonte
5
Isso funciona quando nada mais faz! Tentamos de tudo neste e em muitos outros tópicos - é uma grande equipe de desenvolvimento, portanto, colocar todos no mesmo crlf foi um pesadelo, mas isso resolve o problema.
tkersh
Interessante ... eu usei "git rm --chached <one_specific_file>, em vez de excluir tudo." Git status "relatou esse arquivo como excluído e não rastreado. Em seguida," git reset --hard "corrige esse arquivo e todos os outros arquivos que foram sendo relatados como "As alterações não encenado" (Antes de usar git rm, eu duro tentou hard reset ou nenhum efeito) Eu amo esses sistemas de controle de origem misteriosa...
joeking
Você sabe, ele exclui todo o seu cache. Em grandes projetos, pode perder muito tempo.
Ohar
Isso é brutal. Você poderia ter feito o mesmo excluindo o diretório repo e re-clonando.
ingyhere
4
Considere que você está no Windows e faz distinção entre maiúsculas e minúsculas. Se você também estiver trabalhando com desenvolvedores que estão em sistemas de arquivos que diferenciam maiúsculas de minúsculas, como Macs ou Linux, eles podem estar enviando tags, ramificações ou mesmo arquivos em casos diferentes. Nessa situação, seu índice mostrará os arquivos existentes que são substituídos pelo sistema operacional quando ele é puxado. A única maneira de corrigir isso seria instituir uma política de nomenclatura no servidor Git (ganchos) ou detectar erros com antecedência.
ingyhere
97

O Git não redefinirá arquivos que não estão no repositório. Então você pode:

$ git add .
$ git reset --hard

Isso preparará todas as alterações, o que fará com que o Git esteja ciente desses arquivos e os redefina.

Se isso não funcionar, você pode tentar ocultar e soltar suas alterações:

$ git stash
$ git stash drop
YuriAlbuquerque
fonte
4
Os arquivos já foram rastreados. Tentei de qualquer maneira e também não funciona. Deve haver algo realmente errado com meu repo, mas não tenho idéia do que. Para o git stash thingy, veja minha resposta para Shahbaz.
Norswap 08/07
O que está acontecendo quando você faz um status de git?
YuriAlbuquerque
1
Eu pensei em uma solução. Faça um commit e um rebase interativo para apagar esse commit.
YuriAlbuquerque
Eu tentei isso em um ponto, e funcionou, difícil. Mais tarde, tentei mais uma vez e descobri o resultado surpreendente descrito na edição da minha resposta.
Norswap 08/07
@YuriAlbuquerque, o Git não entende bem o POLA . O objetivo principal de git reset --hard" redefinir a área de teste e o diretório de trabalho para corresponder "? Se um arquivo não for preparado, obviamente, queremos removê-lo quando o fizermos reset --hard.
Pacerier 20/10/2015
71

Se você usa o Git for Windows, é provável que esse seja o seu problema

Eu tive o mesmo problema e esconderijo, redefinir o hardware, limpar ou até todos eles ainda estavam deixando as alterações para trás. O que acabou por ser o problema foi o modo de arquivo x que não foi configurado corretamente pelo git. Este é um "problema conhecido" com o git para windows. As alterações locais são exibidas no status gitk e git como modo antigo 100755, modo novo 100644, sem nenhuma diferença real de arquivo.

A correção é ignorar o modo de arquivo:

git config core.filemode false

Mais informações aqui

vezenkov
fonte
2
Isso funcionou quando mesmo quando rm -rf *; git checkout HEAD .não funcionou. Ufa!
forumulator
Funcionou para mim, enquanto o stash drop / hard reset / rm .attributes falharam.
Kakyo 11/0418
Isso também trabalhou para mim quando eu tinha problemas trabalhando com repo git em Linux que foi hospedado em um Mac
prmph
trabalhou para mim - tentou de tudo e sim o velho modo vs novo modo era o problema (notei que tinha um número diferente, mas os arquivos são os mesmos)
Taehoon A Kim
Economia de vida e tempo.
Yogesh Patil 20/03
31

Ok, eu meio que resolvi o problema.

Parecia que o .gitattributesarquivo, contendo:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

fez com que os arquivos do projeto parecessem sem estágio. Não sei por que, e realmente espero que alguém a par das maneiras do git nos dê uma boa explicação.

Minha solução foi remover esses arquivos, e para adicionar autocrlf = falsesob [core]no .git/config.

Isso não equivale exatamente à mesma coisa que a configuração anterior, pois exige que todos os desenvolvedores tenham autocrlf = false. Eu gostaria de encontrar uma solução melhor.

EDITAR:

Comentei as linhas incriminadoras, as descomentei e funcionou. Mas que ... eu nem ...!

Norswap
fonte
1
Acabei de ter o mesmo problema exato e essa foi a única solução que funcionou. No meu caso, mudei de uma ramificação de recursos para o meu mestre e puxei algumas novas alterações do upstream e isso começou a acontecer para 2 arquivos que foram modificados. Parece que os arquivos podem ter sido alterados do Unix para os finais de linha do Windows, o que pode ter algo a ver com isso. Não tenho certeza de como ou por quê.
Steven Surowiec
+1 Mesmo problema no Windows Git. Já teve autocrlf = false. Mesclei as alterações do repo svn repo ( git svn fetch/ git merge git-svn) e fiquei com 1 arquivo marcado como modificado. O estranho é que já tive esse problema antes e tudo o que precisava fazer foi verificar outro ramo (com a -fbandeira) e depois voltar. Fiz isso e funcionou, mas quando mudei para um ramo de recursos, a "alteração" estava de volta! Sua edição na parte inferior da resposta foi a solução. No meu caso, comentei / descomentei uma linha na parte superior do meu arquivo .gitattributes:* text=auto !eol
Aaron Blenkush
1
Isso EDIT trabalhou para mim também: comente as linhas em .gitattributes, run git status, descomente as linhas .gitattributes, execute git statusnovamente
Ignitor
Isso ocorre porque o git está redefinindo esses arquivos e aplicando as terminações de linha especificadas .gitattributesnovamente. O git diffprovavelmente mostra a famosa parede da / parede de vermelho verde que é típico de diferenças de fim de linha.
Dagrooms
21

Possível causa nº 1 - Normalização de final de linha

Uma situação em que isso pode acontecer é quando o arquivo em questão foi verificado no repositório sem a configuração correta para terminações de linha (1), resultando em um arquivo no repositório com finais de linha incorretos ou finais de linha misturados. Para confirmar, verifique se git diffmostra apenas alterações nas terminações de linha (elas podem não estar visíveis por padrão, tente git diff | cat -vver os retornos de carro como ^Mcaracteres literais ).

Posteriormente, alguém provavelmente adicionou .gitattributesou modificou a core.autocrlfconfiguração para normalizar as terminações de linha (2). Com base na .gitattributesconfiguração global ou, o Git aplicou alterações locais em sua cópia de trabalho que aplicam a normalização de final de linha solicitada. Infelizmente, por algum motivo git reset --hard, não desfaz essas alterações de normalização de linha.

Solução

As soluções alternativas nas quais as terminações de linha locais são redefinidas não resolverão o problema. Toda vez que o arquivo é "visto" pelo git, ele tenta reaplicar a normalização, resultando no mesmo problema.

A melhor opção é permitir que o git aplique a normalização que deseja, normalizando todas as terminações de linha no repositório para coincidir com as .gitattributese comprometendo essas alterações - consulte Tentando corrigir as terminações de linha com git filter-branch, mas sem sorte .

Se você realmente deseja reverter as alterações no arquivo manualmente, a solução mais fácil parece apagar os arquivos modificados e pedir ao git para restaurá-los, embora observe que essa solução parece não funcionar consistentemente 100% dos arquivos. o horário ( AVISO: NÃO execute isso se os arquivos modificados tiverem alterações diferentes das terminações de linha !!):

    git status --porcelain | grep "^ M" | cut -c4- | xargs rm
    git checkout -- .

Observe que, a menos que você normalize as terminações de linha no repositório em algum momento, você continuará executando esse problema.

Causa possível # 2 - Insensibilidade ao caso

A segunda causa possível é a distinção entre maiúsculas e minúsculas no Windows ou Mac OS / X. Por exemplo, digamos que exista um caminho como o seguinte no repositório:

/foo/bar

Agora, alguém no Linux envia arquivos /foo/Bar(provavelmente devido a uma ferramenta de construção ou algo que criou esse diretório) e empurra. No Linux, agora são atualmente dois diretórios separados:

/foo/bar/fileA
/foo/Bar/fileA

A verificação desse repositório no Windows ou no Mac pode resultar em modificações fileAque não podem ser redefinidas, porque a cada redefinição, o git no Windows faz check-out /foo/bar/fileAe, como o Windows não faz distinção entre maiúsculas e minúsculas, substitui o conteúdo fileApor /foo/Bar/fileA, resultando na sua "modificação".

Outro caso pode ser um arquivo individual que existe no repositório que, quando verificado em um sistema de arquivos que não diferencia maiúsculas de minúsculas, se sobrepõe. Por exemplo:

/foo/bar/fileA
/foo/bar/filea

Pode haver outras situações semelhantes que podem causar esses problemas.

O sistema de arquivos que não faz distinção entre maiúsculas e minúsculas deve realmente detectar essa situação e mostrar uma mensagem de aviso útil, mas atualmente não aparece (isso pode mudar no futuro - veja esta discussão e os patches propostos relacionados na lista de discussão do git.git).

Solução

A solução é alinhar o caso dos arquivos no índice git e o caso no sistema de arquivos do Windows. Isso pode ser feito no Linux, que mostrará o verdadeiro estado das coisas, OU no Windows, com o utilitário de código aberto muito útil Git-Unite . O Git-Unite aplicará as alterações de caso necessárias no índice git, que poderão ser confirmadas no repositório.

(1) Isso provavelmente ocorreu por alguém usando o Windows, sem qualquer .gitattributesdefinição para o arquivo em questão, e usando a configuração global padrão para a core.autocrlfqual é false(consulte (2)).

(2) http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/

Raman
fonte
Maldito filho, levou todo o caminho até este. Eu tive que me comprometer após a primeira linha, mas finalmente consegui fazer o checkout master. Isso não foi divertido.
Tim Lieberman
16

Se outras respostas não estiverem funcionando, tente adicionar os arquivos e redefinir

$ git add -A
$ git reset --hard

No meu caso, isso ajudou quando havia um monte de arquivos vazios que o git estava rastreando.

joshuakcockrell
fonte
Isso funciona. Eu apenas usei em $ git add .vez de$ git add -A
Bjarne Gerhardt-Pedersen
8

Outra causa para isso pode ser sistemas de arquivos que não diferenciam maiúsculas de minúsculas . Se você tiver várias pastas em seu repositório no mesmo nível cujos nomes diferem apenas por caso, você será atingido por isso. Navegue no repositório de origem usando sua interface da web (por exemplo, GitHub ou VSTS) para garantir.

Para mais informações: https://stackoverflow.com/a/2016426/67824

Ohad Schneider
fonte
Para encontrar os nomes desses arquivos, executegit ls-tree -r --name-only HEAD | tr A-Z a-z | sort | uniq -d
Diomidis Spinellis
5

Você pode stashafastar suas alterações e soltar o estoque:

git stash
git stash drop
Shahbaz
fonte
1
Você também pode estar interessado nisso .
Shahbaz
5

Nenhum desses métodos funcionou para mim, a única solução era destruir o repositório inteiro e cloná-lo novamente. Isso inclui esconderijo, redefinição, adição e redefinição, configurações de clrf, distinção entre maiúsculas e minúsculas etc.

John Hunt
fonte
Atualização, acabou que meu sistema de arquivos sensível a maiúsculas e minúsculas montado não era realmente maiúsculas de minúsculas. Depois de consertar, esse problema era corrigível usando as técnicas mencionadas acima.
John Hunt
4

Execute o comando clean :

# Remove all untracked files and directories. (`-f` is `force`, `-d` is `remove directories`)

git clean -fd
mrks
fonte
3
Infelizmente, isso não resolve os problemas relacionados às terminações de linha.
21417 Christopher Stoneider
Isso é a única coisa que resolve meu problema, qualquer que seja o meu problema. Eu não tinha .gitattributesfinalizações de arquivo e linha não eram um problema, pois estou em uma caixa Linux e todos os desenvolvedores e nosso servidor são Linux.
Samuel Neff
4

Verifique o seu .gitattributes.

No meu caso, eu tenho *.js text eol=lfnele e a opção git core.autocrlffoi true.

Isso me leva à situação em que o git converte automaticamente meus finais de linha de arquivos e me impede de corrigi-lo e até git reset --hard HEADnão fez nada.

Corrijo-o com comentários *.js text eol=lfno meu .gitattributese descomentei-o depois.

Parece que é apenas mágica.

Ohar
fonte
Foi isso para mim, atualizando meu projeto apresentado *.bat text eol=crlfao meu projeto.
Leo
1

Eu encontrei um problema semelhante também envolvendo .gitattributes, mas para o meu caso, o LFS do GitHub. Embora esse não seja exatamente o cenário do OP, acho que fornece uma oportunidade para ilustrar o que o .gitattributesarquivo faz e por que ele pode levar a alterações sem estágio na forma de diferenças "fantasmas".

No meu caso, um arquivo já estava no meu repositório, como desde o início dos tempos. Em um commit recente, adicionei uma nova git-lfs trackregra usando um padrão que, em retrospectiva, era um pouco amplo demais e acabei correspondendo a esse arquivo antigo. Eu sei que não queria alterar este arquivo; Sei que não mudei o arquivo, mas agora ele estava em minhas alterações sem estágio e não havia quantidade de check-out ou redefinições rígidas nesse arquivo para corrigi-lo. Por quê?

A extensão GitHub LFS funciona principalmente através do aproveitamento dos ganchos que gitfornecem acesso através do .gitattributesarquivo. Geralmente, as entradas em .gitattributesespecificam como os arquivos correspondentes devem ser processados. No caso do OP, preocupava-se em normalizar as terminações de linha; no meu, era se o LFS deveria lidar com o armazenamento de arquivos. Em qualquer um dos casos, o arquivo que aparece gitao computar um git diffnão corresponde ao que você vê ao inspecioná-lo. Portanto, se você alterar a forma como um arquivo é processado por meio do .gitattributespadrão que o corresponde, ele será exibido como alterações sem etapas no relatório de status, mesmo se realmente não houver nenhuma alteração no arquivo.

Tudo o que foi dito, minha "resposta" à pergunta é que, se a alteração no .gitattributesarquivo é algo que você deseja fazer, você deve realmente adicionar as alterações e seguir em frente. Caso contrário, altere o .gitattributespara representar melhor o que você deseja fazer.

Referências

  1. Especificação do GitHub LFS - Ótima descrição de como eles se conectam às chamadas de função cleane smudgepara substituir seu arquivo nos gitobjetos por um arquivo de texto simples com um hash.

  2. gitattributes Documentation - Todos os detalhes sobre o que está disponível para personalizar como gitprocessa seus documentos.

merv
fonte
0

Eu tive o mesmo problema. Eu fiz, git reset --hard HEADmas ainda assim, toda vez que git statusvi, estava vendo alguns arquivos como modificados.

Minha solução foi relativamente simples. Acabei de fechar meu IDE (aqui estava o Xcode) e fechei minha linha de comando (aqui estava o terminal no meu Mac OS) e tentei novamente e funcionou.

No entanto, nunca fui capaz de descobrir o que originou o problema.

Mel
fonte
0

Acredito que exista um problema com o git para Windows, em que o git grava aleatoriamente as terminações de linha erradas no checkout e a única solução alternativa é fazer o checkout de algum outro ramo e forçar o git a ignorar as alterações. Em seguida, efetue o checkout do ramo em que você realmente deseja trabalhar.

git checkout master -f
git checkout <your branch>

Esteja ciente de que isso descartará quaisquer alterações que você tenha feito intencionalmente; portanto, faça isso apenas se você tiver esse problema imediatamente após o checkout.

Edit: Eu poderia realmente ter tido sorte na primeira vez. Acontece que fiquei um pouco novamente depois de trocar de ramificação. Aconteceu que os arquivos que o git estava relatando como modificado após a alteração das ramificações. (Aparentemente porque o git não estava aplicando consistentemente a linha CRLF que terminava nos arquivos corretamente.)

Atualizei para o git mais recente para Windows e espero que o problema tenha desaparecido.

Mrfelis
fonte
0

Problema semelhante, embora eu tenha certeza apenas na superfície. De qualquer forma, pode ajudar alguém: o que eu fiz (FWIW, no SourceTree): escondi o arquivo não confirmado e, em seguida, fiz uma reinicialização completa.

ancião ancião
fonte
0

Como outras respostas apontaram, o problema é devido à correção automática de fim de linha. Encontrei esse problema com arquivos * .svg. Eu usei o arquivo svg para ícones no meu projeto.

Para resolver esse problema, informe ao git que os arquivos svg devem ser tratados como binários, em vez de texto, adicionando a linha abaixo a .gitattributes

* .svg binário

vuamitom
fonte
0

Em uma situação semelhante. Como resultado de muitos anos de tormento, com muitos programadores que conseguiram codificar diferentes codificações dos fins de linhas (. Asp , .js, .css ... não a essência) em um arquivo. Há algum tempo, recusou os atributos .gitat. Configurações para repo esquerda autorclf = truee safecrlf = warn.

O último problema surgiu ao sincronizar a partir do arquivo morto com diferentes fins de linhas. Após copiar do arquivo morto, no status git, muitos arquivos são alterados com a nota

The line will have its original line endings in your working directory. warning: LF will be replaced by CRLF in ...

Dicas de Como normalizar finais de linhas de árvores de trabalho no Git? ajudou

git add -u

MrSwed
fonte
0

Outra possibilidade que encontrei foi que um dos pacotes no repositório terminasse com um HEAD desanexado. Se nenhuma das respostas aqui ajudar e você encontrar uma mensagem de status git como essa, você poderá ter o mesmo problema:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   path/to/package (new commits)

Indo para a path/to/packagepasta a git statusdeve produzir o seguinte resultado:

HEAD detached at 7515f05

E o seguinte comando deve corrigir o problema, onde masterdeve ser substituído pelo seu ramo local:

git checkout master

E você receberá uma mensagem de que sua filial local terá algumas quantidades de confirmações atrás da filial remota. git pulle você deveria estar fora de perigo!

Robin De Schepper
fonte
0

Por algum motivo

git add .

não funcionou , mas

$ git add -A

deu certo!

Daniel Danielecki
fonte