O status do Git mostra os arquivos alterados, mesmo que o conteúdo seja o mesmo

192

Recebi um check-out do git de outra pessoa e estou tentando confirmar as alterações não-estágios no repositório local. No entanto, muitos arquivos (se não todos) aparecem como modificados, mesmo que o conteúdo seja exatamente o mesmo.

Eu já defini core.fileModecomo false e também defini core.autocrlfcomo false, sem sucesso.

Vale ressaltar que o repositório Git que recebi foi de alguém usando Windows, enquanto eu uso Linux.

O que posso fazer para confirmar as alterações reais ?

EDIT: saída de git config -l:

user.name=Aron Rotteveel
user.email=<removed>
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=auto
color.ui=true
color.pager=true
color.branch.current=yellow reverse
color.branch.local=yellow
color.branch.remote=green
color.diff.meta=yellow bold
color.diff.frag=magenta bold
color.diff.old=red bold
color.diff.new=green bold
color.status.added=yellow
color.status.changed=green
color.status.untracked=cyan
core.pager=less -FRSX
core.whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol
alias.co=checkout
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
core.autocrlf=false
remote.origin.url=<removed>
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*

Atualização: adicionou alguns arquivos de exemplo aleatórios. Esses arquivos são apenas texto simples, portanto, são os mais fáceis de incluir.

Os arquivos originais estão localizados aqui: https://gist.github.com/c3c5302430935155ef3d . Hexdumps definitivamente indicam que os arquivos são diferentes, mas não tenho idéia do que causa isso e como corrigi-lo.

Versão HEAD:

0000000: 4854 4d4c 2e53 6166 654f 626a 6563 740d  HTML.SafeObject.
0000010: 0a54 5950 453a 2062 6f6f 6c0d 0a56 4552  .TYPE: bool..VER
0000020: 5349 4f4e 3a20 332e 312e 310d 0a44 4546  SION: 3.1.1..DEF
0000030: 4155 4c54 3a20 6661 6c73 650d 0a2d 2d44  AULT: false..--D
0000040: 4553 4352 4950 5449 4f4e 2d2d 0d0a 3c70  ESCRIPTION--..<p
0000050: 3e0d 0a20 2020 2057 6865 7468 6572 206f  >..    Whether o
0000060: 7220 6e6f 7420 746f 2070 6572 6d69 7420  r not to permit 
0000070: 6f62 6a65 6374 2074 6167 7320 696e 2064  object tags in d
0000080: 6f63 756d 656e 7473 2c20 7769 7468 2061  ocuments, with a
0000090: 206e 756d 6265 7220 6f66 2065 7874 7261   number of extra
00000a0: 0d0a 2020 2020 7365 6375 7269 7479 2066  ..    security f
00000b0: 6561 7475 7265 7320 6164 6465 6420 746f  eatures added to
00000c0: 2070 7265 7665 6e74 2073 6372 6970 7420   prevent script 
00000d0: 6578 6563 7574 696f 6e2e 2054 6869 7320  execution. This 
00000e0: 6973 2073 696d 696c 6172 2074 6f0d 0a20  is similar to.. 
00000f0: 2020 2077 6861 7420 7765 6273 6974 6573     what websites
0000100: 206c 696b 6520 4d79 5370 6163 6520 646f   like MySpace do
0000110: 2074 6f20 6f62 6a65 6374 2074 6167 732e   to object tags.
0000120: 2020 596f 7520 7368 6f75 6c64 2061 6c73    You should als
0000130: 6f20 656e 6162 6c65 0d0a 2020 2020 254f  o enable..    %O
0000140: 7574 7075 742e 466c 6173 6843 6f6d 7061  utput.FlashCompa
0000150: 7420 696e 206f 7264 6572 2074 6f20 6765  t in order to ge
0000160: 6e65 7261 7465 2049 6e74 6572 6e65 7420  nerate Internet 
0000170: 4578 706c 6f72 6572 0d0a 2020 2020 636f  Explorer..    co
0000180: 6d70 6174 6962 696c 6974 7920 636f 6465  mpatibility code
0000190: 2066 6f72 2079 6f75 7220 6f62 6a65 6374   for your object
00001a0: 2074 6167 732e 0d0a 3c2f 703e 0d0a 2d2d   tags...</p>..--
00001b0: 2320 7669 6d3a 2065 7420 7377 3d34 2073  # vim: et sw=4 s
00001c0: 7473 3d34 0d0a                           ts=4..

