Merge Request Pipelines vs. Branch Pipelines: der Unterschied
AI generated
CI/CD
.yml
GitLab · CI/CD · DevOps
Merge Request Pipelines
vs. Branch Pipelines: der Unterschied

Wer in GitLab CI ploetzlich zwei Pipelines fuer denselben Commit sieht, stoesst meist auf den Unterschied zwischen Branch-Pipelines und Merge-Request-Pipelines: Erstere testen den tatsaechlichen Push-Zustand eines Branches, Letztere simulieren, wie der Code nach einem Merge aussehen wuerde. Dieser Artikel erklaert den Unterschied im Detail und zeigt, wie sich mit workflow:rules doppelte Pipelines zuverlaessig vermeiden lassen.

16 Min. Lesezeit Merge Request Pipelines Branch Pipelines workflow:rules CI_PIPELINE_SOURCE

1. Was eine Branch-Pipeline tatsaechlich testet

Eine Branch-Pipeline, in GitLab intern als push-Pipeline gefuehrt, startet automatisch bei jedem Push auf einen Branch und testet exakt den Zustand des Codes, wie er in diesem Branch zu diesem Zeitpunkt vorliegt. Das ist das Standardverhalten, das viele Entwickler von GitLab kennen, und es beantwortet eine klare Frage: Funktioniert der Code so, wie er gerade im Branch steht. Fuer Feature-Branches ohne aktiven Merge Request ist das oft die einzig sinnvolle Frage, weil noch gar nicht feststeht, in welchen Ziel-Branch der Code irgendwann gemerged wird.

Der entscheidende Punkt ist, dass eine Branch-Pipeline nichts darueber aussagt, wie der Code sich verhaelt, nachdem er mit dem Ziel-Branch zusammengefuehrt wurde. Wenn zwischen dem letzten Push auf den Feature-Branch und dem tatsaechlichen Merge noch Aenderungen am Ziel-Branch, meist main oder develop, dazukommen, kann es zu Konflikten oder zu subtilen Inkompatibilitaeten kommen, die eine reine Branch-Pipeline niemals aufdeckt, weil sie den Ziel-Branch bei ihrem Testlauf komplett ignoriert. Genau diese Luecke schliessen Merge-Request-Pipelines.

2. Wie Merge-Request-Pipelines den Ergebniszustand testen

Eine Merge-Request-Pipeline wird ausgeloest, sobald ein Merge Request geoeffnet oder aktualisiert wird, und sie testet nicht den reinen Branch-Zustand, sondern einen simulierten Merge-Commit, der aus dem aktuellen Stand des Feature-Branches und dem aktuellen Stand des Ziel-Branches gebildet wird. GitLab erzeugt dafuer intern einen temporaeren Merge-Ref, der beide Zustaende zusammenfuehrt, und fuehrt die Pipeline gegen diesen simulierten Zustand aus, nicht gegen den reinen Feature-Branch. Damit beantwortet eine Merge-Request-Pipeline die eigentlich relevante Frage: Funktioniert der Code, nachdem er tatsaechlich gemerged wurde, inklusive aller zwischenzeitlichen Aenderungen am Ziel-Branch.

Diese Eigenschaft macht Merge-Request-Pipelines besonders wertvoll in Teams mit hoher Commit-Frequenz auf dem Ziel-Branch, weil dort die Wahrscheinlichkeit steigt, dass sich Ziel-Branch und Feature-Branch zwischenzeitlich auseinanderentwickeln. Ein zusaetzlicher praktischer Vorteil ist, dass Merge-Request-Pipelines im Merge-Request-Interface direkt sichtbar sind, inklusive Diff-Annotationen bei fehlgeschlagenen Tests und der Moeglichkeit, das Merge-Widget so zu konfigurieren, dass ein Merge erst erlaubt wird, wenn die Merge-Request-Pipeline erfolgreich war, was bei reinen Branch-Pipelines ohne Zusatzkonfiguration nicht garantiert ist.


test_mr:
  stage: test
  script:
    - vendor/bin/phpunit
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

3. CI_PIPELINE_SOURCE als zentrale Unterscheidung

