2010-03-27 24 views
31

Wir haben die git bare-Repository in Unix, die Dateien mit demselben Namen hat, die nur in Fällen unterscheidet.Git-Windows Groß-und Kleinschreibung Dateinamen nicht korrekt behandelt

Beispiel:

GRANT.sql 
grant.sql 

Wenn wir die nackten Repository von Unix in einem Windows-Box, git status erkennt die Datei als geändert klonen. Der Arbeitsbaum wird nur mit grant.sql geladen, aber git status vergleicht grant.sql und GRANT.sql und zeigt die Datei so an, wie sie im Arbeitsbaum geändert wurde.

Ich habe versucht, die core.ignorecase false verwenden, aber das Ergebnis ist das gleiche.

Gibt es eine Möglichkeit, dieses Problem zu beheben?

+0

Super Frage und Gregs Antwort rockt einfach! – Hazok

+0

Dies kann auch passieren, wenn Sie die Datei mit einem anderen Gehäuse in verschiedenen Zweigen unter Windows erstellen. – Thomas

Antwort

4

Ich bin mir nicht sicher, ob das überhaupt möglich ist. Git's ignorecase behandelt Diskrepanzen im Falle der einen Datei. Es wird nicht funktionieren, wenn Windows nicht zwei Dateinamen in einem Verzeichnis haben kann, die sich nur in Groß- und Kleinschreibung unterscheiden.

FWIW, mit zwei identischen Dateinamen, aber für ihren Fall ist eine wirklich schlechte Idee, auch unter Unix.

+0

Wenn nur die Linux-Kernel-Entwickler alle mit Ihnen einverstanden sind ... –

36

Windows ist case-insensitive (genauer, Fall-Erhaltung). Es gibt einfach keine Möglichkeit, dass zwei Dateien existieren, deren Namen sich nur in Groß- und Kleinschreibung unterscheiden: zwei Dateinamen, die sich nur in Groß- und Kleinschreibung unterscheiden, haben denselben Dateinamen. Zeitraum.

Also geht Git das Repository durch und checkt eine Datei nach der anderen aus, bis es die erste der beiden Problemdateien erreicht. Git überprüft es und geht dann weiter, bis es die zweite Datei erreicht. Git überprüft es erneut. Da der Dateiname aus Sicht von Windows derselbe ist wie der erste, wird die erste Datei einfach mit der zweiten Datei überschrieben. Nun denkt Git, dass die erste Datei geändert wurde, um den gleichen Inhalt wie die zweite Datei zu haben.

Beachten Sie, dass dies nichts mit Git zu tun hat: Genau dasselbe würde passieren, wenn Sie einen Tarball, eine Zip-Datei oder ein Subversion-Repository hätten.

Wenn Sie die Entwicklung auf mehreren verschiedenen Plattformen tun wollen, müssen Sie die Einschränkungen dieser Plattformen respektieren und Sie müssen sich gemeinsame Nenner auf den niedrigsten beschränken aller Plattformen, die Sie unterstützen. Windows unterstützt ADS, Linux nicht. OSX unterstützt Ressourcengabeln, Windows nicht. BSD unterstützt Groß-/Kleinschreibung, Windows nicht. Sie können also keines davon verwenden. So ist es halt.

core.ignorecase wird Ihnen hier nicht helfen, denn das behandelt genau das gegenüber Problem.

+2

+1 für detaillierte Erklärung – cctan

+1

Das zu beheben heißt nicht, es einfach funktionieren zu lassen. Dies zu beheben bedeutet, dass Sie verrücktes Verhalten in einen klaren Fehler umwandeln. – jrodman

+1

Dort ist auf jeden Fall eine Möglichkeit für zwei Dateien zu existieren, deren Namen sich nur in Groß- und Kleinschreibung unterscheiden, aber es braucht eine Registry-Änderung. Cygwin macht es, aber ich weiß nicht, ob msys kann (es gibt ein spezielles Flag, das an die Win32-API übergeben werden muss): https://cygwin.com/cygwin-ug-net/using-specialnames.html – Matt

32

Ich habe gerade ein ähnliches Problem festgestellt. In meinem Fall befanden sich die beiden Dateien mit ähnlichen Namen nur in einem Unterverzeichnis, das für den Windows-Klon nicht relevant war. Git 1.7 verfügt über eine Funktion sparse checkout, mit der Sie bestimmte Dateien von einer Arbeitskopie ausschließen können. Um dieses Verzeichnis auszuschließen:

git config core.sparsecheckout true 
echo '*' >.git/info/sparse-checkout 
echo '!unwanted_dir/' >>.git/info/sparse-checkout 
git read-tree --reset -u HEAD 

Danach wurde das unwanted_dir/ Unterverzeichnis vollständig von meiner Arbeitskopie gegangen und Git geht weiter mit dem Rest der Dateien als normal zu arbeiten.

Wenn Ihre GRANT.sql und grant.sql für den Windows-Klon nicht relevant sind, können Sie ihre Namen zu .git/info/sparse-checkout hinzufügen, um diese Dateien speziell auszuschließen.

+1

Dies Antwort war einfach genial und funktioniert auch bei Dateinamen mit zu langen Problemen. Danke für die Erleichterung der Kopfschmerzen, die ich hatte !!! Gab vor ein paar Monaten +1. – Hazok

+1

Große Lösung! Ich brauchte die Einstellung, um 'core.sparseCheckout' zu verwenden, um es zur Arbeit zu bringen –

+1

Der Tipp ist wirklich hilfreich! Genial! – Fei

1

Cygwin behandelt Groß-/Kleinschreibung und lustige Zeichen in Dateinamen viel besser als MSys.

ändern diese Registrierungsschlüssel Groß- und Kleinschreibung in Windows zu aktivieren:

HKLM \ System \ CurrentControlSet \ Control \ Session Manager \ Kernel \ ObCaseInsensitive = 0

here Siehe für einige Einschränkungen, wie Groß- und Kleinschreibung unterstützt wird in Cygwin.

2

Wenn Sie Ihr Repository für nicht-case-sensitive Dateisysteme verwenden möchten, können Sie einen Commit-Hook hinzufügen, der verhindert, dass Sie widersprüchliche Dateien einchecken.

#!/bin/bash 

# Save current state 
git stash -u -q --keep-index || exit 1 

# Get the list of clashing files in the whole repository 
CLASHING=`find "$(git rev-parse --show-toplevel)" | sort | uniq -d -i` 

# Restore previous state 
git stash pop -q 

if [[ $CLASHING ]]; then 
    echo "Found clashing files on case-insensitive file systems" 
    echo "$CLASHING" 
    exit 1 
fi 

exit 0 

Dieses Skript erfordert git Version> = 1.7.7, weil es Stash -u verwendet, andernfalls auf untracked Dateien zu vermeiden.

+1

Es kann bei nicht gepackten Dateien in '.gitignore' fehlschlagen. – djjeck

+0

Kann jemand den aktuellen Baum einschließlich abgestufter Änderungen erhalten? Pass auf, dass das Anhängen von 'git diff --staged' an' HEAD' nicht gut genug ist; zum Beispiel würde es nicht funktionieren, wenn Sie die Groß-/Kleinschreibung eines Dateinamens ändern. – djjeck

+0

Große Lösung. Zu sagen "Tu das nicht" ist sehr wenig hilfreich. Ich kann mir nicht vorstellen, dass ein vernünftiger Shop zwei Dateien oder Ordner zulassen würde, die sich nur dann unterscheiden, wenn sie Linux benutzen. –

1

Die einfachste Art und Weise tatsächlich das Problem zu beheben ist eine der Dateien umbenennen, so dass sie wie Windows oder OS X nicht auf Groß- und Kleinschreibung Dateisystem in Konflikt geraten werden

ein von der Linux begehen Nach/Unix-System, wo Sie das Problem am leichtesten lösen können, wird alles in Ordnung nach einem Zug sein. Um dieses Problem zu vermeiden, müssen Sie einen Commit-Hook hinzufügen, der dem entspricht, was djjeck vorgeschlagen hat.

Die Symptome unter Windows für diese sind sehr verwirrend und beinhalten:

  • Dateien, die immer noch als verändert zeigen, wenn man sie zurückkommen, die sehr schwer zu ändern Zweige oder Rebasing macht.
  • Zwei Kopien der Datei mit den Namen nur bei unterschiedlichen beide zeigt Änderungen in git gui

Da beide Dateien nicht auf einem Groß- und Kleinschreibung Plattform koexistieren Sie haben einen der Dateinamen zu ändern, die zu vermeiden Ärger.

Verwandte Themen