Git
Chapters ▾ 2nd Edition

8.1 Git einrichten - Git Konfiguration

Bisher haben wir die grundlegende Funktionsweise und die Verwendung von Git erläutert, sowie eine Reihe von Tools vorgestellt, die dir helfen sollen, Git einfach und effizient zu nutzen. In diesem Kapitel werden wir zeigen, wie du Git noch individueller einsetzen kannst, indem du einige wichtige Konfigurationen anpasst und das Hook-System anwendest. Mit diesen Tools ist es einfach, Git genau so einzurichten, wie du, dein Unternehmen oder deine Gruppe es benötigen.

Git Konfiguration

Wie du in Kapitel 1, Erste Schritte bereits kurz gelesen hast, kannst du die Git-Konfigurationseinstellungen mit dem Befehl git config anpassen. Eine der ersten Dinge, die du vorgenommen hast, war die Einrichtung deines Namens und deiner E-Mail-Adresse:

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

Jetzt lernst du einige der interessanteren Optionen kennen, die du auf diese Weise festlegen kannst, um deine Git-Nutzung zu optimieren.

Zunächst eine kleine Übersicht: Git verwendet eine Reihe von Konfigurationsdateien, um das Standard-Verhalten, wie gewünscht, zu verändern. Der erste Ort, in der Git nach solchen Werten sucht, ist die globale Datei [path]/etc/gitconfig. Dort sind die Einstellungen enthalten, die auf jeden Benutzer auf dem System und alle seiner Repositorys angewendet werden. Wenn du die Option --system an git config übergibst, wird diese Datei gezielt ausgelesen und geschrieben.

Der nächste Ort, an dem Git nachschaut, ist die Datei ~/.gitconfig (oder ~/.config/git/config), die spezifisch für jeden Benutzer ist. Du kannst Git veranlassen, diese Datei zu lesen und zu schreiben, indem du die Option --global übergibst.

Schließlich sucht Git nach Informationen in der Konfigurations-Datei im Git-Verzeichnis (.git/config) des jeweiligen Repositorys, das du gerade verwendest. Diese Werte sind spezifisch für dieses spezielle Repository und werden bei Übergabe der Option --local an git config angewendet. Wenn du nichts angibst, welchen Level du ansprechen möchtest, ist das die Voreinstellung.

Jeder dieser „Level“ (system, global, lokal) überschreibt Werte der vorigen Ebene. Daher werden beispielsweise Werte in .git/config jene in [path]/etc/gitconfig überschreiben.

Anmerkung

Die Konfigurationsdateien von Git sind reine Textdateien, so dass du diese Werte auch ändern kannst, wenn du die Datei manuell bearbeitest. Es ist jedoch generell einfacher und sicherer, den git config Befehl zu benutzen.

Grundeinstellungen des Clients

Die von Git erkannten Einstelloptionen lassen sich in zwei Kategorien einteilen: client-seitig und serverseitig. Die meisten Optionen beziehen sich auf die Clientseite – die Konfiguration deiner persönlichen Arbeitseinstellungen. Sehr sehr viele Konfigurationsoptionen stehen zur Verfügung, aber ein großer Teil davon ist nur in bestimmten Grenzfällen sinnvoll. Wir werden hier nur die gebräuchlichsten und nützlichsten Optionen behandeln. Wenn du eine Liste aller Optionen sehen möchtest, die deine Version von Git kennt, kannst di Folgendes aufrufen:

$ man git-config

Dieser Befehl listet alle verfügbaren Optionen detailliert auf. Du findest dieses Referenzmaterial auch unter https://git-scm.com/docs/git-config.

Anmerkung

Für fortgeschrittene Anwendungsfälle kannst du in der oben erwähnten Dokumentation nach „Conditional includes“ suchen.

core.editor

Um deine Commit- und Tag-Beschreibungen erstellen/bearbeiten zu können verwendet Git das von dir als Standard-Text-Editor eingestellte Programm aus einer der Shell-Umgebungs-Variablen VISUAL oder EDITOR. Alternativ greift Git auf den vi-Editor zurück. Diesen Standard kannst du ändern, indem du die Einstellung core.editor verwendest:

$ git config --global core.editor emacs

Jetzt wird Git Emacs starten, unabhängig davon, was als Standard-Shell-Editor eingestellt ist, um die Texte zu bearbeiten.