Versão copiada:

0000000: 4854 4d4c 2e53 6166 654f 626a 6563 740a  HTML.SafeObject.
0000010: 5459 5045 3a20 626f 6f6c 0a56 4552 5349  TYPE: bool.VERSI
0000020: 4f4e 3a20 332e 312e 310a 4445 4641 554c  ON: 3.1.1.DEFAUL
0000030: 543a 2066 616c 7365 0a2d 2d44 4553 4352  T: false.--DESCR
0000040: 4950 5449 4f4e 2d2d 0a3c 703e 0a20 2020  IPTION--.<p>.   
0000050: 2057 6865 7468 6572 206f 7220 6e6f 7420   Whether or not 
0000060: 746f 2070 6572 6d69 7420 6f62 6a65 6374  to permit object
0000070: 2074 6167 7320 696e 2064 6f63 756d 656e   tags in documen
0000080: 7473 2c20 7769 7468 2061 206e 756d 6265  ts, with a numbe
0000090: 7220 6f66 2065 7874 7261 0a20 2020 2073  r of extra.    s
00000a0: 6563 7572 6974 7920 6665 6174 7572 6573  ecurity features
00000b0: 2061 6464 6564 2074 6f20 7072 6576 656e   added to preven
00000c0: 7420 7363 7269 7074 2065 7865 6375 7469  t script executi
00000d0: 6f6e 2e20 5468 6973 2069 7320 7369 6d69  on. This is simi
00000e0: 6c61 7220 746f 0a20 2020 2077 6861 7420  lar to.    what 
00000f0: 7765 6273 6974 6573 206c 696b 6520 4d79  websites like My
0000100: 5370 6163 6520 646f 2074 6f20 6f62 6a65  Space do to obje
0000110: 6374 2074 6167 732e 2020 596f 7520 7368  ct tags.  You sh
0000120: 6f75 6c64 2061 6c73 6f20 656e 6162 6c65  ould also enable
0000130: 0a20 2020 2025 4f75 7470 7574 2e46 6c61  .    %Output.Fla
0000140: 7368 436f 6d70 6174 2069 6e20 6f72 6465  shCompat in orde
0000150: 7220 746f 2067 656e 6572 6174 6520 496e  r to generate In
0000160: 7465 726e 6574 2045 7870 6c6f 7265 720a  ternet Explorer.
0000170: 2020 2020 636f 6d70 6174 6962 696c 6974      compatibilit
0000180: 7920 636f 6465 2066 6f72 2079 6f75 7220  y code for your 
0000190: 6f62 6a65 6374 2074 6167 732e 0a3c 2f70  object tags..</p
00001a0: 3e0a 2d2d 2320 7669 6d3a 2065 7420 7377  >.--# vim: et sw
00001b0: 3d34 2073 7473 3d34 0a                   =4 sts=4.
Aron Rotteveel
fonte
1
Se você core.filemodedesativou ou definiu como true, a saída é diferente?
precisa saber é o seguinte
A outra informação importante que poderia ajudar é a saídagit --version
Mark Longair
2
@AronRotteveel: Isso é fácil: o primeiro arquivo possui extremidades de linha CRLF (Windows), o segundo LF (Unix)
sehe
3
O git 2.8 (março de 2016) apresenta git ls-files --eol, para ver rapidamente se o eol está envolvido. Veja minha resposta abaixo
VonC
A pessoa no Windows pode executar o git config --global core.autocrlf true para resolver esse problema.
Inyoka 21/03/19

Respostas:

62

Atualização: de acordo com o comentário sobre esta pergunta, o problema foi resolvido:

Isso é fácil: o primeiro arquivo possui extremidades de linha CRLF (Windows), o segundo LF (Unix). O fileutilitário (disponível em git \ usr \ bin) mostrará isso ( file a bresponderá algo como a: ASCII text, with CRLF line terminators b: ASCII text)

Resposta original abaixo:


O diff que você mostra não mostra uma única linha diferente. Você pode postar .git / config (ou melhor git config -l).

Você pode ter alguns espaços em branco ignorados ativados

Você deve tentar desativar core.whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol;

Além disso

git show HEAD:myfile|md5sum
md5sum myfile

pode ser usado para verificar se os arquivos são de fato diferentes. Usar diff externo também pode funcionar

git show HEAD:myfile > /tmp/myfile.HEAD