Technisch unterscheiden sich beide Pipeline-Typen ueber die vordefinierte Variable CI_PIPELINE_SOURCE, die bei einer Branch-Pipeline den Wert push und bei einer Merge-Request-Pipeline den Wert merge_request_event annimmt. Diese Variable ist die zentrale Grundlage fuer alle rules- und workflow:rules-Bedingungen, mit denen sich das Verhalten von Jobs je nach Pipeline-Typ steuern laesst. Zusaetzlich stehen bei Merge-Request-Pipelines weitere Variablen wie CI_MERGE_REQUEST_TARGET_BRANCH_NAME und CI_MERGE_REQUEST_SOURCE_BRANCH_NAME zur Verfuegung, die bei reinen Branch-Pipelines gar nicht gesetzt sind, weil dort schlicht kein Merge Request existiert, auf den sie sich beziehen koennten.

Diese zusaetzlichen Variablen sind praktisch fuer Jobs, die sich unterschiedlich verhalten sollen, je nachdem in welchen Ziel-Branch gemerged werden soll, etwa um bei einem Merge Request Richtung main strengere Test-Anforderungen zu stellen als bei einem Merge Request zwischen zwei Feature-Branches. Wer diese Variablen in einer Branch-Pipeline referenziert, erhaelt schlicht einen leeren Wert, was ein haeufiger Grund fuer unerwartetes Job-Verhalten ist, wenn Teams beide Pipeline-Typen parallel einsetzen, ohne die Unterschiede in der Variablen-Verfuegbarkeit zu beruecksichtigen.

4. Das Problem doppelter Pipelines ohne workflow:rules

Ohne explizite Konfiguration laufen fuer denselben Commit potenziell zwei komplette Pipelines gleichzeitig: eine Branch-Pipeline, weil ein Push stattgefunden hat, und eine Merge-Request-Pipeline, weil fuer diesen Branch bereits ein offener Merge Request existiert. Beide Pipelines fuehren im Wesentlichen dieselben Jobs aus, verdoppeln damit den CI-Minuten-Verbrauch und ueberladen sowohl die Commit-Ansicht als auch die Merge-Request-Ansicht mit zwei parallelen, oft leicht unterschiedlichen Status-Icons, was bei Entwicklern regelmaessig zu Verwirrung fuehrt, welcher der beiden Status eigentlich massgeblich ist.

Dieses Verhalten ist kein Fehler, sondern die logische Konsequenz daraus, dass GitLab beide Pipeline-Typen unabhaengig voneinander ausloest, sofern nichts anderes konfiguriert ist. Fuer Projekte, die noch keine Merge-Request-Pipelines nutzen, faellt das Problem nicht auf, aber sobald ein Team von reinen Branch-Pipelines auf Merge-Request-Pipelines umstellt, ohne gleichzeitig die Branch-Pipeline fuer Branches mit offenem Merge Request zu unterdruecken, verdoppelt sich der CI-Ressourcenverbrauch faktisch ueber Nacht, oft unbemerkt, bis jemand die CI-Minuten-Abrechnung genauer pruft.

5. workflow:rules als saubere Loesung

Die von GitLab empfohlene Loesung ist eine workflow:rules-Konfiguration auf oberster Ebene der .gitlab-ci.yml, die festlegt, unter welchen Bedingungen ueberhaupt eine Pipeline gestartet wird, bevor einzelne Job-Regeln ausgewertet werden. Das gaengige Muster besagt: Wenn ein Merge Request fuer den aktuellen Branch existiert, soll ausschliesslich die Merge-Request-Pipeline laufen und die Branch-Pipeline unterdrueckt werden; existiert kein Merge Request, etwa bei einem frischen Feature-Branch ohne geoeffneten Merge Request, soll die Branch-Pipeline weiterhin normal laufen, damit Entwickler auch ohne Merge Request sofortiges Feedback zu ihrem Push bekommen.

Diese Logik laesst sich mit einer Kombination aus $CI_PIPELINE_SOURCE und der Variable $CI_OPEN_MERGE_REQUESTS oder direkter mit einer Regel-Reihenfolge abbilden, die Merge-Request-Events zuerst zulaesst und Branch-Pushes nur dann, wenn kein passender Merge Request existiert. GitLab bietet dafuer inzwischen auch eine vorkonfigurierte Vorlage namens Workflows/MergeRequest-Pipelines, die per include eingebunden werden kann und genau dieses empfohlene Muster fertig implementiert, sodass Teams nicht jedes Mal die exakte Bedingungslogik von Grund auf neu schreiben muessen.


workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
    - if: '$CI_COMMIT_TAG'
    - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
      when: never
    - if: '$CI_COMMIT_BRANCH'

6. Merge-Widget und Pipeline-Erfolgs-Anforderungen

Ein wichtiger praktischer Vorteil von Merge-Request-Pipelines ist ihre enge Integration mit dem Merge-Widget im Merge Request selbst. In den Projekteinstellungen unter Merge requests laesst sich die Option Pipelines must succeed aktivieren, die einen Merge erst erlaubt, wenn die zugehoerige Merge-Request-Pipeline erfolgreich durchgelaufen ist. Diese Kopplung funktioniert zuverlaessig nur mit echten Merge-Request-Pipelines, weil GitLab bei reinen Branch-Pipelines nicht immer eindeutig zuordnen kann, welcher Pipeline-Lauf tatsaechlich fuer den aktuellen Merge-Request-Zustand massgeblich ist, insbesondere wenn zwischen dem letzten Push und dem Merge-Versuch Zeit vergangen ist.

Zusaetzlich lassen sich mit Merge-Request-Pipelines auch Approval-Regeln kombinieren, etwa dass ein Merge Request erst gemerged werden darf, wenn sowohl die Pipeline erfolgreich war als auch eine bestimmte Anzahl an Code-Owner-Genehmigungen vorliegt. Diese Kombination aus technischer Absicherung durch die Pipeline und menschlicher Absicherung durch Reviewer ist in Teams mit strengen Qualitaetsanforderungen, etwa bei sicherheitskritischer Software oder bei Projekten mit vielen gleichzeitig arbeitenden Contributor, ein zentraler Baustein, um zu verhindern, dass fehlerhafter Code ungeprueft in den Ziel-Branch gelangt.

7. Performance-Aspekt: Merge-Ref-Berechnung und Caching

Ein oft uebersehener Aspekt ist, dass die Berechnung des simulierten Merge-Ref fuer eine Merge-Request-Pipeline zusaetzlichen Overhead gegenueber einer reinen Branch-Pipeline bedeutet, weil GitLab vor dem eigentlichen Pipeline-Start pruefen muss, ob Feature-Branch und Ziel-Branch konfliktfrei zusammengefuehrt werden koennen. Bei den meisten Projekten ist dieser Overhead vernachlaessigbar gering, kann aber bei sehr grossen Repositories mit langer Historie und haeufigen Merge-Konflikten spuerbar werden, insbesondere wenn viele Merge Requests gleichzeitig gegen denselben, sich schnell aendernden Ziel-Branch getestet werden.

Fuer Caching-Strategien ist ausserdem relevant, dass eine Merge-Request-Pipeline typischerweise einen anderen Cache-Key-Kontext hat als eine Branch-Pipeline, weil sich der zugrunde liegende simulierte Commit bei jedem Update des Ziel-Branches technisch aendert, auch wenn der Feature-Branch selbst unveraendert bleibt. Teams, die aggressive Caching-Strategien mit dem Ziel-Branch-Namen im Cache-Key verwenden, sollten das beruecksichtigen, um zu vermeiden, dass ein Cache staendig neu aufgebaut wird, obwohl sich der fuer den Cache relevante Code gar nicht geaendert hat.

8. Wann reine Branch-Pipelines ausreichen

Nicht jedes Projekt braucht zwingend Merge-Request-Pipelines. Bei kleinen internen Tools, bei Projekten mit sehr niedriger Commit-Frequenz auf dem Ziel-Branch oder bei Solo-Entwicklern ohne Review-Prozess ist der Zusatznutzen der Merge-Ergebnis-Simulation gering, weil sich Feature-Branch und Ziel-Branch selten so weit auseinanderentwickeln, dass ein reiner Branch-Test die Realitaet nicht mehr widerspiegelt. In solchen Faellen reicht eine einfache Branch-Pipeline-Konfiguration oft aus und vermeidet die zusaetzliche Komplexitaet von workflow:rules und Merge-Request-spezifischen Variablen.