commit.template

Wenn du dieses Attribut auf die Pfadangabe einer Datei auf deinem System setzt, verwendet Git diese Datei als initiale Standard-Nachricht, wenn du einen Commit durchführst. Der Vorteil bei der Erstellung einer benutzerdefinierten Commit-Vorlage besteht darin, dass du sie verwenden kannst, um sich (oder andere) beim Erstellen einer Commit-Nachricht an das richtige Format und den richtigen Stil zu erinnern.

Nehmen wir z.B. eine Template-Datei unter ~/.gitmessage.txt, die so aussieht:

Subject line (try to keep under 50 characters)

Multi-line description of commit,
feel free to be detailed.

[Ticket: X]

Diese Commit-Vorlage erinnert den Committer daran, die Betreffzeile kurz zu halten (für die git log --oneline Ausgabe)., weitere Details hinzuzufügen und sich auf ein Problem oder eine Bug-Tracker-Ticketnummer zu beziehen, falls vorhanden.

Um Git anzuweisen, das als Standardnachricht zu verwenden, die in deinem Editor erscheint, wenn du git commit ausführst, setze den Konfigurationswert commit.template:

$ git config --global commit.template ~/.gitmessage.txt
$ git commit

Dann öffnet sich dein Text-Editor in etwa so für deine Commit-Beschreibung, wenn du committest:

Subject line (try to keep under 50 characters)

Multi-line description of commit,
feel free to be detailed.

[Ticket: X]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   lib/test.rb
#
~
~
".git/COMMIT_EDITMSG" 14L, 297C

Mit einer eigenen Regel für Commit-Beschreibungen und dem Einfügen einer entsprechenden Vorlage in die Git-Konfiguration deines Systems erhöht sich die Wahrscheinlichkeit, dass diese Regel regelmäßig eingehalten wird.

core.pager

Diese Einstellung bestimmt, welcher Pager genutzt werden soll, wenn git den Output von log und diff seitenweise ausgeben soll. Den Wert kann auf more oder wie von dir bevorzugt eingestellt werden (Standard ist less). Du kannst ihn deaktivieren, indem du eine leere Zeichenkette verwendest:

$ git config --global core.pager ''

Wenn du diese Konfiguration nutzt, wird Git die komplette Ausgabe aller Befehle anzeigen, unabhängig davon, wie lang sie sind.

user.signingkey

Wenn du signierte und annotierte Tags erstellst (wie in Kapitel 7, Ihre Arbeit signieren beschrieben), erleichtert die Definition deines GPG-Signierschlüssels in der Konfigurations-Einstellung die Arbeit. Stelle deine Schlüssel-ID so ein:

$ git config --global user.signingkey <gpg-key-id>

Jetzt kannst du Tags signieren, ohne jedes Mal deinen Schlüssel mit dem Befehl git tag angeben zu müssen:

$ git tag -s <tag-name>

core.excludesfile

Du kannst Suchmuster in die .gitignore Datei deines Projekts einfügen. Damit kannst du verhindern, dass Git bestimmte Dateien als nicht in der Versionsverwaltung erfasste Dateien erkennt und sie zum Commit vormerken will, wenn du git add darauf ausführst, wie in Kapitel 2, Ignorieren von Dateien beschrieben.

In manchen Fällen sollen bestimmte Dateien für alle Repositorys ignoriert werden, in denen du arbeitest. Falls du macOS verwendest, kennst du vermutlich die .DS_Store Dateien. Bei Emacs oder Vim kennst du vielleicht Dateien, die mit einer Tilde (~) oder auf .swp enden.

Mit dieser Einstellung kannst du eine Art globale .gitignore Datei schreiben. Erstelle eine ~/.gitignore_global Datei mit diesem Inhalt:

*~
.*.swp
.DS_Store

… und dann führst du git config --global core.excludesfile ~/.gitignore_global aus. Git wird sich nie wieder um diese Dateien kümmern.

help.autocorrect

Wenn du dich bei einem Befehl vertippst, zeigt das System dir so etwas wie das hier:

$ git chekcout master
git: 'chekcout' is not a git command. See 'git --help'.

The most similar command is
    checkout

