Git ändert die Standard-Umask, wenn die Datei aktualisiert wird

Lesezeit: 6 Minuten

Git andert die Standard Umask wenn die Datei aktualisiert wird
Roman Gelemjuk

Ich habe ein Problem mit Git. Ich habe in Google und in StackOverflow nach einer Lösung gesucht, aber nichts hilft.

Das Problem ist, dass jedes Mal, wenn git eine Datei im Arbeitsverzeichnis aktualisiert (wenn ich Zweige auschecke oder einen Zweig zusammenführe usw.), die Dateiberechtigungen so geändert werden, dass das Flag „in Gruppe beschreibbar“ hinzugefügt wird. Und mein Apache zeigt “Error 500” für die Datei an, wenn sie in die Gruppe geschrieben werden kann.

Beispiel: Ich habe eine Datei index.php. Berechtigungen sind “-rwxr-xr-x”. Aktueller (aktiver) Zweig ist Master. Diese Datei wurde im Zweig „develop“ geändert. Ich führe “git checkout developer” aus und die Datei index.php erhält die Berechtigungen “-rwxrwxr-x” (beschreibbar für Gruppe wird hinzugefügt). Und meine Website funktioniert nicht mehr. Da Apache dieses Flag in PHP-Dateien nicht zulässt (ich weiß nicht warum, aber ich kann es nicht ändern).

Jedes Mal, wenn ich “git checkout development” ausführe, muss ich auch “chmod gw index.php” ausführen. Ich mag es nicht, zwei Befehle auszuführen (und manchmal vergesse ich, dies auszuführen, und meine Site funktioniert nicht).

Was kann ich tun, um dieses Problem zu lösen? Ich denke, das hat etwas mit umask zu tun. Ich habe einige Tricks gemacht, die ich im Internet gefunden habe, aber nichts funktioniert.

Danke.

  • Gibt es einen Grund, warum Sie Ihre Umask nicht einfach richtig einstellen können (dh auf 0022 oder ähnliches)?

    – CB Bailey

    20. Juli 12 um 7:18 Uhr


  • Wie macht man das? Um umask zu setzen? Ist das eine Systemänderung oder nur eine Git-Änderung? Wenn System dann kann ich das nicht ändern

    – Roman Gelemjuk

    20. Juli 12 um 7:28 Uhr

  • Renn einfach umask 0022. Um es für interaktive Sitzungen einzustellen, geben Sie diesen Befehl in Ihre ein .bashrc oder Shell-Äquivalent. Um es immer einzustellen, aber es in Ihrem .profile.

    – CB Bailey

    20. Juli 12 um 7:31 Uhr


  • Ich möchte keine Systemeinstellungen ändern. Die Site wird mit diesem Benutzer ausgeführt. Ich befürchte, dies kann sich auf etwas anderes auswirken. Gibt es eine Möglichkeit, das Problem nur mit Änderungen in den Git-Einstellungen zu lösen? Ich weiß, dass es Post-Update-Hooks in Git gibt. Aber ich kann nicht finden, wie ich das mit Hooks lösen kann.

    – Roman Gelemjuk

    20. Juli 12 um 08:06 Uhr

  • Es ist kein Git-Problem, es ist ein umask-Problem; Wenn die Site unter diesem Benutzer ausgeführt wird und nur funktioniert, wenn dieser Benutzer Dateien erstellt, die nicht von der Gruppe beschreibbar sind, dann sicherlich Sie wollen um die umask dieses Benutzers auf 0022 zu ändern. (.profile sind Nutzer Einstellungen, nicht Systemeinstellungen)

    – CB Bailey

    20. Juli 12 um 08:11 Uhr

Schnelle Antwort ist diese Shell-Funktion, die Sie in Ihre einfügen müssen ~/.profile. Es folgt eine Erklärung.

git(){(umask 0022; command git "$@")}

EIN Maske ist Eigenschaft eines Prozesses. Es wird vom übergeordneten Prozess geerbt und kann später von innen geändert werden. Der Befehl zum Ändern von umask heißt normalerweise auch umask.

Git hat keine Konfigurationsoption zum Einstellen seiner umask, es ändert seine umask nicht, nachdem es ausgeführt wurde. Sie müssen Git’s umask von außen setzen, lassen Sie es vom übergeordneten Prozess (normalerweise einer Shell) erben.

Mmm, Sie scheinen die Idee nicht zu mögen, dass irgendetwas außer git umask geändert hat. Also ändern wir es einfach bei der Ausführung git.

