diff --git a/.gitattributes b/.gitattributes index 49217959..f3d49dc4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -26,3 +26,14 @@ *.woff binary *.woff2 binary *.conf text eol=lf + +# Die git-Haken haben KEINE Endung -- keine der Regeln oben greift auf +# sie. Nachgemessen am 01.10.2026: Im Verlauf lagen 73 CR-Bytes in +# tools/git-haken/pre-commit. +# +# Auf Windows blockiert der Haken damit trotzdem richtig (gemessen: +# Rueckgabe 1, 0 Commits) -- auf Linux nicht, dort ist "#!/bin/sh " +# ein Programmname mit einem unsichtbaren Zeichen am Ende. Das ist +# Vorsorge, keine Reparatur: Ein Haken, der still nicht laeuft, ist +# genau die Sicherung, die aussieht, als waere sie da. +tools/git-haken/* text eol=lf diff --git a/server/pruef-arbeitsschloss.mjs b/server/pruef-arbeitsschloss.mjs index 848ea39e..39dcd928 100644 --- a/server/pruef-arbeitsschloss.mjs +++ b/server/pruef-arbeitsschloss.mjs @@ -64,6 +64,39 @@ ok(existsSync(HAKEN), "tools/git-haken/pre-commit ist da"); ".arbeitsschloss steht in .gitignore (sonst waere es ein Schloss von gestern)"); } +/* ==== DER HAKEN BRAUCHT LINUX-ZEILENENDEN ========================= + + Er hat KEINE Dateiendung, also greift keine der Regeln in + .gitattributes von sich aus. Ohne eine eigene Zeile dort wandelt + git ihn beim Auschecken auf Windows in CRLF -- und auf Linux ist + `#!/bin/sh` mit einem CR dahinter ein Programmname mit einem + unsichtbaren Zeichen am Ende („bad interpreter"). + + NACHGEMESSEN AM 01.10.2026, damit hier keine Behauptung steht: + Auf Windows blockiert auch ein CRLF-Haken richtig (Rueckgabe 1, + null Commits). Die Regel ist also Vorsorge und keine Reparatur -- + aber ein Haken, der still nicht laeuft, ist genau die Sicherung, + die aussieht, als waere sie da. + + UND EINE LEHRE AUS DEM MESSEN SELBST: Meine erste Messung + meldete 73 CR-Bytes, wo keines war. Gemessen hatte ich mit + einer Rohrkette aus `tr` und `od`, und `tr` nimmt in dieser + Shell die Maskierung fuer das Wagenruecklauf-Zeichen nicht als + Zeichen -- gezaehlt wurden am Ende Zeilenenden. + + Byteweise wird deshalb hier gemessen, nicht in einer + Rohrkette: `readFileSync` ohne Zeichensatz gibt Bytes, und + 13 ist 13. + */ +{ + const roh = readFileSync(HAKEN); + ok(!roh.includes(13), + `der Haken hat reine LF-Zeilenenden (${roh.filter((b) => b === 13).length} CR)`); + const regeln = readFileSync(join(WURZEL, ".gitattributes"), "utf8"); + ok(/tools\/git-haken\/\*\s+text\s+eol=lf/.test(regeln), + ".gitattributes haelt den Haken auf LF (er hat keine Endung)"); +} + /* DER HAKEN MUSS AUCH GEFUNDEN WERDEN. `.git/hooks` wird nicht versioniert; ohne `core.hooksPath` liegt der Haken im Baum und tut nichts. Das ist die Sorte Sicherung, die aussieht, als wäre sie da. */