'git status' zeigt geänderte Dateien an, 'git diff' jedoch nicht


181

Ich habe mir alle ähnlichen Fragen angesehen. Ich habe es jedoch noch einmal überprüft und es passiert definitiv etwas Seltsames.

Auf einem Server (Solaris mit Git 1.8.1) habe ich das Git-Repository geklont und dann den Ordner .git in meine vorhandenen Live-Dateien kopiert. Das hat perfekt funktioniert, ich konnte rennen

git status

dann

git diff [filename]

um alle Dateien zu überprüfen, die anders waren.

Auf einem anderen Server (Solaris mit Git 1.7.6) mache ich jedoch genau das Gleiche

git diff [filename]

zeigt nichts, auch wenn der Inhalt der Datei definitiv anders ist. Ich habe auch getestet, wie ich eine neue Datei hinzufüge, festschreibe und dann bearbeite. Das gleiche Problem git statuszeigt die Datei als geändert, git diffzeigt aber nichts. Wenn ich die geänderte Datei herunterlade und ein Diff lokal ausführe, erhalte ich eine Diff-Ausgabe.


9
Ist es in Ihrem Index? In diesem Fall können Sie den Diff mit anzeigen git diff --cached.
Jeremyharris

2
git diff --cachedgibt mir auch nur eine leere Ausgabe.
Oliver P

git loggibt auch keine Ausgabe.
Oliver P

Angenommen, es liegt wirklich ein Fehler vor, sollten Sie in der Lage sein, ein minimales Beispiel zu erstellen. Versuchen Sie es zu reproduzieren und teilen Sie die Probe.
mheinzerling

1) Dateimodus wurde geändert? Suchen Sie nach core.fileModeMöglichkeit hier 2) Auch ich bin vor ähnliches Problem mit Console2 config (ich habe es unter git) , wenn Console2 tatsächlich ausgeführt wird . Vielleicht macht eine Art Dateisperre Git zu dem, was die Datei geändert hat.
Madhead

Antworten:



63

Es gibt einige Gründe, warum git statussich ein Unterschied zeigt, aber git diffnicht.

  • Der Modus (Berechtigungsbits) der Datei wurde geändert - beispielsweise von 777 auf 700.

  • Der Zeilenvorschubstil wurde von CRLF (DOS) in LF (UNIX) geändert.

Der einfachste Weg, um herauszufinden, was passiert ist, besteht darin, auszuführen git format-patch HEAD^und zu sehen, was der generierte Patch sagt.


11
Wenn Änderungen gelten, gelten Berechtigungsdateien: git config core.filemode false zum Ignorieren der Berechtigung von Dateien
jruzafa

Wie haben Sie herausgefunden, dass der Wechsel des Zeilenvorschubs von CRLF zu LF eine der Situationen ist, in denen der Git-Status einen Unterschied zeigt und der Git-Diff nicht?
Alex Spurling

Wenn Sie Mitarbeiter haben, die Windows verwenden, können Sie alle möglichen lustigen Dinge über Zeilenenden herausfinden. Ich denke, es könnte Fälle geben, in denen "git diff" den Wechsel von CRLF zu LF zeigt - dies hängt wahrscheinlich von Ihrer Konfiguration ab. Ich habe eine Weile nicht mehr mit Windows gearbeitet, daher weiß ich nicht, wie die Standardeinstellungen jetzt sind.
cmccabe

59

Für mich hatte das etwas mit Dateiberechtigungen zu tun. Jemand mit Mac / Linux in meinem Projekt scheint einige Dateien mit nicht standardmäßigen Berechtigungen festzuschreiben, die mein Windows-Git-Client nicht reproduzieren konnte. Die Lösung für mich bestand darin, git anzuweisen, Dateiberechtigungen zu ignorieren:

git config core.fileMode false

Andere Einsicht: Wie kann ich Git dazu bringen, Änderungen im Dateimodus (chmod) zu ignorieren?


Dies löste ein Problem, das ich mit einer Reihe von Dateien hatte, obwohl ich denke, dass es stattdessen mit der Erstellungs- / Änderungszeit der Datei war.
Derek

Das hat es für mich gelöst. Der Wert für fileMode scheint auf Mac / Linux-Volumes standardmäßig true und auf Windows-Volumes false zu sein. Ich habe ein Projekt von Mac auf Windows verschoben und es musste auf false umgestellt werden.
Geekinit