Wenn eine Shell eine Zeile ausführt, nimmt sie das erste Wort in der Zeile und versucht, eine Funktion mit diesem Namen zu finden. Nur wenn es keine gibt, versucht es, einen Befehl mit diesem Namen darin zu finden PATH. Die Funktion, die ich oben geschrieben habe, heißt gitdaher jeder direkte Aufruf von git führt es jetzt anstelle von aus git Befehl.

Die Funktion führt eine Subshell aus, ändert ihre umask und führt die aus git Befehl aus der Subshell. Nachdem Git seine Arbeit beendet hat, wird auch die Subshell beendet und die ursprüngliche Shell-Instanz wird immer noch die ursprüngliche umask haben.

Die Funktion zeigt aber auch, wie sie sich selbst umgehen kann. Wenn Sie anrufen git über command git oder auch /usr/bin/git, wird die Funktion nicht aufgerufen. Für jeden anständigen Gebrauch ist dies jedoch gut genug.

Es ist ziemlich gefährlich, die Dateiausführung als Binärdatei zuzulassen. Jedenfalls habe ich das Problem mit umask gelöst. Mein post-receive Skript sieht so aus:

!/bin/sh
umask 002
GIT_WORK_TREE=/var/www/site git checkout -f

So, file permissionist eingestellt 664 und directory permissions einstellen 775was perfekt zu mir passt.

PS Einstellen von umask in a .profile Datei von git Benutzer hat keine Auswirkung, und ich verstehe nicht warum, kommentieren Sie bitte aus, wenn Sie wissen, warum dies geschieht.

  • umask 0022 würde für einen normalen Webserver mehr Sinn machen, da nur der Eigentümer Schreibrechte hat: Resulting in file permission 644 u directory permissions 755

    – Laszlo Schürg

    16. März 18 um 17:33 Uhr

Ich bin gerade auf dieses Problem gestoßen, als ich ein Repo in ein Home-Verzeichnis ausgecheckt habe, das über NFS auf Ubuntu 14.04 (Trusty) mit dem zurückportierten Linux-Kernel Xenial Version 4.x gemountet wurde. Git-Klon in ein lokales Verzeichnis war in Ordnung. Noch seltsamer: Ein zweiter Ubuntu 14.04-Server zeigte nicht das gleiche Problem auf demselben gemounteten Verzeichnis.

Nachdem ich viel herumgestochert hatte, konnte ich mit strace sehen, dass git den open()-Systemaufruf aufrief, um jede Datei mit den Optionen O_CREAT, O_WRONLY und O_EXCL und einem Modus von 0666 zu erstellen, aber dann war der nächste syscal ein fstat() gegen die Datei und sagte mir, es sei Modus 0700. In meinem Fall betraf das Problem nur bestimmte Dateien im Repo. Obwohl „git ls-index“ für die meisten Dateien den Modus 0644 anzeigte, wurden einige von ihnen korrekt erstellt und andere nicht; obwohl es immer die gleichen Dateien waren, die beim Klonen falsche Berechtigungen hatten.

Ich bemerkte, dass es einen Unterschied in der Kernel-Version zwischen den beiden Systemen gab, und entdeckte dann den folgenden Fehler: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1654288

Das Upgrade des Kernels auf 4.4.0-98 (von 4.4.0-59) hat dies für mich behoben. Ich habe einige Hosts überprüft, die noch den Linux-Kernel der Version 3.x verwenden, und diese hatten kein Problem.

Die Verwendung von Hooks zum Ändern des Dateimodus nach dem Auschecken behebt das Problem, nachdem es bereits aufgetreten ist. Sie haben bereits einen schlechten Dateimodus im Dateisystem, wenn Sie den Hook ausführen. Wenn eine Anfrage genau zwischen Checkout und Hook-Ausführung eintrifft, antwortet der Server mit dem 500-Fehler. Aber vielleicht interessiert Sie diese Lösung trotzdem.

Du brauchst ein post-checkout Haken läuft chmod g-w auf alle notwendigen Dateien. Der Haken ist .git/hooks/post-checkoutsollte ausführbar sein und bekommt den Strom HEAD als zweiter Parameter ($2 in der Shell). Der Haken könnte so aussehen:

#!/bin/bash
git ls-files -z --with-tree="$2" | xargs -0 chmod g-w --

Da der Hook keine Liste der ausgecheckten Dateien erhält, ist dies möglicherweise die bestmögliche Implementierung. Es ändert den Modus aller aktuellen Dateien HEAD.

.

821880cookie-checkGit ändert die Standard-Umask, wenn die Datei aktualisiert wird

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy