🧭Workflows

Git schreibt keinen Arbeitsablauf vor – Teams einigen sich darauf. Hier laufen die drei bekanntesten Modelle als echte Befehlsfolgen durch die Simulator-Engine, dazu Remotes, Pull Requests, Releases, .gitignore und gute Commit-Nachrichten.

🗺️Branching-Modelle Schritt für Schritt

🌿 Feature-Branch + Pull Request

Jede Aufgabe bekommt einen eigenen, kurzlebigen Branch vom aktuellen main. Über einen Pull Request (GitLab: Merge Request) wird geprüft und gemergt. main bleibt stets auslieferbar.

  • 👍 einfach zu verstehen
  • 👍 Review und CI vor dem Merge
  • 👍 passt zu GitHub, GitLab, Gitea/Forgejo
  • 👎 lange lebende Branches → große Konflikte
  • 👎 Merge-Commits können die Geschichte unübersichtlich machen
Schritt 1 / 7 · Tasten ← →

Start: ein Repository mit einem Commit auf main (geklont von origin).

b8aa7c5bd3d4f17c042133eb7b55291b0e608ab1 Initialer Commit (Alice)b8aa7c5Initialer Com…HEAD → mainorigin/main

☁️Remotes und Tracking-Branches

Ein Remote ist nur ein Name für eine URL. Git merkt sich lokal, wo die Branches dort beim letzten Kontakt standen: die Remote-Tracking-Branches origin/….
  Server (origin)            Dein Rechner
 ┌─────────────────┐        ┌────────────────────────────────────┐
 │ main ─▶ C4      │─fetch─▶│ origin/main ─▶ C4  (nur lesen)     │
 │                 │        │      │ merge / rebase (pull)       │
 │                 │        │      ▼                             │
 │                 │◀─push──│ main ─▶ C5         (dein Branch)   │
 └─────────────────┘        └────────────────────────────────────┘
  git pull  =  git fetch  +  git merge origin/main   (oder --rebase)

git fetch lädt neue Commits und bewegt nur origin/* – dein Branch bleibt, wo er ist. Gefahrlos, jederzeit.

git pull = fetch + Zusammenführen mit dem Upstream. Laufen beide Seiten auseinander, verlangt aktuelles Git eine Entscheidung: --rebase, --no-rebase (Merge) oder --ff-only – dauerhaft per git config pull.rebase.

git push klappt nur als Fast-Forward. Sonst: erst holen und integrieren. --force-with-lease überschreibt nur, wenn der Server noch auf dem Stand ist, den du zuletzt gesehen hast.

git branch -vv zeigt Upstream und „ahead/behind“.

b8aa7c5bd3d4f17c042133eb7b55291b0e608ab1 Initialer Commit (Alice)b8aa7c5Initialer Com…origin/maineec6f8d3be11a7b09f1e499b8bb1dcfc6688aa14 Meine Idee (Alice)eec6f8dMeine IdeeHEAD → main
alice@laptop: ~/projekt
💡 Du hast einen lokalen Commit. Lass mit „kollege“ Bob etwas pushen, dann: git push (abgelehnt) → git fetch → git status → git pull --rebase → git push.
main $

🔁Pull Requests

1. git switch -c feature/x         Branch anlegen
2. commit, commit, commit          arbeiten
3. git push -u origin feature/x    hochladen
4. Pull Request eröffnen           auf der Plattform (Web)
5. Review ◀──▶ neue Commits        Diskussion, Änderungen
   CI: Tests, Linter ✅
6. Merge in main                   Merge-Commit | Squash | Rebase
7. Branch löschen                  lokal + auf dem Server
💡 PRs sind keine Git-Funktion
Pull Requests (GitLab: „Merge Requests“) sind eine Funktion der Hosting-Plattformen wie GitHub, GitLab oder Gitea/Forgejo. Git selbst kennt nur Branches, Commits und Remotes – und git request-pull, das eine Zusammenfassung für eine E-Mail erzeugt.
✅ Drei Arten zu mergen
Merge-Commit bewahrt alle Commits und die Verzweigung. Squash fasst den Branch zu einem einzigen neuen Commit zusammen. Rebase setzt die Commits linear auf main (neue IDs). Welche Variante, entscheidet das Team.

🏷Tags und Releases

Leichtgewichtig vs. annotiert

git tag v1.0.0 legt nur eine Referenz an. git tag -a v1.0.0 -m "…" erzeugt ein eigenes Tag-Objekt mit Autor, Datum und Nachricht (mit -s signiert). Für Releases: annotiert.

Tags pushen

git push überträgt Tags nicht automatisch. Einzeln: git push origin v1.0.0, alle: git push --tags, nur annotierte erreichbare: git push --follow-tags.

Semantic Versioning

MAJOR.MINOR.PATCH: MAJOR bei inkompatiblen Änderungen, MINOR bei neuen, kompatiblen Funktionen, PATCH bei Fehlerbehebungen (semver.org). git describe nennt z. B. v1.0.0-3-g4ac0b51 = 3 Commits nach v1.0.0.

🙈.gitignore-Tester

Welche Datei wird ignoriert – und durch welche Regel? Der Matcher folgt der Dokumentation (git-scm.com/docs/gitignore) und wurde gegen git check-ignore getestet.

11 Regeln erkannt. Leerzeilen und #-Kommentare zählen nicht.

Ergebnis
  • 🙈node_modules/react/index.jsignoriert
    .gitignore:2:node_modules/ – Elternordner „node_modules/“ ist ausgeschlossen, Wiedereinschluss unmöglich
  • 🙈src/node_modules/x.jsignoriert
    .gitignore:2:node_modules/ – Elternordner „src/node_modules/“ ist ausgeschlossen, Wiedereinschluss unmöglich
  • 🙈dist/app.jsignoriert
    .gitignore:3:/dist – Elternordner „dist/“ ist ausgeschlossen, Wiedereinschluss unmöglich
  • 👀src/dist/app.jsversioniert
  • 🙈fehler.logignoriert
    .gitignore:4:*.log
  • 👀wichtig.logversioniert
    .gitignore:5:!wichtig.log – durch ! wieder eingeschlossen
  • 🙈logs/behalten.txtignoriert
    .gitignore:6:logs/ – Elternordner „logs/“ ist ausgeschlossen, Wiedereinschluss unmöglich
  • 👀tmp/.gitkeepversioniert
    .gitignore:9:!tmp/.gitkeep – durch ! wieder eingeschlossen
  • 🙈tmp/x.binignoriert
    .gitignore:8:tmp/*
  • 🙈docs/handbuch/v1/anleitung.pdfignoriert
    .gitignore:10:docs/**/*.pdf
  • 🙈a/b/cache/daten.binignoriert
    .gitignore:11:**/cache – Elternordner „a/b/cache/“ ist ausgeschlossen, Wiedereinschluss unmöglich
  • 🙈.env.localignoriert
    .gitignore:12:.env*
  • 👀src/app.tsversioniert
  • 👀build/versioniert