1
Dies ist auch hilfreich, wenn Sie VSCode mit einem Docker-Container ausführen, der Ihr Verzeichnis unter Windows 10 bereitstellt. Wenn Sie den Git-Status außerhalb des Containers überprüfen, wird korrekt angezeigt, dass Sie keine Dateien geändert haben. Wenn Sie jedoch den Git-Status im Container überprüfen, werden die Dateien geändert. Das Ausführen des obigen Befehls im Container hat mein Problem behoben.
Frederick Ollinger

39

Ich hatte ein Problem, bei dem Hunderte von Zeilenenden von einem Programm geändert und git diffalle Quelldateien als geändert aufgelistet wurden. Nach dem Fixieren der Zeilenendengit status die Dateien weiterhin als geändert aufgelistet.

Ich konnte dieses Problem beheben, indem ich alle Dateien zum Index hinzufügte und dann den Index zurücksetzte.

git add -A
git reset

core.filemode wurde auf false gesetzt.


Danke dir! Lief wie am Schnürchen!
Starwave

1
Ich habe mit gelöst git add --renormalize ., siehe meine Antwort unten.
Stefano M

17

Ich vermute, dass entweder mit Ihrer Git-Installation oder Ihrem Repository etwas nicht stimmt.

Versuchen Sie zu laufen:

GIT_TRACE=2 git <command>

Sehen Sie, ob Sie etwas Nützliches bekommen. Wenn das nicht hilft, verwenden Sie einfach strace und sehen Sie, was falsch läuft:

strace git <command>

6
@towi: Da dies für Sie eine Prämie wert war, würde mich interessieren, was Sie über den Grund für Ihre ähnlichen Fehler erfahren haben.
cfi

5
In meinem Fall habe ich -Fder LESSenv-Variablen das Flag hinzugefügt, das weniger zum Beenden auffordert, wenn weniger als ein Bildschirm mit Informationen angezeigt werden soll. Da Git weniger als Pager verwendet und ich einen kleinen Unterschied hatte, wurde nichts gezeigt. Entweder musste ich -Xder LESSUmgebung hinzufügen , die den Inhalt auf dem Bildschirm auch nach weniger Exits anzeigt, oder einfach entfernen -F. GIT_TRACEzeigte, lessdass ausgeführt wurde, was mich daran erinnerte, dass ich die LESSVariable kürzlich geändert habe . Gleicher Grund in @ rcwxoks Antwort, wollte aber einen Kommentar GIT_TRACEdazu abgeben, wie geholfen hat.
Raghu Dodda

Diese Antwort stellt mich an „Pager“ andeuten und führt mich zu der Lösung der Einstellung core.pagerin .gitconfig, die sich perfekt für mich funktioniert.
ytu

10

Ich hatte ein ähnliches Problem: git diffwürde Unterschiede zeigen, aber git diff <filename>nicht. Es stellte sich heraus, dass ich LESSeinen String einschließlich -F( --quit-if-one-screen) gesetzt habe. Das Entfernen dieses Flags löste das Problem.


1
Anstatt zu entfernen -F, -Xkönnte das Hinzufügen auch funktionieren, siehe meine Antwort unten für einen ähnlichen Fall.
Avivr

Danke dafür! Hat mich verrückt gemacht.
Hackel

8

Wie bereits in einer früheren Antwort erwähnt , kann diese Situation aufgrund von Leitungsendproblemen (CR / LF vs. LF) auftreten. Ich habe dieses Problem (unter Git Version 2.22.0) mit diesem Befehl gelöst:

git add --renormalize .

Nach dem Handbuch:

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

5

Kurze Antwort

Laufen git add hilft manchmal.

Beispiel

Der Git-Status zeigt geänderte Dateien an und Git Diff zeigt nichts an ...

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

... Wenn Sie git add ausführen, wird die Inkonsistenz behoben.

> git add
> git status
On branch master
nothing to commit, working directory clean
> 

2
Das klingt für mich wie "die Symptome bekämpfen" anstatt "die Krankheit heilen" ...;)
einjohn

@einjohn Was denkst du ist die Krankheit in diesem Fall?
Shaun Luttin

