Git Versionierung: Grundlagen, Branches, Merge Conflicts & Workflows
Git ist das weltweit führende verteilte Versionierungssystem für Softwareentwicklung. Es ermöglicht effiziente Kollaboration, Nachverfolgung von Änderungen und sichere Code-Verwaltung.
Git Grundlagen
Was ist Git?
Git ist ein verteiltes Versionierungssystem (Distributed Version Control System - DVCS), das entwickelt wurde, um die Zusammenarbeit an Softwareprojekten zu vereinfachen.
Kernkonzepte
# Git Repository initialisieren
git init
# Repository klonen
git clone https://github.com/user/repository.git
# Status anzeigen
git status
# Änderungen hinzufügen
git add datei.txt
git add .
# Änderungen committen
git commit -m "Beschreibung der Änderung"
# Änderungen pushen
git push origin main
# Änderungen pullen
git pull origin main
Git Architektur
# Arbeitsbereiche in Git
# Working Directory → Staging Area → Local Repository → Remote Repository
# Working Directory (Arbeitsverzeichnis)
echo "Neuer Inhalt" > datei.txt
# Staging Area (Index)
git add datei.txt
# Local Repository (lokales Repository)
git commit -m "Änderung committen"
# Remote Repository (entferntes Repository)
git push origin main
Git Konfiguration
Initiale Konfiguration
# Benutzername und Email konfigurieren
git config --global user.name "Max Mustermann"
git config --global user.email "max@example.com"
# Standard-Editor festlegen
git config --global core.editor "vim"
# Standard-Branch-Namen (main statt master)
git config --global init.defaultBranch main
# Konfiguration anzeigen
git config --list
# Spezielle Konfiguration für ein Repository
git config user.email "work@example.com"
Git Aliase
# Nützliche Aliase erstellen
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
# Aliases verwenden
git st # git status
git co main # git checkout main
git br # git branch
git ci -m "Nachricht" # git commit -m "Nachricht"
Branches in Git
Grundlagen von Branches
Branches ermöglichen parallele Entwicklung an verschiedenen Features ohne den Hauptcode zu beeinflussen.
# Neuen Branch erstellen
git branch feature-login
# Zu Branch wechseln
git checkout feature-login
# Branch erstellen und wechseln (kombiniert)
git checkout -b feature-login
# Alle Branches anzeigen
git branch
git branch -a # inklusive Remote-Branches
# Branch löschen
git branch -d feature-login # nur wenn gemerged
git branch -D feature-login # erzwingen
# Remote-Branch löschen
git push origin --delete feature-login
Branch-Strategien
# Feature Branch Workflow
# 1. Von main aus neuen Feature-Branch erstellen
git checkout main
git pull origin main
git checkout -b feature-user-authentication
# 2. Am Feature arbeiten
git add .
git commit -m "Implement user authentication"
git push origin feature-user-authentication
# 3. Pull Request erstellen und mergen
# 4. Branch nach Merge löschen
git checkout main
git pull origin main
git branch -d feature-user-authentication
Branch-Management
# Branches vergleichen
git diff main feature-branch
git log main..feature-branch
# Branch zusammenführen (merge)
git checkout main
git merge feature-branch
# Branch zusammenführen (rebase)
git checkout feature-branch
git rebase main
# Cherry-pick (spezifische Commits übernehmen)
git checkout main
git cherry-pick <commit-hash>
# Stash (temporäre Änderungen speichern)
git stash
git stash list
git stash pop
git stash apply
git stash drop
Merge Conflicts
Was sind Merge Conflicts?
Merge Conflicts entstehen, wenn Git automatisch nicht entscheiden kann, welche Version einer Datei übernommen werden soll.
Typische Conflict-Situationen
# Beispiel: Zwei Entwickler ändern dieselbe Zeile
# Entwickler A (Branch feature-a)
echo "console.log('Hello from Feature A');" > app.js
git add app.js
git commit -m "Add feature A logging"
# Entwickler B (Branch main)
echo "console.log('Hello from Main');" > app.js
git add app.js
git commit -m "Add main logging"
# Merge-Versuch
git checkout main
git merge feature-a
# CONFLICT: Merge conflict in app.js
Conflict-Behebung
# 1. Conflict anzeigen
git status
# 2. Datei öffnen und bearbeiten
# Git markiert Conflicts mit <<<<<<<, =======, >>>>>>>
# app.js nach Conflict:
# <<<<<<< HEAD
# console.log('Hello from Main');
# =======
# console.log('Hello from Feature A');
# >>>>>>> feature-a
# 3. Manuell lösen
# console.log('Hello from Main and Feature A');
# 4. Datei speichern und als gelöst markieren
git add app.js
git commit -m "Resolve merge conflict in app.js"
# Alternative: Merge abbrechen
git merge --abort
Fortgeschrittene Conflict-Lösung
# Merge Tools verwenden
git mergetool
# Konflikt-Strategien festlegen
git merge -X theirs feature-branch # ihre Version bevorzugen
git merge -X ours feature-branch # unsere Version bevorzugen
# Octopus Merge (mehrere Branches gleichzeitig)
git merge branch1 branch2 branch3
# Subtree Merge (externes Projekt einbinden)
git subtree add --prefix=external-repo https://github.com/user/repo.git main
Git Workflows
1. Centralized Workflow
# Einfachster Workflow
# Alle arbeiten direkt auf main
# 1. Lokale Änderungen
git add .
git commit -m "Add new feature"
# 2. Änderungen hochladen
git push origin main
# 3. Konflikte lösen (falls vorhanden)
git pull origin main
# Konflikte lösen
git push origin main
2. Feature Branch Workflow
# Jedes Feature bekommt eigenen Branch
# 1. Feature-Branch erstellen
git checkout main
git pull origin main
git checkout -b feature-user-profile
# 2. Am Feature arbeiten
git add .
git commit -m "Add user profile page"
git push origin feature-user-profile
# 3. Pull Request erstellen
# Über GitHub/GitLab UI oder CLI
# 4. Review und Merge
# Code Review durch Teammitglieder
# Merge in main nach Genehmigung
# 5. Branch aufräumen
git checkout main
git pull origin main
git branch -d feature-user-profile
3. Gitflow Workflow
# Gitflow mit main, develop, feature, release, hotfix branches
# 1. Develop-Branch initialisieren
git checkout main
git checkout -b develop
git push origin develop
# 2. Feature-Branch von develop
git checkout develop
git checkout -b feature-shopping-cart
# 3. Feature in develop mergen
git checkout develop
git merge feature-shopping-cart
git push origin develop
# 4. Release-Branch erstellen
git checkout develop
git checkout -b release/v1.0.0
# 5. Release in main und develop mergen
git checkout main
git merge release/v1.0.0
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin main --tags
git checkout develop
git merge release/v1.0.0
git push origin develop
# 6. Hotfix von main
git checkout main
git checkout -b hotfix/critical-bug
# Bug fixen
git checkout main
git merge hotfix/critical-bug
git checkout develop
git merge hotfix/critical-bug
4. Forking Workflow
# Für Open Source Projekte oder externe Beiträge
# 1. Repository forken (über GitHub/GitLab UI)
# 2. Eigenes Repository klonen
git clone https://github.com/yourusername/project.git
cd project
# 3. Upstream Remote hinzufügen
git remote add upstream https://github.com/original/project.git
# 4. Feature-Branch erstellen
git checkout -b feature-new-functionality
# 5. Änderungen committen
git add .
git commit -m "Add new functionality"
# 6. Push zum eigenen Repository
git push origin feature-new-functionality
# 7. Pull Request zum Original-Repository
# 8. Regelmäßig Upstream aktualisieren
git fetch upstream
git checkout main
git merge upstream/main
Fortgeschrittene Git-Techniken
Rebase und Interactive Rebase
# Einfacher Rebase
git checkout feature-branch
git rebase main
# Interactive Rebase (Commits umsortieren/bearbeiten)
git rebase -i HEAD~3
# Interactive Rebase Optionen:
# pick: Commit unverändert übernehmen
# reword: Commit-Nachricht ändern
# edit: Commit bearbeiten
# squash: Mit vorherigem Commit zusammenführen
# fixup: Mit vorherigem Commit zusammenführen (ohne Nachricht)
# drop: Commit entfernen
# Beispiel für Interactive Rebase
# pick 1234567 Add feature A
# squash 2345678 Add feature B
# reword 3456789 Fix typo
# Rebase erzwingen (Vorsicht!)
git push --force-with-lease origin feature-branch
Git Hooks
# Hooks in .git/hooks/
# Pre-commit Hook (vor jedem Commit)
#!/bin/sh
# .git/hooks/pre-commit
echo "Running pre-commit checks..."
npm run lint
npm run test
# Pre-push Hook (vor jedem Push)
#!/bin/sh
# .git/hooks/pre-push
echo "Running pre-push tests..."
npm run test:coverage
# Hooks aktivieren (machen)
chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/pre-push
# Hooks global einrichten
git config --global init.templatedir '~/.git-templates'
Git Submodules
# Submodule hinzufügen
git submodule add https://github.com/user/library.git libs/library
# Submodule initialisieren
git submodule init
git submodule update
# Submodule klonen mit --recurse-submodules
git clone --recurse-submodules https://github.com/user/project.git
# Submodule aktualisieren
git submodule update --remote
# Submodule entfernen
git rm --cached libs/library
rm -rf libs/library
git commit -m "Remove submodule"
Best Practices
Commit-Nachrichten
# Gute Commit-Nachrichten
feat: Add user authentication system
fix: Resolve memory leak in data processing
docs: Update API documentation
style: Format code according to style guide
refactor: Simplify database connection logic
test: Add unit tests for user service
chore: Update dependencies
# Struktur: <type>(<scope>): <description>
# Types: feat, fix, docs, style, refactor, test, chore
# Detaillierte Commit-Nachricht
feat(auth): Add OAuth2 integration
- Add Google OAuth provider
- Implement token refresh mechanism
- Add user profile synchronization
Closes #123
Branch-Namenskonventionen
# Gute Branch-Namen
feature/user-authentication
bugfix/memory-leak-fix
hotfix/critical-security-patch
release/v1.2.0
docs/update-api-documentation
refactor/database-connection-pool
test/add-unit-tests
# Schlechte Branch-Namen
fix-stuff
new-feature
branch-1
temp
Repository-Struktur
# .gitignore
# Compiled files
*.class
*.jar
*.war
*.ear
# IDE files
.idea/
.vscode/
*.swp
*.swo
# Dependencies
node_modules/
target/
build/
# Logs
*.log
logs/
# Environment files
.env
.env.local
# .gitattributes
# Text files
*.txt text
*.md text
*.js text
*.java text
# Binary files
*.jpg binary
*.png binary
*.pdf binary
# Line endings
* text=auto eol=lf
Fehlerbehebung und Troubleshooting
Häufige Probleme
# 1. Falscher Commit im falschen Branch
git checkout correct-branch
git cherry-pick <wrong-commit-hash>
git checkout wrong-branch
git reset --hard HEAD~1
# 2. Verlorene Commits wiederherstellen
git reflog
git checkout -b recovery <commit-hash>
# 3. Unwanted changes zurücksetzen
git reset --hard HEAD
git reset --hard HEAD~1 # Letzten Commit entfernen
git clean -fd # Untracked files entfernen
# 4. Remote-Repository Probleme
git remote -v
git remote set-url origin https://github.com/user/new-repo.git
# 5. Push nach Force-Push wiederherstellen
git reflog
git reset --hard HEAD@{1}
git push --force-with-lease origin main
Performance-Optimierung
# Repository optimieren
git gc --prune=now
# Große Dateien finden
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2 | tail -10
# Git LFS für große Dateien
git lfs install
git lfs track "*.psd"
git lfs track "*.zip"
git add .gitattributes
git commit -m "Track large files with Git LFS"
Git in der Praxis
CI/CD Integration
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Run linting
run: npm run lint
- name: Build project
run: npm run build
Git für Team-Kollaboration
# Team-Richtlinien
# 1. Feature-Branches verwenden
# 2. Pull Requests für Code Review
# 3. Automatische Tests bei jedem Push
# 4. Protected Branches für main und develop
# 5. Regelmäßige Rebase statt Merge
# Beispiel für protected Branch Setup
# Über GitHub/GitLab:
# - Require pull request reviews before merging
# - Require status checks to pass before merging
# - Require branches to be up to date before merging
# - Include administrators as reviewers
Prüfungsrelevante Konzepte
Wichtige Git-Befehle
| Befehl | Beschreibung | Verwendung |
|---|---|---|
git init | Repository initialisieren | Neues Projekt starten |
git clone | Repository klonen | Bestehendes Projekt kopieren |
git add | Änderungen zum Staging hinzufügen | Änderungen vorbereiten |
git commit | Änderungen committen | Lokale Änderungen speichern |
git push | Änderungen hochladen | Mit Remote synchronisieren |
git pull | Änderungen herunterladen | Remote-Änderungen übernehmen |
git branch | Branches verwalten | Entwicklungslinien erstellen |
git merge | Branches zusammenführen | Änderungen integrieren |
git rebase | Branches umstellen | Lineare Historie erstellen |
Typische Prüfungsaufgaben
- Erklären Sie Git-Workflows
- Lösen Sie Merge Conflicts
- Implementieren Sie Branch-Strategien
- Verwenden Sie fortgeschrittene Git-Befehle
- Richten Sie CI/CD mit Git ein
Zusammenfassung
Git ist unverzichtbar für moderne Softwareentwicklung:
- Verteiltes System: Jeder Entwickler hat vollständige Kopie
- Branches: Parallele Entwicklung ohne Konflikte
- Merge: Intelligente Zusammenführung von Änderungen
- Workflows: Strukturierte Kollaboration im Team
- CI/CD: Automatisierung von Build und Deployment
Gutes Git-Management erfordert Disziplin, klare Regeln und regelmäßige Pflege des Repository.