diff -u myfile /tmp/myfile.HEAD

# or if you prefer an interactive tool like e.g.:
vim -d myfile /tmp/myfile.HEAD
ver
fonte
O estranho é que o md5sums para os dois arquivos é diferente, mas não consigo encontrar QUALQUER diferença de espaço em branco. (Presumo que seja esse o caso, mas eu simplesmente não o vejo). Qualquer ajuda é bem vinda.
Aron Rotteveel
Basta enviar um exemplo em algum lugar (gist.github.com seria apropriado para isso). Suponho que seja com nova linha na última linha, uma codificação de ordem de bytes ou codificações UTF8 não canônicas em geral. Você sempre pode ver xxdou bdifffazer diffs binários também #
Veja se
Obrigado pela dica. xddera novo para mim. Ótima ferramenta! Eu atualizei minha postagem com um exemplo.
Aron Rotteveel
1
@AronRotteveel: Isso é fácil: o primeiro arquivo possui extremidades de linha CRLF (Windows), o segundo LF (Unix). Editar O fileutilitário mostrará que ( file a bresponderá algo como a: ASCII text, with CRLF line terminators b: ASCII text)
veja
aqueles que realmente não devem aparecer como ^ M no VIM? (Eu não vejo isso). Obviamente, acredito em você, mas estou realmente interessado em como você percebeu isso :)
Aron Rotteveel
134

Resolvi esse problema usando os seguintes stpes

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

Observe que a etapa 2 pode remover as alterações locais. A solução fez parte das etapas descritas no site git https://help.github.com/articles/dealing-with-line-endings/

Jacek Szybisz
fonte
No meu caso, fiz algumas anotações em alguns arquivos e copiei o repositório sem a pasta .git para um novo computador. Quando percebi que estava perdendo meu pacote .git, era tarde demais para voltar e recuperá-lo. Então eu: 1. Verifiquei uma nova cópia de todo o repositório 2. Substituí os arquivos vanilla pelos arquivos pelas minhas alterações 3. Executei o primeiro passo no post do OP: git rm --cached -r .4. Isso preparou minhas alterações (e quaisquer outros arquivos que foram substituídos) ), então eu os desfiz. Nesse ponto, meu repo estava de volta ao normal.
Cody
2
Brilhante. Obrigado por isso.
rupi
6
Tem que ter cuidado, pois você perderá outras alterações se o fizer.
Mohy Eldeen
Eu tive esse problema depois de copiar e colar minha pasta repo do Windows para o Ubuntu. Não houve alterações locais, mas, por alguma razão, o git pensou que todos os arquivos foram alterados. Esta solução resolveu esse problema.
Linek 6/12/19
86

Você mudou o modo dos arquivos? Fiz isso na minha máquina e a máquina local de desenvolvimento tinha 777 dados a todos os arquivos, enquanto o repositório tinha 755, que mostrava todos os arquivos modificados. Eu fiz git diffe mostrou o modo antigo e o novo modo são diferentes. Se esse é o problema, você pode ignorá-los facilmente pelo git config core.filemode false
Cheers

itsandy
fonte
2
Usando o Windows 10 lxss (ou seja, Ubuntu Bash) com um repositório no sistema de arquivos do Windows com git no Linux, pensei que fosse um problema de final de linha. Nem sequer considerara que poderia ter sido assim que os modos de arquivo também são diferentes.
Matt L
Isso funcionou para mim quando alterei meu sistema operacional local do Ubuntu para o Windows. Cheers
Mark Bucknell
O @MattL e itsandy geralmente desenvolvo no Win 10 com o Git Bash, mas hoje estou no Mac e vejo que o git acha que os .gitignorearquivos foram alterados quando não o foram. Neste Mac, git config core.filemoderesponde com true. Eu mudei para false, mas isso não ajudou.
Ryan
43

Eu tive o mesmo problema. após a cópia win-> lin, todos os arquivos foram modificados.
usei fromdos para corrigir terminações de linha
e depois

git add -uv 

para adicionar alterações.
adicionou 3 arquivos (nem todos), que eu realmente modifiquei. e depois disso, o status do git mostra apenas 3 arquivos modificados. após o git commit, tudo está ok com o status git