1
Die Krankheit könnte mehrere Dinge sein. Wie von anderen erwähnt, kann es sich um ein Berechtigungsproblem oder etwas mit den Zeilenenden handeln. Es könnten auch bereits inszenierte Änderungen sein. Diese letzte Möglichkeit passt jedoch nicht zu Ihrem Beispiel. Trotzdem kennen Sie mit Ihrer Lösung den Grund (Krankheit) nicht, sondern beseitigen nur das Problem (eines scheinbar fehlerhaften leeren Diff (Symptome)). Um es klar zu sagen: Ich sage nicht, dass es eine schlechte Lösung ist. Es könnte jemandem helfen, wenn er / sie nur möchte, dass das Problem verschwindet. ... hoffentlich habe ich etwas Licht auf meinen Krankheits-Metapher geworfen. :)
Einjohn

@einjohn Es scheint die meiste Zeit Zeilenenden zu sein. Es scheint statusund diffhat getrennte Möglichkeiten, mit diesen umzugehen.
Shaun Luttin

5

Ich bin auf dieses Problem gestoßen. Mein Fall ähnelte dem LESSvon rcwxok veröffentlichten Problem .

In meinem Fall setze ich die PAGERUmgebungsvariable aufPAGER='less -RSF' .

Im Gegensatz zu den vorherigen Antworten wollte ich die -FOption jedoch nicht entfernen , da ich sie explizit dort platziert habe, um zu verhindern, dass der Unterschied angezeigt wirdless Unterschied angezeigt wird, wenn er kürzer als ein Bildschirm ist.

Um das gewünschte Ergebnis zu erzielen -F, habe ich Folgendes hinzugefügt , anstatt es zu entfernen -X: PAGER='less -RSFX'. Dies hat sowohl das git diffProblem gelöst als auch verhindert, dass kurze Unterschiede mit angezeigt werden less.


Die Großschreibung scheint seltsam. Meinen Sie "weniger -RSFX" anstelle von "WENIGER -RSFX"? Sind die Optionen der richtige Fall?
StackzOfZtuff

1
Ja, danke, es war ein Fehler. Ich bin mir nicht sicher, wie es passiert ist. Jetzt behoben.
Avivr

3

Ich bin gerade in einem ähnlichen Problem gelaufen. git diff filezeigte nichts an, weil ich dem Git-Index eine Datei mit einem Teil des Namens in Großbuchstaben hinzugefügt habe:GeoJSONContainer.js .

Danach habe ich es umbenannt GeoJsonContainer.jsund Änderungen wurden nicht mehr verfolgt. git diff GeoJsonContainer.jszeigte nichts. Ich musste die Datei mit einem Force-Flag aus dem Index entfernen und die Datei erneut hinzufügen:

git rm -f GeoJSONContainer.js
git add GeoJSONContainer.js

2

Sie haben nicht wirklich eine tatsächliche Frage gestellt, aber da dies ein allgemeiner Anwendungsfall ist, verwende ich ziemlich oft Folgendes. Sie können dies selbst versuchen und prüfen, ob der Fehler weiterhin besteht.

Meine Annahme zu Ihrem Anwendungsfall:

Sie haben ein vorhandenes Verzeichnis mit Dateien und Verzeichnissen und möchten es jetzt in ein Git-Repository konvertieren, das von einem anderen Ort geklont wird ohne Daten in Ihrem aktuellen Verzeichnis ändern.

Es gibt wirklich zwei Möglichkeiten.

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

Mit dieser Methode haben Sie das vorhandene Repository in ein leeres Verzeichnis geklont und das .gitVerzeichnis dann in das Zielverzeichnis verschoben . Um ohne Probleme arbeiten zu können, müssen Sie in der Regel ausgeführt werden

git reset --hard

Dies würde jedoch den Status der Dateien in Ihrem aktuellen Verzeichnis ändern. Sie können dies mit einer vollständigen Kopie / rsync Ihres Verzeichnisses versuchen und untersuchen, welche Änderungen vorgenommen wurden. Zumindest danach sollten Sie keine Diskrepanzen mehr zwischen git logund sehen status.

Neues Repository initialisieren - auf Ursprung zeigen

Das zweite ist weniger störend: cdin Ihr Ziel und starten Sie ein neues Repository mit

git init

Dann sagst du diesem neuen Repository, dass es einen Vorfahren an einem anderen Ort hat:

git remote add origin original_git_repo_path

Dann sicher

git fetch origin master

um die Daten zu kopieren, ohne Ihre lokalen Dateien zu ändern. Jetzt sollte alles in Ordnung sein.

