Git auf APFS – worauf Devs achten müssen

git auf APFS

Avatar von Torsten Wunderlich

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.
Avatar von Torsten Wunderlich

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.