Demo_S
fonte
2
Obrigado, era disso que eu precisava. Usei a sugestão do @ sehe de comparar o md5sum para verificar se os arquivos eram idênticos (no meu caso, eram). Depois disso, o uso do sinalizador -u filtrou corretamente esses arquivos sem diferenças reais daqueles com alterações.
STW
Obrigado, foi útil. Eu tive esse problema depois de fazer npm ina raiz do meu projeto. De alguma forma, muitos arquivos estavam obtendo diferentes terminações de linha, o que estava criando esse problema.
Servidor Khalilov
este é o que eu esperava ... as mudanças que fizeram restos e descansar tenho de desfazer
Deepak
28

Consegui corrigir os problemas na máquina Windows alterando core.autocrlf de false para core.autocrlf = input

git config core.autocrlf input

conforme sugerido em https://stackoverflow.com/a/1112313/52277

Michael Freidgeim
fonte
24

No meu caso, os arquivos foram exibidos como modificados depois de alterar as permissões dos arquivos .

Para fazer o git ignorar as alterações de permissão, faça o seguinte:

# For the current repository
git config core.filemode false   

# Globally
git config --global core.filemode false
Sakis
fonte
1
Sua resposta me salvou muito tempo. Obrigado!
Pavel_K 23/02/19
Depois de fazer isso, recomendo que oculte / organize as alterações desejadas , redefinindo / verificando os arquivos que tiveram suas permissões alteradas e, em seguida, reativando core.filemode. :)
XtraSimplicity
Eu tive esse problema depois de copiar os arquivos de um laptop para outro. Seu conserto salvou. Obrigado!
19419 Sam
23

No entanto, muitos arquivos (se não todos) aparecem como modificados, mesmo que o conteúdo seja exatamente o mesmo.

Com o git 2.8 (março de 2016), você poderá verificar rapidamente se essas alterações estão relacionadas ao eol.

Veja commit a7630bd (16 de janeiro de 2016) por Torsten Bögershausen ( tboegi) .
(Mesclado por Junio ​​C Hamano - gitster- na confirmação 05f1539 , 03 de fevereiro de 2016)

ls-files: adicionar diagnósticos eol

Ao trabalhar em um ambiente de plataforma cruzada, um usuário pode querer verificar se os arquivos de texto são armazenados normalizados no repositório e se .gitattributes estão configurados adequadamente.

Torne possível permitir que o Git mostre as terminações de linha no índice e na árvore de trabalho e os atributos efetivos de texto / eol.

O final da linha (" eolinfo") é mostrado assim:

"-text"        binary (or with bare CR) file
"none"         text file without any EOL
"lf"           text file with LF
"crlf"         text file with CRLF
"mixed"        text file with mixed line endings.

O atributo texto / eol efetivo é um destes:

"", "-text", "text", "text=auto", "text eol=lf", "text eol=crlf"

git ls-files --eol fornece uma saída como esta:

i/none   w/none   attr/text=auto      t/t5100/empty
i/-text  w/-text  attr/-text          t/test-binary-2.png
i/lf     w/lf     attr/text eol=lf    t/t5100/rfc2047-info-0007
i/lf     w/crlf   attr/text eol=crlf  doit.bat
i/mixed  w/mixed  attr/               locale/XX.po

para mostrar qual convenção eol é usada nos dados no índice (' i') e na árvore de trabalho (' w') e qual atributo está em vigor para cada caminho que é mostrado .

VonC
fonte
Embora isso mostre o problema, ele não o corrige.
Greeso 11/02
7

Aqui está como eu corrigi o problema no Linux enquanto clonava um projeto que foi criado no Windows:

no linux para que as coisas funcionem corretamente, você precisa ter esta configuração: core.autocrlf = input

isto é como configurá-lo: git config --global core.autocrlf input

Em seguida, clone o projeto novamente no github.

buscador da verdade
fonte
Isso funcionou para mim em um cenário em que estou usando o Visual Studio no Windows, mas estou fazendo confirmações e verificações adicionais no WSL na linha de comando. Na linha de comando, todos os arquivos foram mostrados como alterados, mas no Visual Studio, apenas alguns arquivos foram alterados. Adicionei autoclrf = input no meu arquivo .gitconfig e ele foi corrigido instantaneamente. Obrigado!
Big Data Brian
5

O FAQ do Git tem uma resposta que pode ser relevante, embora eu nunca tenha encontrado isso antes:

Por que o git diff às vezes lista um arquivo que não possui alterações?

