'git status' muestra archivos modificados, pero 'git diff' no

181

He echado un vistazo a todas las preguntas similares. Sin embargo, lo he verificado dos veces y definitivamente algo extraño está sucediendo.

En un servidor (Solaris con Git 1.8.1) cloné el repositorio de Git y luego copié la carpeta .git en mis archivos vivos existentes. Esto funcionó perfectamente, podría correr

git status

luego

git diff [filename]

para verificar cualquier archivo que fuera diferente.

Sin embargo, en otro servidor (Solaris con Git 1.7.6) estoy haciendo exactamente lo mismo

git diff [filename]

no muestra nada, incluso si el contenido del archivo es definitivamente diferente. También probé agregar un nuevo archivo, confirmarlo y luego editarlo. El mismo problema git statusmuestra el archivo modificado, pero git diffno muestra nada. Si descargo el archivo modificado y ejecuto un diff localmente, obtengo un resultado de diff.

Oliver P
fuente
9
¿Está en tu índice? Si es así, puede ver la diferencia con git diff --cached.
jeremyharris
2
git diff --cachedsolo me da una salida en blanco también.
Oliver P
git logTampoco da salida.
Oliver P
Suponiendo que realmente hay un error, debería poder crear un ejemplo mínimo. Intenta reproducirlo y comparte la muestra.
mheinzerling
1) ¿Se cambió el modo de archivo? Busque la core.fileModeopción aquí 2) Además, estoy enfrentando un problema similar con la configuración de Console2 (lo tengo en git) cuando Console2 se está ejecutando realmente. Tal vez una especie de bloqueo de archivo hace que el archivo haya cambiado.
loco

Respuestas:

63

Hay algunas razones por las cuales git statuspodría mostrar una diferencia, pero git diffpodría no serlo.

  • El modo (bits de permiso) del archivo cambió, por ejemplo, de 777 a 700.

  • El estilo de avance de línea cambió de CRLF (DOS) a LF (UNIX)

La forma más fácil de averiguar qué sucedió es ejecutar git format-patch HEAD^y ver qué dice el parche generado.

cmccabe
fuente
11
si se aplican los archivos de permiso de cambios: git config core.filemode false para ignorar el permiso de archivos
jruzafa
¿Cómo descubrió que el cambio de avance de línea de CRLF a LF es una de las situaciones en las que el estado de git mostrará una diferencia y git diff no?
Alex Spurling
Tener compañeros de trabajo que usan Windows lo ayudará a descubrir todo tipo de cosas divertidas sobre los finales de línea. Sin embargo, creo que podría haber casos en los que "git diff" muestre el cambio de CRLF a LF: probablemente depende de su configuración. No he trabajado con Windows en mucho tiempo, así que no sé cómo son los valores predeterminados ahora.
cmccabe
59

Para mí, tenía algo que ver con los permisos de archivo. Alguien con Mac / Linux en mi proyecto parece confirmar algunos archivos con permisos no predeterminados que mi cliente git de Windows no pudo reproducir. La solución para mí fue decirle a git que ignore los permisos de archivo:

git config core.fileMode false

Otra información: ¿Cómo hago que Git ignore los cambios en el modo de archivo (chmod)?

Alex Abdugafarov
fuente
Esto resolvió un problema que estaba teniendo con un montón de archivos, aunque creo que fue con el archivo creado / modificado en su lugar.
Derek
Esto lo resolvió para mí. El valor de fileMode parece ser predeterminado en verdadero en los volúmenes de Mac / Linux y falso en los volúmenes de Windows. Moví un proyecto de Mac a Windows y necesitaba cambiarlo a falso.
Geekinit
1
Esto también ayudó si está ejecutando VSCode usando un contenedor Docker que monta su directorio en Windows 10. En el exterior del contenedor, al verificar el estado de git, muestra correctamente que no ha cambiado ningún archivo. Pero si verifica el estado de git dentro del contenedor, muestra que los archivos han cambiado. Ejecutar el comando anterior dentro del contenedor solucionó mi problema.
Frederick Ollinger
39

Tuve un problema en el que un programa modificó cientos de finales de línea y git diffenumeró todos los archivos de origen como modificados. Después de arreglar las terminaciones de línea, git statustodavía se enumeran los archivos como modificados.

Pude solucionar este problema agregando todos los archivos al índice y luego restableciendo el índice.

git add -A
git reset

core.filemode se estableció en falso.

Jaakko
fuente
¡Gracias! ¡Trabajado como un encanto!
Starwave
1
Resolví con git add --renormalize ., ver mi respuesta a continuación.
Stefano M
17

Sospecho que hay algo mal, ya sea con su instalación de Git o su repositorio.

Intenta correr:

GIT_TRACE=2 git <command>

Mira si obtienes algo útil. Si eso no ayuda, solo usa strace y mira qué está pasando:

strace git <command>
usuario1338062
fuente
66
@towi: Dado que esto valió una recompensa para usted, me interesaría ver lo que ha aprendido sobre el motivo de sus fallas similares.
cfi
55
En mi caso, agregué el -Findicador a la LESSvariable env que dice menos para salir si hay menos de una pantalla llena de información para mostrar. Como git usa menos como buscapersonas y tenía una pequeña diferencia, no se mostraba nada. O bien, tuve que agregar -Xal LESSentorno que muestra el contenido en la pantalla incluso después de menos salidas o simplemente eliminarlo -F. GIT_TRACEmostró que lessse estaba ejecutando, lo que me recordó que cambié la LESSvariable recientemente. La misma razón en la respuesta de @ rcwxok, pero quería un comentario sobre cómo GIT_TRACEayudó.
Raghu Dodda
Esta respuesta proporciona me toque de "pager" y me lleva a la solución del entorno core.pageren .gitconfigque funciona perfectamente para mí.
ytu
10

Tuve un problema similar: git diffmostraría diferencias, pero git diff <filename>no lo haría. Resultó que configuré LESSuna cadena que incluye -F( --quit-if-one-screen). Eliminar esa bandera resolvió el problema.

rcwxok
fuente
1
En lugar de eliminar -F, agregar -Xtambién podría funcionar, vea mi respuesta a continuación para un caso similar.
avivr
¡Gracias por esto! Me estaba volviendo loco.
Hackel
8

Como ya se señaló en una respuesta anterior , esta situación puede surgir debido a problemas de final de línea (CR / LF vs. LF). Resolví este problema (bajo Git versión 2.22.0) con este comando:

git add --renormalize .

De acuerdo con el manual:

       --renormalize
           Apply the "clean" process freshly to all tracked files to
           forcibly add them again to the index. This is useful after
           changing core.autocrlf configuration or the text attribute in
           order to correct files added with wrong CRLF/LF line endings.
           This option implies -u.
Stefano M
fuente
5

Respuesta corta

Correr a git addveces ayuda.

Ejemplo

El estado de Git muestra archivos modificados y git diff no muestra nada ...

> git status
On branch master
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:   package.json

no changes added to commit (use "git add" and/or "git commit -a")
> git diff
> 

... ejecutar git add resuelve la inconsistencia.

> git add
> git status
On branch master
nothing to commit, working directory clean
> 
Shaun Luttin
fuente
2
Esto me suena como 'combatir los síntomas' en lugar de 'curar la enfermedad' ...;)
einjohn
@einjohn ¿Cuál crees que es la enfermedad en este caso?
Shaun Luttin
1
La enfermedad podría ser varias cosas. Como lo mencionaron otros, podría ser un problema de permisos o algo con las terminaciones de línea. También podría ser cambios ya organizados. Sin embargo, esta última posibilidad no se ajusta a su ejemplo. Sin embargo, con su solución no sabrá la razón (enfermedad), simplemente eliminará el problema (de un diff vacío (síntomas) aparentemente defectuoso). Para ser claros: no digo que sea una mala solución. Podría ayudar a alguien, si él / ella solo quiere que el problema desaparezca. ... espero haber arrojado algo de luz sobre mi enfermedad-metapher. :)
Einjohn
@einjohn Parece que la mayoría de las veces se trata de finales de línea. Parece statusy difftiene formas separadas de manejarlos.
Shaun Luttin
5

Me encontré con este problema. Mi caso fue similar a la LESScuestión Publicado por rcwxok .

En mi caso, configuré la PAGERvariable de entorno en PAGER='less -RSF'.

Sin embargo, a diferencia de las respuestas anteriores, no quería eliminar la -Fopción, porque la puse explícitamente allí con la esperanza de evitar mostrar la diferencia lesssi es más corta que una pantalla completa.

Para obtener el resultado deseado, en lugar de eliminar -F, añadí -X: PAGER='less -RSFX'. Esto resolvió el git diffproblema y, además, evita mostrar diferencias cortas con less.

avivr
fuente
La capitalización parece extraña. ¿Te refieres a "menos -RSFX" en lugar de "MENOS -RSFX"? ¿Son las opciones el caso correcto?
StackzOfZtuff
1
Sí, gracias, fue un error. No estoy seguro de cómo sucedió. Ahora arreglado.
avivr
3

Acabo de correr en un problema similar. git diff filemostró nada porque añadí archivo en el índice de Git con alguna parte de su nombre en mayúsculas: GeoJSONContainer.js.

Luego, le cambié el nombre GeoJsonContainer.jsy los cambios dejaron de ser rastreados. git diff GeoJsonContainer.jsNo estaba mostrando nada. Tuve que eliminar el archivo del índice con un indicador de fuerza y ​​agregar el archivo nuevamente:

git rm -f GeoJSONContainer.js
git add GeoJSONContainer.js
Alexandr Lazarev
fuente
2

Realmente no hizo una pregunta real, pero dado que este es un caso de uso general que uso con bastante frecuencia, esto es lo que hago. Puede intentarlo usted mismo y ver si el error persiste.

Mi suposición sobre su caso de uso:

Tiene un directorio existente que contiene archivos y directorios y ahora desea convertirlo en un repositorio Git que se clone desde otro lugar sin cambiar ningún dato en su directorio actual.

Realmente hay dos formas.

Clone repo - mv .git- git reset --hard

Este método es lo que hizo: clonar el repositorio existente en un directorio vacío y luego mover el .gitdirectorio al directorio de destino. Para trabajar sin problemas, esto generalmente requiere que ejecute

git reset --hard

Sin embargo, eso cambiaría el estado de los archivos en su directorio actual. Puede probar esto en una copia completa / rsync de su directorio y estudiar qué cambios. Al menos después ya no debería ver discrepancias entre git logy status.

Init nuevo repositorio - punto de origen

El segundo es menos perturbador: cden su destino, y comience un nuevo repositorio con

git init

Luego le dices a ese nuevo repositorio, que tiene un antepasado en otro lugar:

git remote add origin original_git_repo_path

Entonces con seguridad

git fetch origin master

copiar sobre los datos sin cambiar sus archivos locales. Todo debería estar bien ahora.

Siempre recomiendo la segunda forma por ser menos propenso a errores.

cfi
fuente
Parece implicar que se trata de un error git . Ok, podría ser Todavía asumí que me faltaba la comprensión adecuada de git, porque no soy tan inteligente como Linus ;-)
towi
@towi: No, no estoy implicando que esto sea un error git, ni estoy implicando lo contrario. No estoy familiarizado con los git internos. Pero como regla general, al mover las .gitcarpetas a otras áreas de trabajo, potencialmente estamos violando los supuestos de git. Si esto resulta en un comportamiento errático, no podemos culpar a git, tenemos que culparnos a nosotros mismos por jugar trucos con git. git proporciona medios para arreglar eso, por ejemplo, el reset --hard. Es solo que eso no es lo que queremos. Esta es exactamente la razón por la cual init/remote addse recomienda el camino, y todo está bien.
cfi
@towi y Oliver P: si bien entiendo que desea que se resuelva su caso particular de error, a veces solo se recomienda seguir las recomendaciones generales, especialmente si se ajustan perfectamente a su caso de uso. Tampoco hay pérdida de datos. Y la remote addforma de hacer las cosas todavía se puede aplicar a una situación desordenada como la descrita por Oliver P
cfi
1
Un voto negativo sin un comentario no ayuda a mejorar esta respuesta, ni el sitio en su conjunto. Quien haga un voto negativo, deje un comentario para que se pueda resolver el problema.
cfi
1

Me topé con este problema nuevamente. Pero esta vez ocurrió por una razón diferente. Había copiado archivos en el repositorio para sobrescribir las versiones anteriores. Ahora puedo ver que los archivos se modifican pero diff no devuelve los diffs.

Por ejemplo, tengo un archivo mainpage.xaml. En File Explorer, pegué un nuevo archivo mainpage.xaml sobre el de mi repositorio actual. Hice el trabajo en otra máquina y acabo de pegar el archivo aquí.
git muestra modificado

El archivo se muestra modificado, pero cuando ejecuto git diff, no mostrará los cambios. Probablemente sea porque la información de archivo en el archivo ha cambiado y git sabe que no es realmente el mismo archivo. Interesante.

git diff no muestra nada

Puede ver que cuando ejecuto diff en el archivo no muestra nada, solo devuelve el mensaje.

raddevus
fuente
1

Tuve este mismo problema descrito de la siguiente manera: si escribí

$ git diff

Git simplemente regresó a la solicitud sin error.

Si escribiera

$ git diff <filename>

Git simplemente regresó a la solicitud sin error.

Finalmente, al leer, noté que en git diffrealidad llama mingw64\bin\diff.exeal hacer el trabajo.

Aquí está el trato. Estoy ejecutando Windows, instalé otra utilidad Bash y cambió mi ruta para que ya no apunte a mi directorio mingw64 \ bin .

Entonces, si escribe:

git diff

y solo vuelve a la indicación de que puede tener este problema.

El diff.exe real que ejecuta gitse encuentra en su directorio mingw64 \ bin

Finalmente, para solucionar esto, copié mi mingw64\bindirectorio en la ubicación en la que Git lo estaba buscando. Lo probé y todavía no funcionaba.

Luego, cerré mi ventana de Git Bash y la abrí nuevamente, fui a mi mismo repositorio que estaba fallando y ahora funciona.

raddevus
fuente