Was mir neulich passierte … Danke an meine Kollegin Amina, die in die gleiche Falle getappt ist und mir einen dezenten Hinweis gegeben hat.
Folgende Situation: Du hast einen neuen Mac und hast ihn mit den Voreinstellungen und dem voreingestellten Dateisystem eingerichtet, um schnell loslegen zu können. Was könnte in den nächsten Monaten schief gehen?
… und dann kam git auf APFS
Nachdem du deinen Mac einige Zeit benutzt hast, darfst du mit deinem Team an einem Stück Software arbeiten. Du klonst das Repository und … Oh, nein!
❯ git clone git@github.com:wunderlicht/gitonapfs.git Cloning into 'gitonapfs'... remote: Enumerating objects: 15, done. remote: Counting objects: 100% (15/15), done. remote: Compressing objects: 100% (13/13), done. remote: Total 15 (delta 2), reused 5 (delta 0), pack-reused 0 Receiving objects: 100% (15/15), 4.24 KiB | 4.24 MiB/s, done. Resolving deltas: 100% (2/2), done. warning: the following paths have collided (e.g. case-sensitive paths on a case-insensitive filesystem) and only one from the same colliding group is in the working tree: 'tests/Test.txt' 'tests/test.txt'
Das obige Repository ist übrigens ein guter Test, um herauszufinden, ob das Problem bei Dir überhaupt besteht und ob die gezeigte Lösung funktioniert.
Warum passiert das?
In dem Repository, das du klonen willst, befinden sich Dateien mit demselben Namen, die sich nur durch die Groß- und Kleinschreibung unterscheiden – wie im folgenden Beispiel gezeigt:
test Test ./tests/ ./Tests/
Ok, aber wer hat sie überhaupt erst dort so ablegen können?
Einige deiner Mit-Entwickelnden arbeiten höchstwahrscheinlich auf einem Linux-System mit einem Dateisystem, das Groß- und Kleinschreibung berücksichtigt.
Das Standard-Dateisystem für neue Macs mit SSDs ist APFS. Leider in der Variante, die Groß- und Kleinschreibung nicht berücksichtigt. Das bedeutet, dass „file“ und „File“ das Gleiche sind.
Was nun?
Was sind deine Möglichkeiten?
- Formatiere deinen Mac neu. Ja, klar. Du musst was liefern und kannst nicht einen halben Tag damit verbringen, deinen Mac neu zu formatieren und von einem Time-Machine-Backup wiederherzustellen.
- Bitte eine*n andere*n Entwickler*in aus deinem Team, die „gleichen“ Namen im Repository zu entfernen. Offensichtlich kannst du es nicht selbst tun.
- … oder kannst du es doch?
Doch, du kannst! Die Lösung sind Sparsebundles (eine Art Image) mit einem Dateisystem, das zwischen Groß- und Kleinschreibung unterscheidet und das du in dein bestehendes Dateisystem einbinden kannst.
Erstelle ein geeignetes Image
hdiutil create -size 100M -fs "Case-sensitive APFS" -type SPARSEBUNDLE -volname devimage devimage
Dies erzeugt ein mitwachsendes Sparsebundle mit 100MB Anfangsgröße und einem Case-sensitiven APFS-Dateisystem mit dem Volume-Namen devimage
in einem neuen Bundle-Verzeichnis devimage.sparcebundle
.
Hänge das Image ein
Wir benötigen zuerst einen Mount Point:
mkdir ./repos
Nun mounten wir das Image:
hdiutil attach devimage.sparsebundle -mountpoint ./repos
Um das Image nachher wieder problemlos auszuhängen, müssen wir noch Spotlight verbieten, dessen normalerweise nützliche Arbeit zu tun. Also verbieten wir das Erstellen der Indexe und das Suchen.
sudo mdutil -i off -d ./repos
Klone ein Repository in das angehängte Image
Wechsle in das Verzeichnis
cd ./repos git clone <Repository>
Arbeite nun etwas an deiner Software. Vielleicht benennst du die Dateien in etwas besser Unterscheidbares um.
Hinweis
Du kannst ein Repository nicht direkt nach ./repos klonen. Sobald das Image gemountet ist, existieren einige Metadaten des Images in einem versteckten Verzeichnis. Daher ist ./repo nicht leer und git wird sich beschweren. Natürlich gibt es dafür eine Lösung. Aus Gründen der Übersicht lassen wir das hier mal weg.Das Image aushängen
Wenn die Arbeit getan ist, entferne das Image.
hdiutil detach ./repos
Mögliche Probleme
Ich habe festgestellt, dass sich das Image manchmal nicht aushängen lässt; manchmal bleiben Dateien ohne offensichtlichen Grund geöffnet. Diese kann man sich anzeigen lassen, um der Sache auf den Grund zu gehen.
lsof -D ./repos
Normalerweise löst sich das Problem von selbst, wenn man seine Terminal-Session beendet. Wenn es aber doch einmal sein muss, kannst du das Image auch unter Zwang aushängen.
hdiutil detach -force ./repos
Was bleibt als Erkenntnis?
- Wenn du einen neuen Mac installierst, solltest du deine SSD mit dem Dateisystem APFS (Groß-/Kleinschreibung) formatieren (vorzugsweise mit dessen verschlüsselter Variante) oder …
- Verwende klar unterscheidbare Namen in deiner Codebase. Was ohnehin viel besser ist.
Schreibe einen Kommentar