Git hilft dir dabei herauszufinden, was du gemeint hast, aber es führt den Befehl nicht aus. Wenn du help.autocorrect auf 1 setzt, dann führt Git den vorgeschlagenen Befehl auch aus:

$ git chekcout master
WARNING: You called a Git command named 'chekcout', which does not exist.
Continuing under the assumption that you meant 'checkout'
in 0.1 seconds automatically...

Beachte die „0,1 Sekunden“ Angabe. help.autocorrect ist eigentlich eine Ganzzahl, die Zehntelsekunden repräsentiert. Wenn du den Wert auf 50 setzt, gibt dir Git 5 Sekunden Zeit deine Meinung zu ändern, bevor der autokorrigierte Befehl ausgeführt wird.

Farben in Git

Git unterstützt die farbige Terminalausgabe, was sehr nützlich ist, um die Befehlsausgabe schnell und einfach visuell zu verarbeiten. Eine Reihe von Optionen können dir helfen, die Farbgestaltung nach deinen Wünschen einzustellen.

color.ui

Git färbt den größten Teil seiner Ausgabe automatisch ein, aber es gibt einen Hauptschalter, wenn dir dieses Verhalten nicht gefällt. Um alle farbigen Terminalausgaben von Git auszuschalten, nutze Folgendes:

$ git config --global color.ui false

Die Standardeinstellung ist auto, das die Ausgabe von Farben ausgibt, wenn es direkt zu einem Terminal geht, aber die Farbkontrollcodes weglässt, wenn die Ausgabe in eine Pipe oder eine Datei umgeleitet wird.

Du kannst es auch auf always einstellen, dass der Unterschied zwischen Terminals und Pipes ignoriert. Das willst du in der Regel nicht. In den meisten Szenarien kannst du stattdessen ein --color Flag an den Git-Befehl übergeben, um ihn zu zwingen, Farbcodes zu verwenden, wenn du Farbcodes in deine umgeleiteten Ausgabe wünschst. Die Voreinstellung ist fast immer die Richtige.

color.*

Wenn du genauer bestimmen möchtest, welche Befehle wie eingefärbt werden, dann bietet Git sehr spezifische Farbeinstellungen. Die einzelnen Befehle können auf true, false, oder always gesetzt werden:

color.branch
color.diff
color.interactive
color.status

Darüber hinaus hat jede dieser Optionen Untereinstellungen, mit denen du bestimmte Farben für Teile der Ausgabe festlegen kannst, falls du die Farben überschreiben willst. Um beispielsweise die Metainformationen in deiner Diff-Ausgabe auf blauen Vordergrund, schwarzen Hintergrund und fetten Text zu setzen, kannst du Folgendes ausführen:

$ git config --global color.diff.meta "blue black bold"

Du kannst die Farbe auf einen der folgenden Werte setzen: normal, black, red, green, yellow, blue, magenta, cyan oder white. Wenn du ein Attribut wie im vorherigen Beispiel fett wünschst, kannst du zwischen bold (fett), dim (abgedunkelt), ul (unterstrichen), blink (blinken) und reverse (Vorder- und Hintergrund vertauschen) wählen.

Externe Merge- und Diff-Tools

Obwohl Git eine interne Diff-Implementierung hat, die wir in diesem Buch vorgestellt haben, kannst du stattdessen ein externes Tool verwenden. Du kannst auch ein grafisches Tool zum Mergen und Lösen von Konflikten einrichten, anstatt Konflikte manuell lösen zu müssen. Wir zeigen dir, wie du das Tool Perforce Visual Merge (P4Merge) einrichtest, um deine Diffs und Merge-Ansichten zu analysieren. P4Merge ist ein praktisches grafisches Tool und dazu noch kostenlos.

Es zu installieren, sollte kein Problem sein, denn P4Merge läuft auf allen wichtigen Plattformen. Wir verwenden Pfadnamen in den Beispielen, die auf macOS- und Linux-Systemen funktionieren. Unter Windows musst du /usr/local/bin in einen ausführbaren Pfad in deiner Umgebung umändern.

Starte mit P4Merge von Perforce downloaden. Richte danach externe Wrapper-Skripte ein, um deine Befehle auszuführen. Wir verwenden hier den macOS-Pfad für die ausführbare Datei. In anderen Systemen sollte er so angepasst werden, dass er auf den Ordner verweist, in dem dein p4merge Binary installiert ist. Richte ein Merge-Wrapper-Skript mit dem Namen extMerge ein, das deine Binärdatei mit allen angegebenen Argumenten aufruft:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*