Anders sieht es bei Teams mit mehreren aktiven Contributor und einem Ziel-Branch aus, der mehrfach taeglich aktualisiert wird, etwa durch andere parallel gemergte Merge Requests. Dort steigt die Wahrscheinlichkeit, dass ein Feature-Branch zum Zeitpunkt seines letzten Pushes zwar problemlos funktioniert, nach dem tatsaechlichen Merge aber durch zwischenzeitliche Aenderungen am Ziel-Branch bricht, deutlich, und genau dieses Szenario ist der Hauptgrund, warum sich Merge-Request-Pipelines in aktiven Teams langfristig durchsetzen, trotz des zusaetzlichen Konfigurationsaufwands mit workflow:rules.

9. Fazit: Zwei Pipeline-Typen fuer zwei unterschiedliche Fragen

Branch-Pipelines und Merge-Request-Pipelines beantworten unterschiedliche Fragen, die beide ihre Berechtigung haben: Funktioniert der Code so, wie er im Branch steht, gegenueber Funktioniert der Code so, wie er nach dem Merge aussehen wuerde. Fuer Teams mit aktivem Merge-Request-Workflow und mehreren Contributor ist die Kombination aus Merge-Request-Pipelines und einer sauberen workflow:rules-Konfiguration, die doppelte Branch-Pipelines unterdrueckt, der empfohlene Standardansatz, weil er sowohl realistischere Tests als auch geringeren CI-Ressourcenverbrauch liefert.

Die folgende Tabelle stellt beide Pipeline-Typen entlang der wichtigsten praktischen Kriterien gegenueber, als schnelle Referenz fuer die eigene Konfigurationsentscheidung.

Kriterium Branch-Pipeline Merge-Request-Pipeline Praxis-Hinweis
Getesteter Zustand reiner Push-Zustand des Branches simulierter Merge-Commit mit Ziel-Branch MR-Pipeline naeher an der Realitaet nach Merge
CI_PIPELINE_SOURCE push merge_request_event Basis fuer rules-Unterscheidung
Merge-Widget-Integration eingeschraenkt vollstaendig, inkl. Pipelines-must-succeed fuer verbindliche Qualitaetschecks MR-Pipeline nutzen
Ohne Konfiguration bei offenem MR laeuft zusaetzlich, oft ungewollt laeuft zusaetzlich, oft ungewollt workflow:rules zur Vermeidung doppelter Laeufe einsetzen
Verfuegbare Variablen CI_COMMIT_BRANCH etc. zusaetzlich CI_MERGE_REQUEST_* Variablen fuer ziel-branch-abhaengige Logik MR-Variablen nutzen

Mironsoft

CI/CD-Pipelines, Zero-Downtime-Deployments und Release-Automatisierung

Deployments, die ohne Ausfallzeit und ohne Nervenkitzel laufen?

Wir prüfen bestehende GitLab-Pipelines auf fragile Deployment-Schritte und fehlende Absicherung und bauen daraus einen Release-Prozess mit Zero-Downtime-Deployments, automatisierten Checks und einem Rollback, dem ihr im Ernstfall vertrauen könnt.

Pipeline-Review

Bestehende .gitlab-ci.yml auf Fragilität, fehlende Stages und Sicherheitslücken prüfen.

Zero-Downtime-Deployment

Symlink-Releases, Health-Checks und Rollback-Strategien für Magento-Shops aufbauen.

CI/CD-Automatisierung

Tests, Security-Scans und Deployments zu einer zuverlässigen Pipeline verbinden.

10. Zusammenfassung

MR-Pipelines vs. Branch-Pipelines: Das Wichtigste auf einen Blick

Branch-Pipeline testet

Den reinen Push-Zustand eines Branches, unabhaengig davon, ob und wohin spaeter gemerged wird.

Merge-Request-Pipeline testet

Einen simulierten Merge-Commit aus Feature-Branch und aktuellem Ziel-Branch-Stand.

Doppelte Pipelines vermeiden

workflow:rules auf oberster Ebene unterdrueckt Branch-Pipelines, sobald ein offener Merge Request existiert.

Merge-Widget-Vorteil