💡 Die wichtigsten Regeln
Ohne / gilt ein Muster in jeder Tiefe (*.log). Ein / am Anfang oder in der Mitte verankert es relativ zur .gitignore (/dist, docs/*.pdf). Ein / am Ende trifft nur Verzeichnisse.** steht für beliebig viele Verzeichnisse. Die letzte passende Regel gewinnt.
⚠️ Schon versioniert? Dann hilft .gitignore nicht
.gitignore wirkt nur auf unversionierte Dateien. Eine bereits committete Datei muss erst aus dem Index: git rm --cached datei. Und: Ist ein Ordner ausgeschlossen (logs/), kann !logs/x nichts darin zurückholen – dafür logs/* schreiben.

✍️Commit-Nachrichten und Conventional Commits

Eine gute Nachricht erklärt, was und warum – für die Kolleginnen in einem Jahr. Conventional Commits (conventionalcommits.org) macht daraus ein maschinenlesbares Format, aus dem sich Versionsnummern und Changelogs ableiten lassen.
<typ>[(bereich)][!]: <beschreibung>

[optionaler Text, umbrochen bei 72 Zeichen]

[optionale Fußzeilen, z. B. BREAKING CHANGE: …]
Typ: featBereich: loginSemVer: MINOR
  • ✅ Typ feat: neue Funktion (→ MINOR)
  • ✅ Betreff: 46 Zeichen
Übliche Typen
feat neue Funktion (→ MINOR)
fix Fehlerbehebung (→ PATCH)
docs nur Dokumentation
style Formatierung, keine Logikänderung
refactor Umbau ohne neue Funktion/Fehlerbehebung
perf Performance
test Tests
build Build-System, Abhängigkeiten
ci CI-Konfiguration
chore Sonstiges/Wartung
revert Rückgängigmachen eines Commits

Quellen: Pro Git 3.4 „Branching-Workflows“, 3.5 „Remote-Branches“, 2.6 „Taggen“, 5 „Verteiltes Git“ (git-scm.com/book/de/v2); nvie.com „A successful Git branching model“ (2010, Nachtrag 2020); trunkbaseddevelopment.com; conventionalcommits.org 1.0.0; semver.org; git-scm.com/docs/gitignore, git-pull, git-push.