Ich empfehle immer den zweiten Weg, um weniger fehleranfällig zu sein.


Sie scheinen zu implizieren, dass dies ein Git-Fehler ist . Ok, könnte sein. Ich nahm immer noch an, dass mir das richtige Git-Verständnis fehlte, weil ich nicht so schlau bin wie Linus ;-)
Towi

@towi: Nein, ich impliziere nicht, dass dies ein Git-Fehler ist, noch impliziere ich das Gegenteil. Ich bin nicht mit den Git-Interna vertraut. Als Faustregel gilt jedoch, dass beim Verschieben von .gitOrdnern in andere Arbeitsbereiche möglicherweise die Annahmen von Git verletzt werden. Wenn dies zu unberechenbarem Verhalten führt, können wir Git nicht beschuldigen, wir müssen uns selbst die Schuld geben, Streiche mit Git zu spielen. git bietet Mittel, um das zu beheben, z reset --hard. Es ist nur so, dass wir das nicht wollen. Dies ist genau der Grund, warum der init/remote addWeg empfohlen wird und alles in Ordnung ist.
cfi

@towi und Oliver P: Obwohl ich verstehe, dass Sie möchten, dass Ihr spezieller Fehlerfall gelöst wird, ist es manchmal nur ratsam, die allgemeinen Empfehlungen zu befolgen - insbesondere, wenn sie perfekt zu Ihrem Anwendungsfall passen. Es gibt auch keinen Datenverlust. Und die remote addArt und Weise, Dinge zu tun, kann immer noch auf eine durcheinandergebrachte Situation angewendet werden, wie sie von Oliver P
cfi

1
Eine Abwertung ohne Kommentar trägt weder zur Verbesserung dieser Antwort noch der gesamten Website bei. Wer auch immer abstimmt, hinterlasse bitte einen Kommentar, damit das Problem behoben werden kann.
cfi

1

Ich bin wieder auf dieses Problem gestoßen. Aber diesmal geschah es aus einem anderen Grund. Ich hatte Dateien in das Repo kopiert, um die vorherigen Versionen zu überschreiben. Jetzt kann ich sehen, dass die Dateien geändert wurden, aber diff gibt die Unterschiede nicht zurück.

Zum Beispiel habe ich eine mainpage.xaml-Datei. Im Datei-Explorer habe ich eine neue mainpage.xaml-Datei über die in meinem aktuellen Repo eingefügt. Ich habe die Arbeit auf einem anderen Computer erledigt und die Datei hier eingefügt.
Git zeigt modifiziert

Die Datei wird geändert angezeigt, aber wenn ich git diff ausführe, werden die Änderungen nicht angezeigt. Dies liegt wahrscheinlich daran, dass sich die Datei in der Datei geändert hat und Git weiß, dass es sich nicht wirklich um dieselbe Datei handelt. Interessant.

Git Diff zeigt nichts

Sie können sehen, dass wenn ich diff für die Datei ausführe, nichts angezeigt wird, sondern nur die Eingabeaufforderung zurückgegeben wird.


1

Ich hatte das gleiche Problem wie folgt beschrieben: Wenn ich tippte

$ git diff

Git kehrte einfach ohne Fehler zur Eingabeaufforderung zurück.

Wenn ich tippte

$ git diff <filename>

Git kehrte einfach ohne Fehler zur Eingabeaufforderung zurück.

Schließlich bemerkte ich beim Herumlesen, dass man git difftatsächlich mingw64\bin\diff.exedie Arbeit erledigen muss.

Das ist der Deal. Ich verwende Windows und habe ein anderes Bash-Dienstprogramm installiert. Es hat meinen Pfad geändert, sodass es nicht mehr auf mein mingw64 \ bin verweist .

Wenn Sie also Folgendes eingeben:

git diff

und es kehrt einfach zu der Eingabeaufforderung zurück, bei der Sie möglicherweise dieses Problem haben.

Die tatsächliche diff.exe, die von ausgeführt wird, gitbefindet sich in Ihrem Verzeichnis mingw64 \ bin

Um dies zu beheben, habe ich meine tatsächlich kopiert mingw64\bin Verzeichnis an den Ort an dem Git danach gesucht hat. Ich habe es versucht und es hat immer noch nicht funktioniert.

Dann schloss ich mein Git Bash- Fenster und öffnete es erneut. Es ging zu demselben Repository, das fehlgeschlagen war, und jetzt funktioniert es.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.