Der diff Wrapper überprüft, ob sieben Argumente angegeben sind und übergibt zwei davon an dein Merge-Skript. Standardmäßig übergibt Git die folgenden Argumente an das Diff-Programm:

path old-file old-hex old-mode new-file new-hex new-mode

Da du nur die Argumente old-file und new-file benötigst, verwendest du das Wrapper-Skript, um diese zu übergeben.

$ cat /usr/local/bin/extDiff
#!/bin/sh
[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"

Du musst außerdem darauf achten, dass diese Tools ausführbar sind:

$ sudo chmod +x /usr/local/bin/extMerge
$ sudo chmod +x /usr/local/bin/extDiff

Jetzt kannst du deine Konfigurationsdatei so einrichten, dass sie deine benutzerdefinierte Merge-Lösung und Diff-Tools nutzt. Dazu sind eine Reihe von benutzerdefinierten Einstellungen erforderlich: merge.tool, um Git mitzuteilen, welche Strategie zu verwenden ist, mergetool.<tool>.cmd, um anzugeben, wie der Befehl ausgeführt werden soll, mergetool.<tool>.trustExitCode, um Git mitzuteilen, ob der Exit-Code dieses Programms eine erfolgreiche Merge-Lösung anzeigt oder nicht, und diff.external, um Git mitzuteilen, welchen Befehl es für diffs ausführen soll. Du kannst also entweder die vier Konfigurationsbefehle ausführen:

$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \
  'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global mergetool.extMerge.trustExitCode false
$ git config --global diff.external extDiff

oder du kannst die ~/.gitconfig Datei bearbeiten und diese Zeilen hinzufügen:

[merge]
  tool = extMerge
[mergetool "extMerge"]
  cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
  trustExitCode = false
[diff]
  external = extDiff

Wenn das alles konfiguriert ist, kannst du diff Befehle wie diesen ausführen:

$ git diff 32d1776b1^ 32d1776b1

Statt die Diff-Ausgabe auf der Kommandozeile zu erhalten, wird P4Merge von Git gestartet, was folgendermaßen aussieht:

P4Merge
Abbildung 168. P4Merge

Wenn du versuchst, zwei Branches zu mergen und dabei Merge-Konflikte hast, kannst du den Befehl git mergetool ausführen. Er startet P4Merge, um diese Konflikte über das GUI-Tool zu lösen.

Das Tolle an diesem Wrapper-Setup ist, dass du deine Diff- und Merge-Tools einfach ändern kannst. Um beispielsweise deine Tools extDiff und extMerge so zu ändern, dass das KDiff3-Tool stattdessen ausgeführt wird, musst du nur deine extMerge Datei bearbeiten:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*

Nun wird Git das KDiff3-Tool für das Diff-Viewing und die Lösung der Merge-Konflikte verwenden.

Git ist standardmäßig so eingestellt, dass es eine Reihe anderer Tools zum Auflösen von Merges verwendet, ohne dass du die cmd-Konfiguration einrichten musst. Um eine Liste der unterstützten Tools anzuzeigen, versuche es wie folgt:

$ git mergetool --tool-help
'git mergetool --tool=<tool>' may be set to one of the following:
        emerge
        gvimdiff
        gvimdiff2
        opendiff
        p4merge
        vimdiff
        vimdiff2

The following tools are valid, but not currently available:
        araxis
        bc3
        codecompare
        deltawalker
        diffmerge
        diffuse
        ecmerge
        kdiff3
        meld
        tkdiff
        tortoisemerge
        xxdiff

Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.

Wenn du nicht daran interessiert bist, KDiff3 für diff zu verwenden, sondern es nur für die Merge-Auflösung verwenden willst und der Befehl kdiff3 in deinem Pfad steht, dann kannst du Folgendes ausführen:

$ git config --global merge.tool kdiff3

Wenn du diese Methode verwendest, ohne die Dateien extMerge und extDiff einzurichten, verwendet Git KDiff3 für die Merge-Auflösung und das normale Git diff-Tool für Diffs.

Formatierung und Leerzeichen

Formatierungs- und Leerzeichen-Probleme sind einige der frustrierendsten und schwierigsten Probleme, auf die viele Entwickler bei der Teamarbeit stoßen, vor allem in plattformübergreifenden Projekten. Es ist sehr einfach für Patches oder andere kollaborative Arbeiten, geringfügige Änderungen an Leerzeichen vorzunehmen, da die Editoren diese im Hintergrund einfügen. Falls deine Dateien jemals mit einem Windows-System in Kontakt kommen, werden ihre Zeilenenden möglicherweise ersetzt. Git hat einige Konfigurationsoptionen, um bei diesen Schwierigkeiten zu helfen.

core.autocrlf

Wenn du unter Windows programmierst und mit Leuten arbeitest, die andere Systeme verwenden (oder umgekehrt), wirst du wahrscheinlich irgendwann auf Probleme mit den Zeilenenden treffen. Der Grund hierfür ist, dass Windows in seinen Dateien sowohl ein Carriage-Return-Zeichen als auch ein Linefeed-Zeichen für Zeilenumbrüche verwendet, während macOS- und Linux-Systeme nur das Linefeed-Zeichen verwenden. Viele Editoren unter Windows ersetzen im Hintergrund bestehende Zeilenenden im LF-Stil durch CRLF oder fügen beide Zeilenendezeichen ein, wenn der Benutzer die Eingabetaste drückt.

Git kann das durch automatische Konvertierung von CRLF-Zeilenenden in LF übernehmen, wenn du eine Datei zum Index hinzufügest, und umgekehrt, wenn es Code auf dein Dateisystem auscheckt. Du kannst diese Funktionen mit der core.autocrlf Einstellung einschalten. Wenn du dich auf einem Windows-Computer befindest, setze die Einstellung auf true. das konvertiert LF-Endungen in CRLF, wenn du Code auscheckst:

$ git config --global core.autocrlf true

Auf einem Linux- oder macOS-System, das LF-Zeilenenden verwendet, solltest du nicht zulassen, dass Git Dateien automatisch konvertiert, wenn du sie auscheckst. Falls jedoch versehentlich eine Datei mit CRLF-Endungen hinzugefügt wird, kannst du dafür sorgen, dass Git sie korrigiert. Du kannst Git anweisen, CRLF beim Commit in LF zu konvertieren, aber nicht umgekehrt, indem du core.autocrlf auf input setzt:

$ git config --global core.autocrlf input

Dieses Setup sollte deine CRLF-Endungen in Windows-Checkouts nicht ändern, aber LF-Endungen auf macOS- und Linux-Systemen und im Repository.

Wenn du ein Windows-Programmierer bist, der ein reines Windows-Projekt durchführt, dann kannst du diese Funktionalität deaktivieren und die Carriage Returns im Repository aufzeichnen, indem du den Konfigurationswert auf false setzt:

$ git config --global core.autocrlf false

core.whitespace

Git wird von Hause aus mit einer Voreinstellung zur Erkennung und Behebung einiger Leerzeichen-Probleme installiert. Es kann nach sechs primären Leerzeichen-Problemen suchen. Drei sind standardmäßig aktiviert und können deaktiviert werden, und drei sind standardmäßig deaktiviert, können aber aktiviert werden.

Die drei, bei denen die Standardeinstellung eingeschaltet ist, sind blank-at-eol, das nach Leerzeichen am Ende einer Zeile sucht; blank-at-eof, das leere Zeilen am Ende einer Datei bemerkt und space-before-tab, das nach Leerzeichen vor Tabulatoren am Anfang einer Zeile sucht.

Die drei, die standardmäßig deaktiviert sind, aber eingeschaltet werden können, sind indent-with-non-tab, das nach Zeilen sucht, die mit Leerzeichen anstelle von Tabs beginnen (und von der Option tabwidth kontrolliert werden); tab-in-indent, das nach Tabs im Einzug einer Zeile sucht und cr-at-eol, das Git mitteilt, dass Carriage Returns am Ende von Zeilen OK sind.

Du kannst mit Git bestimmen, welche dieser Optionen aktiviert werden sollen. Setze dazu, getrennt durch Kommas, core.whitespace auf den gewünschten Wert (ein oder aus). Du kannst eine Option deaktivieren, indem du ein - (Minus-Zeichen) dem Namen voranstellst, oder den Standardwert verwendest, indem du ihn ganz aus der Zeichenkette der Einstellung entfernst. Wenn du z.B. möchtest, dass alles außer space-before-tab gesetzt wird, kannst du das so machen (wobei trailing-space eine Kurzform ist, um sowohl blank-at-eol als auch blank-at-eof abzudecken):

$ git config --global core.whitespace \
    trailing-space,-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol

Oder du kannst nur den anzupassenden Teil angeben:

$ git config --global core.whitespace \
    -space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol

Git wird diese Punkte erkennen, wenn du einen git diff Befehl ausführst und versuchen sie einzufärben, damit du sie gegebenenfalls vor dem Commit beheben kannst. Git wird diese Werte auch verwenden, um dir zu helfen, wenn du Patches mit git apply einspielst. Wenn du Patches installieren, kannst du Git bitten, dich zu warnen, wenn es Patches mit den angegebenen Leerzeichen-Problemen anwendet:

$ git apply --whitespace=warn <patch>

Du kannst auch Git versuchen lassen, das Problem automatisch zu beheben, bevor du den Patch einspielst:

$ git apply --whitespace=fix <patch>

Diese Optionen gelten auch für den Befehl git rebase. Wenn du Leerzeichen-Probleme committet hast, aber noch nicht zum Upstream gepusht hast, kannst du git rebase --whitespace=fix ausführen, damit Git Leerzeichen-Probleme automatisch behebt, während es die Patches neu schreibt.

Server-Konfiguration

Für die Serverseite von Git stehen nicht annähernd so viele Konfigurationsoptionen zur Verfügung. Es gibt jedoch einige wichtige Einstellungen, die du beachten solltest.

receive.fsckObjects

Git ist in der Lage zu kontrollieren, ob jedes während eines Pushs empfangene Objekt noch mit seiner SHA-1-Prüfsumme übereinstimmt und auf gültige Objekte zeigt. Standardmäßig tut es das jedoch nicht. Es ist eine ziemlich aufwändige Operation und kann den Betrieb verlangsamen, insbesondere bei großen Repositorys oder Pushes. Wenn du möchtest, dass Git bei jedem Push die Objektkonsistenz überprüft, kannst du es dazu zwingen, indem du receive.fsckObjects auf true setzt:

$ git config --system receive.fsckObjects true

Jetzt prüft Git die Integrität deines Repositorys, noch bevor jeder Push akzeptiert wird, um sicherzustellen, dass fehlerhafte (oder böswillige) Clients keine korrupten Daten einschleusen.

receive.denyNonFastForwards

Wenn du Commits rebased, die du bereits gepusht hast, und dann versuchst, erneut zu pushen, oder anderweitig versuchst, einen Commit an einen Remote-Branch zu senden, der nicht den Commit enthält, auf den der Remote-Branch aktuell zeigt, wird dies abgelehnt. Im Allgemeinen ist das eine gute Richtlinie. Bei dem Rebase kannst du festlegen den Remote-Branch mit einem -f Flag in deinem Push-Befehl zu aktualisieren, wenn du weißt, was du tust.

Um Git anzuweisen, Force-Pushes abzulehnen, setze receive.denyNonFastForwards:

$ git config --system receive.denyNonFastForwards true

Die andere Möglichkeit ist, das über serverseitige Receive-Hooks tun, die wir im weiteren Verlauf behandeln werden. Dieser Ansatz ermöglicht es dir, komplexere Dinge zu tun, wie z.B. einem bestimmten Teil der Benutzer die Möglichkeit „non-fast-forwards“ zu verweigern.

receive.denyDeletes

Ein möglicher Workaround für die denyNonFastForwards Regel besteht darin, dass der Benutzer den Branch löscht und ihn dann mit einer neuen Referenz wieder pusht. Um das zu verhindern, setze receive.denyDeletes auf true:

$ git config --system receive.denyDeletes true

Dadurch wird das Löschen von Branches oder Tags verhindert – kein User darf das dann tun. Um dann Remote-Branches zu entfernen, musst du die ref-Dateien manuell vom Server entfernen. Es gibt weitere interessante Möglichkeiten, das auf Benutzerebene über ACLs zu realisieren, wie du in Beispiel für Git-forcierte Regeln erfahren wirst.

scroll-to-top