El estado de Git muestra los archivos modificados aunque el contenido sea el mismo.

195

Recibí un pago git de otra persona y estoy tratando de cometer los cambios no organizados en el repositorio local. Sin embargo, un archivo de lote (si no todos) aparece como modificado a pesar de que el contenido es exactamente el mismo.

Ya lo configuré core.fileModecomo falso y también core.autocrlfcomo falso, sin éxito.

Vale la pena mencionar que el repositorio de Git que recibí fue de alguien que usa Windows, mientras yo uso Linux.

¿Qué puedo hacer para confirmar los cambios reales ?

EDITAR: salida 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/*

Actualización: se agregaron algunos archivos de ejemplo al azar. Estos archivos son solo texto sin formato, por lo que son los más fáciles de incluir.

Los archivos originales se encuentran aquí: https://gist.github.com/c3c5302430935155ef3d . Los hexdumps definitivamente indican que los archivos son diferentes, pero no tengo idea de qué causa esto y cómo solucionarlo.

Versión 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..

Versión 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
fuente
1
Si ha core.filemodedesarmado o configurado true, ¿la salida es diferente?
Mark Longair
La otra parte importante de la información que sea útil es la salida degit --version
Marcos Longair
2
@AronRotteveel: Eso es fácil: el primer archivo tiene extremos de línea CRLF (windows), el segundo LF (Unix)
sehe
3
Se presenta git 2.8 (marzo de 2016) git ls-files --eol, para ver rápidamente si hay eol involucrado. Vea mi respuesta a continuación
VonC
La persona en Windows puede ejecutar git config --global core.autocrlf true para resolver este problema.
Inyoka

Respuestas:

62

Actualización: según el comentario sobre esta pregunta, el problema se ha resuelto:

Eso es fácil: el primer archivo tiene extremos de línea CRLF (windows), el segundo LF (Unix). La fileutilidad (disponible en git \ usr \ bin) le mostrará que ( file a bresponderá algo así como a: ASCII text, with CRLF line terminators b: ASCII text)

Respuesta original a continuación:


La diferencia que muestra no muestra una sola línea diferente. ¿Puedes publicar .git / config (o mejor git config -l).

Es posible que tenga algunos espacios en blanco ignorados activados

Deberías intentar deshabilitarlo core.whitespace=fix,-indent-with-non-tab,trailing-space,cr-at-eol;

además

git show HEAD:myfile|md5sum
md5sum myfile

podría usarse para verificar que los archivos son de hecho diferentes. El uso de diff externo también podría 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
sehe
fuente
Lo extraño es que los md5sums para ambos archivos son diferentes, pero no puedo encontrar NINGUNA diferencia de espacios en blanco. (Asumo que este es el caso, pero simplemente no lo veo). Cualquier ayuda sera bienvenida.
Aron Rotteveel
Simplemente cargue un ejemplo en alguna parte (gist.github.com sería apropiado para esto). Supongo que es con nueva línea en la última línea, una marca de orden de bytes o codificaciones UTF8 no canónicas en general. Siempre puedes mirar xxdo bdiffhacer diferencias binarias también
sehe
gracias por el consejo. xddFue nuevo para mí. Gran herramienta! Actualicé mi publicación con un ejemplo.
Aron Rotteveel
1
@AronRotteveel: Eso es fácil: el primer archivo tiene extremos de línea CRLF (ventanas), el segundo LF (Unix). Editar La fileutilidad le mostrará eso ( file a bresponderá algo como a: ASCII text, with CRLF line terminators b: ASCII text)
sehe
¿No deberían esos realmente mostrar como ^ M en VIM? (No lo veo) Obviamente, te creo, pero estoy realmente interesado en cómo notaste esto :)
Aron Rotteveel
135

He resuelto este problema usando los siguientes pasos

1) Eliminar todos los archivos del índice de Git.

git rm --cached -r .

2) Reescribe el índice Git para recoger todas las nuevas terminaciones de línea.

git reset --hard

Tenga en cuenta que el paso 2 puede eliminar sus cambios locales. La solución fue parte de los pasos descritos en el sitio git https://help.github.com/articles/dealing-with-line-endings/

Jacek Szybisz
fuente
En mi caso, había hecho un montón de notas en algunos archivos, luego copié el repositorio sin la carpeta .git en una computadora nueva. Cuando me di cuenta de que me faltaba mi paquete .git, ya era demasiado tarde para volver y recuperarlo. Así que: 1. Revisé una nueva copia de todo el repositorio 2. Reemplacé los archivos de vainilla con los archivos con mis cambios 3. Ejecuté el primer paso en la publicación del OP: git rm --cached -r .4. Esto organizó mis cambios (y cualquier otro archivo que se reemplazó ) así que los desestimé. En este punto, mi repositorio había vuelto a la normalidad.
cody
2
Brillante. Gracias por esto.
rupi 01 de
66
Debe tener cuidado ya que perderá cualquier otro cambio si lo hace.
Mohy Eldeen
Tuve este problema después de copiar y pegar mi carpeta de repositorio de Windows a Ubuntu. No hubo cambios locales, pero por alguna razón, git pensó que cada archivo ha cambiado. Esta solución resolvió este problema.
Linek
88

¿Has cambiado el modo de los archivos? Lo hice en mi máquina y la máquina de desarrollo local tenía 777 dados a todos los archivos, mientras que el repositorio tenía 755 que mostraban cada archivo modificado. Lo hice git diffy mostró que el modo antiguo y el nuevo son diferentes. Si ese es el problema, entonces puedes ignorarlos fácilmente por git config core.filemode false
Cheers

itsandy
fuente
2
Usando Windows 10 lxss (es decir, Ubuntu Bash) con un repositorio en el sistema de archivos de Windows con git en Linux, pensé que era un problema de final de línea. Ni siquiera había considerado que podría haber sido la forma en que los modos de archivo también son diferentes.
Matt L
Esto funcionó para mí cuando cambié mi O / S local de Ubuntu a Windows. Saludos
Mark Bucknell
@MattL y casi siempre desarrollo en Win 10 con Git Bash, pero hoy estoy en Mac y veo que git piensa que los .gitignorearchivos han cambiado cuando no lo han hecho. En esta Mac, git config core.filemoderesponde con true. Lo cambié a false, pero eso no ayudó.
Ryan
43

Yo tuve el mismo problema. después de win-> lin copy tengo todos los archivos modificados.
Solía fromdos para arreglar las terminaciones de línea
y luego

git add -uv 

para agregar cambios.
agregó 3 archivos (no todos), que en realidad modifiqué. y después de eso, el estado de git muestra solo 3 archivos modificados. después de git commit, todo está bien con el estado de git

Población
fuente
2
Gracias, esto era lo que necesitaba. Utilicé la sugerencia de @ sehe de comparar md5sum para verificar que los archivos fueran idénticos (en mi caso lo fueron). Después de eso, el uso de la bandera -u filtró correctamente esos archivos sin diferencias reales de aquellos con cambios.
STW
Gracias, fue útil. Tuve este problema después de hacerlo npm ien la raíz de mi proyecto. De alguna manera, muchos archivos obtenían un final de línea diferente, lo que estaba creando este problema.
Servidor Khalilov
esto es lo que esperaba ... los cambios que se han realizado sigue y resto del pueblo se deshacer
Deepak
25

En mi caso, los archivos aparecieron modificados después de cambiar los permisos de los archivos .

Para hacer que git ignore los cambios de permisos, haga lo siguiente:

# For the current repository
git config core.filemode false   

# Globally
git config --global core.filemode false
Sakis
fuente
1
Tu respuesta me ahorró mucho tiempo. ¡Gracias!
Pavel_K
Después de hacer esto, recomiendo guardar / organizar los cambios deseados , restablecer / verificar los archivos a los que se les han cambiado los permisos y luego volver a habilitarlos core.filemode. :)
XtraSimplicity
Tuve este problema después de copiar los archivos de una computadora portátil a otra. Su fijo lo guardó. ¡Gracias!
Sam
23

Sin embargo, muchos archivos (si no todos) aparecen como modificados, aunque el contenido sea exactamente el mismo.

Con git 2.8 (marzo de 2016), podrá verificar rápidamente si esos cambios están relacionados con eol.

Ver commit a7630bd (16 de enero de 2016) por Torsten Bögershausen ( tboegi) .
(Fusionada por Junio ​​C Hamano - gitster- en commit 05f1539 , 03 feb 2016)

ls-files: agregar diagnósticos eol

Cuando se trabaja en un entorno multiplataforma, un usuario puede querer verificar si los archivos de texto están almacenados normalizados en el repositorio y si .gitattributesestán configurados adecuadamente.

Haga posible que Git muestre las terminaciones de línea en el índice y en el árbol de trabajo y los atributos efectivos de texto / eol.

El final de la línea (" eolinfo") se muestra así:

"-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.

El atributo text / eol efectivo es uno de estos:

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

git ls-files --eol da una salida 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 qué convención de eol se usa en los datos en el índice (' i') y en el árbol de trabajo (' w'), y qué atributo está vigente para cada ruta que se muestra .

VonC
fuente
Aunque esto muestra el problema, no lo soluciona.
Greeso
7

Así es como solucioné el problema en Linux mientras clonaba un proyecto creado en Windows:

en linux para que las cosas funcionen correctamente, debe tener esta configuración: core.autocrlf = input

así es como configurarlo: git config --global core.autocrlf input

Luego clone el proyecto nuevamente desde github.

buscador de la verdad
fuente
Esto funcionó para mí en un escenario en el que estoy usando Visual Studio en Windows, pero estoy haciendo confirmaciones y comprobaciones adicionales en WSL en la línea de comandos. En la línea de comandos, todos los archivos se muestran como modificados, pero en Visual Studio, solo se modifican algunos archivos. Agregué autoclrf = input en mi archivo .gitconfig y lo arregló al instante. ¡Gracias!
Big Data Brian
5

Las preguntas frecuentes de Git tienen una respuesta que puede ser relevante, aunque nunca me he encontrado con esto antes:

¿Por qué git diff a veces enumera un archivo que no tiene cambios?

git diff y otras operaciones de git están optimizadas para que ni siquiera vea archivos cuyo estado (tamaño, tiempo de modificación, etc.) en el disco y en el índice de git son diferentes. Esto hace que git diff sea extremadamente rápido para pequeños cambios. Si el archivo ha sido tocado de alguna manera, git diff tiene que mirar el contenido y compararlo, lo cual es una operación mucho más lenta incluso cuando de hecho no hay cambio. git diff enumera los archivos como un recordatorio de que no se utiliza de manera óptima. La ejecución del estado de git no solo mostrará el estado, sino que también actualizará el índice con el estado del disco de archivos sin cambios, lo que hará que las operaciones posteriores, no solo diff, sean mucho más rápidas. Un caso típico que hace que diff enumere muchos archivos es ejecutar comandos de edición masiva como perl -pi -e '...'.

¿Qué git statusmuestra para ti?

Mark Longair
fuente
git statussimplemente muestra una enorme lista de archivos en la sección modificada.
Aron Rotteveel
@Aron: según esa pista, diría: 85% dice conversión de final de línea
sehe
44
Guau. Un recordatorio de cuán ininteligibles son algunos de los documentos oficiales de git.
Marte
2

Después de copiar mi repositorio local y la copia de trabajo en otra carpeta (en Windows, por cierto), tenía cuatro archivos que seguían apareciendo como cambiados e intenté todas las sugerencias enumeradas en las otras respuestas. Al final, lo que lo arregló para mí fue eliminar la sucursal local y descargarla nuevamente desde el control remoto. En mi caso, supongo que tuvo algo que ver con copiar un repositorio local en lugar de clonarlo.

Nate Cook
fuente
2

Entonces, probé casi todo aquí y quiero aportar una solución más que solucionó todos mis problemas. Mis problemas no fueron con finales de línea o permisos reales ni nada de eso. Fue porque había instalado Cygwin y una gran cantidad de cosas que vienen con eso, que sin saberlo también instaló su propia versión de git. Nunca me di cuenta de esto, solo que estaba teniendo problemas extraños con los usuarios y los archivos marcados como modificados (debido a los cambios de permisos).

Resulta que lo descubrí porque pensé que debería actualizar Git a la última versión, lo cual hice, pero ejecuto git --version devolvió el número de versión anterior. Después de la búsqueda subsiguiente de por qué, encontré la raíz del directorio bin de cygwin en la ruta de mi entorno, que contenía un ejecutable git, que se ejecutaba en el número de versión anterior. Imagínate.

Esto también fue difícil de encontrar porque tengo instalado TortoiseGit. Mis herramientas de línea de comando usarían la versión cygwin debido a fallas en la ruta, y TortoiseGit se configuró para usar la versión de Windows, lo que la hace aún más confusa.

Espero que esto ayude a alguien.

amigo
fuente
1
Buena atrapada. +1. Es por eso que siempre configuro mi RUTA, como en stackoverflow.com/a/44351065/6309
VonC
A menudo dejo que un instalador establezca la RUTA, pero luego la verifico manualmente, lo cual hice aquí. Mi instalación anterior tenía git 2.4.x (x86) e instalé git 2.13.x (x64). ¡Puedes imaginar mi confusión cuando eliminé la referencia de ruta x86 y aún obtuve 2.4! Fue entonces cuando vi el directorio bin de cygwin y ese parecía el siguiente lugar lógico para buscar. Por lo tanto, la configuración de FWIW o incluso la comprobación visual de su RUTA podrían no resolver esto si el directorio bin de Cygwin aparece primero
dudewad
1

La única entrada sospechosa en su configuración me parece ser core.ignorecase. Podrías intentar desarmar eso con:

  git config --unset core.ignorecase

... y ver si la salida de git statuso git diffes diferente.

Mark Longair
fuente
1

Acabo de configurar filemode = false en .git / config y funcionó para mí.

filemode = false
Felipe Santa
fuente
0

Para mí fue porque 2 máquinas virtuales de Linux estaban asignadas al mismo sistema de archivos de inicio. Una VM ejecutaba git-1.7.1 y la otra ejecutaba git-2.14

La VM que ejecuta git-1.7.1 siempre mostraría 4 archivos como modificados (incluso aunque el contenido y las terminaciones de línea fueran idénticos).

Una vez que se ejecutó 'git status' en la VM que ejecuta g-2.14, ambas VM comenzarán a informar que el repositorio está limpio. 'git status' tiene efectos secundarios. No es una operación inmutable. Y git-1.7.1 no entiende el mundo de la misma manera que git-2 +.

Guillermo
fuente