Nur Merge-Request-Pipelines lassen sich zuverlaessig mit Pipelines-must-succeed und Approval-Regeln koppeln.

11. FAQ: MR-Pipelines vs. Branch-Pipelines: Das Wichtigste auf einen Blick

1Was ist der grundlegende Unterschied zwischen Branch- und Merge-Request-Pipeline?
Eine Branch-Pipeline testet den Code genau so, wie er im Branch nach dem Push vorliegt. Eine Merge-Request-Pipeline testet stattdessen einen simulierten Merge-Commit, der den Feature-Branch mit dem aktuellen Stand des Ziel-Branches zusammenfuehrt, und bildet damit den erwarteten Zustand nach dem Merge ab.
2Warum laufen bei mir zwei Pipelines fuer denselben Commit?
Das passiert, wenn sowohl ein Push auf den Branch als auch ein offener Merge Request fuer diesen Branch vorliegt, ohne dass workflow:rules konfiguriert ist. GitLab startet dann standardmaessig sowohl die Branch-Pipeline als auch die Merge-Request-Pipeline.
3Wie unterscheide ich beide Pipeline-Typen in rules-Bedingungen?
Ueber die Variable CI_PIPELINE_SOURCE, die bei Branch-Pipelines den Wert push und bei Merge-Request-Pipelines den Wert merge_request_event annimmt. Diese Variable ist die zentrale Grundlage fuer entsprechende if-Bedingungen in rules und workflow:rules.
4Welche zusaetzlichen Variablen gibt es nur bei Merge-Request-Pipelines?
Unter anderem CI_MERGE_REQUEST_TARGET_BRANCH_NAME und CI_MERGE_REQUEST_SOURCE_BRANCH_NAME, die den Ziel- und Quell-Branch des Merge Requests angeben. Diese Variablen sind bei reinen Branch-Pipelines nicht gesetzt, weil dort kein Merge Request existiert.
5Wie vermeide ich doppelte Pipelines zuverlaessig?
Mit einer workflow:rules-Konfiguration auf oberster Ebene der .gitlab-ci.yml, die Merge-Request-Events erlaubt und Branch-Pushes unterdrueckt, sobald fuer denselben Branch bereits ein offener Merge Request existiert. GitLab bietet dafuer auch eine fertige Vorlage zum Einbinden.
6Kann ich Pipelines must succeed auch mit reinen Branch-Pipelines nutzen?
Technisch teilweise, aber die Zuordnung ist bei reinen Branch-Pipelines weniger zuverlaessig, weil GitLab nicht immer eindeutig bestimmen kann, welcher Pipeline-Lauf fuer den aktuellen Merge-Request-Zustand massgeblich ist. Fuer verbindliche Qualitaetschecks werden deshalb Merge-Request-Pipelines empfohlen.
7Verursacht die Merge-Ref-Berechnung spuerbaren Overhead?
Bei den meisten Projekten ist der Overhead vernachlaessigbar. Bei sehr grossen Repositories mit haeufigen Merge-Konflikten und vielen parallel laufenden Merge Requests kann die Berechnung des simulierten Merge-Ref jedoch spuerbar werden.
8Brauche ich fuer kleine Projekte unbedingt Merge-Request-Pipelines?
Nein, bei kleinen Projekten mit niedriger Commit-Frequenz auf dem Ziel-Branch oder ohne aktiven Review-Prozess ist der Zusatznutzen gering. Eine einfache Branch-Pipeline-Konfiguration reicht dort oft vollstaendig aus.
9Beeinflusst der Pipeline-Typ das Caching-Verhalten?
Ja, eine Merge-Request-Pipeline hat durch den simulierten Merge-Commit einen anderen Cache-Kontext als eine Branch-Pipeline. Bei aggressiven Caching-Strategien mit Ziel-Branch-Namen im Cache-Key sollte das beruecksichtigt werden, um unnoetige Cache-Neuerstellung zu vermeiden.
10Gibt es eine fertige GitLab-Vorlage fuer das empfohlene workflow:rules-Muster?
Ja, GitLab stellt eine Vorlage namens Workflows/MergeRequest-Pipelines bereit, die per include eingebunden werden kann und das empfohlene Muster zur Vermeidung doppelter Pipelines bereits fertig implementiert.