O git diff e outras operações git são otimizadas para que nem olhem para arquivos cujo status (tamanho, hora da modificação etc) no disco e no índice do git são diferentes. Isso torna o git diff extremamente rápido para pequenas alterações. Se o arquivo foi tocado de alguma forma, o git diff precisa examinar o conteúdo e compará-lo, o que é uma operação muito mais lenta, mesmo quando na verdade não há alterações. O git diff lista os arquivos como um lembrete de que não é usado da melhor maneira. A execução do status git não apenas mostrará o status, mas também atualizará o índice com o status de disco de arquivos inalterados, tornando as operações subseqüentes, não apenas diff, muito mais rápidas. Um caso típico que faz com que muitos arquivos sejam listados pelo diff está executando comandos de edição em massa como perl -pi -e '...'.

O que git statusmostra para você?

Mark Longair
fonte
git statussimplesmente mostra uma lista enorme de arquivos na seção modificada.
Aron Rotteveel
@Aron: com base nessa pista, eu diria: 85% afirmam conversão de linha de linha
veja
4
Uau. Um lembrete de quão ininteligíveis são alguns dos documentos oficiais do git.
Mars
2

Depois de copiar meu repositório local e a cópia de trabalho para outra pasta (a propósito, no Windows), eu tinha quatro arquivos que apareciam como alterados e tentava todas as sugestões listadas nas outras respostas. No final, o que o corrigiu foi excluir o ramo local e baixá-lo novamente do controle remoto. No meu caso, acho que tinha algo a ver com copiar um repositório local em vez de clonar.

Nate Cook
fonte
2

Então, tentei praticamente tudo aqui e quero contribuir com mais uma solução que resolva todos os meus problemas. Meus problemas não eram com finais de linha ou permissões reais ou algo assim. Foi porque eu tinha instalado o Cygwin e toda uma série de coisas que vêm com isso, que, sem o meu conhecimento, também instalaram sua própria versão do git. Eu nunca percebi isso, só que estava tendo problemas estranhos com usuários e arquivos sendo marcados como alterados (devido a alterações de permissões).

Acontece que eu descobri isso porque pensei em atualizar o Git para a versão mais recente, o que fiz, mas executando git --version retornou o número da versão antiga. Após a busca que se seguiu, encontrei a raiz do diretório cygwin bin no caminho do meu ambiente, que continha um executável git, rodando no número da versão antiga. Vai saber.

Isso também foi difícil de encontrar, porque eu tenho o TortoiseGit instalado. Minhas ferramentas de linha de comando usariam a versão cygwin devido a desvios de caminho, e o TortoiseGit foi configurado para usar a versão do Windows, tornando-a ainda mais confusa.

Espero que isso ajude alguém.

cara
fonte
1
Boa pegada. +1. É por isso que eu sempre defino meu PATH, como em stackoverflow.com/a/44351065/6309
VonC
Frequentemente, deixo um instalador definir o PATH, mas depois verifico manualmente, o que fiz aqui. Minha instalação anterior tinha o git 2.4.x (x86) e eu instalei o git 2.13.x (x64). Você pode imaginar minha confusão quando removi a referência de caminho x86 e ainda tenho 2,4 !! Foi quando vi o diretório bin do cygwin e esse parecia o próximo lugar lógico para procurar. Portanto, a configuração do FWIW ou mesmo a verificação visual do seu PATH podem não resolver isso se o diretório bin do Cygwin estiver listado primeiro!
Dudewad 06/06
1

A única entrada suspeita na sua configuração me parece ser core.ignorecase. Você pode tentar desabilitar isso com:

  git config --unset core.ignorecase

... e veja se a saída de git statusou git diffé diferente.

Mark Longair
fonte
1

Acabei de definir filemode = false em .git / config e funcionou para mim.

filemode = false
Felipe Santa
fonte
0

Para mim, foi porque duas VMs linux foram mapeadas para o mesmo sistema de arquivos domésticos. Uma VM estava executando o git-1.7.1 e a outra estava executando o git-2.14

A VM executando o git-1.7.1 sempre mostrava 4 arquivos alterados (mesmo que o conteúdo e as terminações de linha fossem idênticos).

Depois que o 'status git' fosse executado na VM executando g-2.14, as duas VMs começariam a relatar o repositório como limpo. 'status git' tem efeitos colaterais. Não é uma operação imutável. E o git-1.7.1 não entende o mundo da mesma maneira que o git-2 +.

William
fonte