Git: Verhindern Sie Commits im Hauptzweig

80

(Der Einfachheit halber) Ich habe einen masterZweig und einen devin meinem Git-Repo. Ich möchte sicherstellen, dass die masterFiliale immer funktioniert, daher sollte sich meine gesamte Arbeit in der devFiliale befinden.

Wenn ich jedoch meine Änderungen mit einer --no-ffZusammenführung zusammenführe, bleibe ich in der Regel in der masterZweigstelle und arbeite einfach weiter darin (weil ich vergessen habe, meine devZweigstelle auszuchecken ).

Kann ich eine Regel für den masterZweig festlegen, die besagt, dass ich keine Commits ausführen und Zusammenführungen vorspulen kann, sondern nur --no-ffvon einem anderen Zweig?

Dies muss für privat gehostete Repositorys funktionieren (also nicht GitHub und BitBucket).

Rasmus Bækgaard
quelle
3
"Fast-Forward-Commits" sind keine Sache. Commits sind nur Commits, git commitmachen ein neues, es findet kein schneller Vorlauf statt. Es hört sich so an, als ob Sie normale Commits nur verbieten möchten, wenn der aktuelle Zweig masterin diesem Fall in den pre-commitHook schaut .
Torek

Antworten:

149

Ja, es ist möglich. Sie müssen einen Pre-Commit-Hook erstellen, der Commits an den Hauptzweig ablehnt. Git ruft beim Aufrufen des Merge- Befehls keinen Pre-Commit-Hook auf , daher lehnt dieser Hook nur reguläre Commits ab.

  1. Gehen Sie zu Ihrem Repository.
  2. Erstellen Sie die Datei .git / hooks / pre-commit mit folgendem Inhalt:

    #!/bin/sh
    
    branch="$(git rev-parse --abbrev-ref HEAD)"
    
    if [ "$branch" = "master" ]; then
      echo "You can't commit directly to master branch"
      exit 1
    fi
    
  3. Machen Sie es ausführbar (unter Windows nicht erforderlich ):

    $ chmod +x .git/hooks/pre-commit
    

Um Schnellvorlaufzusammenführungen zu deaktivieren , müssen Sie Ihrer .git / config- Datei außerdem die folgende Option hinzufügen :

[branch "master"]
    mergeoptions = --no-ff

Wenn Sie auch den Hauptzweig auf Ihrer Fernbedienung schützen möchten, überprüfen Sie diese Antwort: So beschränken Sie den Zugriff auf den Hauptzweig auf git

qzb
quelle
Das sieht genau so aus, wie ich es brauche - funktioniert das auch unter Windows?
Rasmus Bækgaard
2
@ RasmusBækgaard Ja, das wird es: Das Bash-Skript für den Hook wird von der Git-Bash interpretiert, die in Git für Windows enthalten ist. (Sie brauchen nur nicht den chmod Schritt)
VonC
Hinweis: Sie können auch verhindern, dass Sie auf einen entfernten masterZweig im Pre-Push-Haken drücken. Beispiel: gist.github.com/aaronhoffman/ffbfd36928f9336be2436cffe39feaec
Aaron Hoffman
3
Nizza, für alle, die nach einer Möglichkeit suchen, diese Regeln oder andere Git-Hooks in das Projekt-Repository aufzunehmen, überprüfen Sie dieses einfache npm-Paket: github.com/kilianc/shared-git-hooks , da Sie nichts einschließen können, was sich unter dem befindet .git-Verzeichnis in das Repository.
George Dimitriadis
8
Dies gilt auch nur für unser lokales Git-Repo. Wie können wir Regeln für alle Entwickler in verschiedenen Git-Repos durchsetzen, ohne dass sie den Inhalt des .git-Verzeichnisses manuell ändern müssen?
Alexander Mills
11

Sie können dazu das Pre-Commit- Dienstprogramm verwenden. Es verfügt über einen integrierten no-commit-to-branchHaken, mit dem Commits für einen oder mehrere Zweige verhindert werden können.

Installieren

Der grundlegende Einrichtungsprozess ist:

  • Installation mit Pip oder Brew (Anweisungen unter https://pre-commit.com/#install )
  • Erstellen Sie eine .pre-commit-config.yamlDatei im Stammverzeichnis Ihres Projekts (siehe unten für einen ersten Entwurf)
  • Installieren Sie die Hooks in Ihrer Git-Konfiguration, indem Sie ausführen pre-commit install.

Grundkonfiguration zum Schutz von Zweigen

Hier ist eine grundlegende Konfiguration, die nur den no-commit-to-branchHook enthält:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v3.3.0
  hooks:
    - id: no-commit-to-branch
      args: ['--branch', 'master']

Wenn Sie mehrere Zweige schützen möchten, können Sie mehrere --branchArgumente in die Argumentliste aufnehmen:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: v3.3.0
  hooks:
    - id: no-commit-to-branch
      args: ['--branch', 'master', '--branch', 'staging']

Ist das nicht alles übertrieben?

Pre-Commit verfügt über viele andere integrierte Hooks und eine große Sammlung von Community-Built-Hooks , die die Art und Weise, wie Sie Ihre Commits bereinigen und validieren, verändern. Der Grund, warum ich dies erwähne, ist, dass dieses Tool zwar übertrieben ist, um nur Commits für einen geschützten Zweig zu verhindern, aber viele andere Funktionen aufweist, die es zu einer überzeugenden und einfachen Ergänzung für jedes Git-Projekt machen.

JGC
quelle
6

Es kann sinnvoll sein, es global über zu installieren

git config --global core.hooksPath ~/githooks

und Verschieben dieser pre-commitDatei in dieses Verzeichnis

Michel Samia
quelle
Was ist, wenn ich mehrere Repositorys habe? Betrifft dies nicht alle?
Rasmus Bækgaard
1
und das ist es, was Sie in den meisten Fällen tun können
Michel Samia
Sagen , dass ich dieses seltsame Projekt haben, wo sie umbenannt masterzu Production- können Ausnahmen gemacht werden?
Rasmus Bækgaard
Sie können oder Operator in Bash verwenden, um weitere Zweige anzugeben, die Sie auf Client-Seite schützen möchten
Michel Samia