diff --git a/git/README.md b/git/README.md index 3c5f1d4..d57efc8 100644 --- a/git/README.md +++ b/git/README.md @@ -773,25 +773,119 @@ git rm -r --cached verzeichnis/ ### Pull und Fetch +#### Zusammenspiel von Fetch, Pull, Merge und Rebase + +**Grundprinzip:** + +``` +git pull = git fetch + git merge +git pull --rebase = git fetch + git rebase +``` + +**Was passiert im Detail:** + +1. **`git fetch`** - Holt Änderungen vom Remote, **ohne** sie zu integrieren + - Lädt neue Commits vom Remote-Repository herunter + - Aktualisiert Remote-Tracking-Branches (z.B. `origin/main`) + - Ändert **nichts** am lokalen Branch oder Working Directory + - Sicher - kann nichts kaputt machen + +2. **`git pull`** - Holt Änderungen **und** merged sie automatisch + - Führt intern `git fetch` aus + - Merged dann automatisch `origin/main` in lokalen `main` + - Erstellt Merge-Commit bei divergierenden Histories + - Kann zu Merge-Konflikten führen + +3. **`git pull --rebase`** - Holt Änderungen **und** rebaset darauf + - Führt intern `git fetch` aus + - Setzt lokale Commits **auf top** der neuen Remote-Commits + - Keine Merge-Commits → saubere, lineare History + - Empfohlen für Feature-Branches + +**Visueller Vergleich:** + +``` +# Ausgangssituation: Lokale und Remote-Commits divergieren + C (origin/main) + / +A - B + \ + D (main, lokal) + +# Nach git pull (merge): + C (origin/main) + / \ +A - B E (main, Merge-Commit) + \ / + D + +# Nach git pull --rebase: +A - B - C (origin/main) - D' (main, rebasiert) +``` + +#### Befehle im Detail + ```bash -# Änderungen holen und mergen +# Fetch: Nur Änderungen holen (ohne zu integrieren) +git fetch +git fetch origin + +# Jetzt lokal prüfen was sich geändert hat: +git log origin/main # Remote-Commits anschauen +git diff main origin/main # Unterschiede vergleichen + +# Dann entscheiden: Merge oder Rebase? +git merge origin/main # Merge-Variante +# oder +git rebase origin/main # Rebase-Variante + +# Pull: Änderungen holen und mergen (automatisch) git pull # Von spezifischem Remote und Branch git pull origin main -# Fetch: Nur Änderungen holen (ohne zu mergen) -git fetch -git fetch origin - -# Mit Rebase statt Merge +# Mit Rebase statt Merge (empfohlen für saubere History) git pull --rebase +git pull --rebase origin main # Alle Remotes fetchen git fetch --all # Remote-Branches prunen (gelöschte entfernen) git fetch --prune + +# Fetch und prune in einem +git fetch --all --prune +``` + +#### Wann was verwenden? + +| Szenario | Empfohlener Befehl | Begründung | +|----------|-------------------|------------| +| Erstmal schauen was sich geändert hat | `git fetch` | Kein Risiko, nur Download | +| Main/Master aktualisieren | `git pull` | Standard, Merge ist OK | +| Feature-Branch aktualisieren | `git pull --rebase` | Saubere lineare History | +| Unsicher bei Konflikten | `git fetch` + manuell merge/rebase | Mehr Kontrolle | +| Shared Branch (mehrere Entwickler) | `git pull` | Merge preserviert alle Histories | +| Privater Branch | `git pull --rebase` | History-Cleanup möglich | + +**Best Practice - Der sichere Weg:** + +```bash +# 1. Erstmal nur fetchen (kein Risiko) +git fetch origin + +# 2. Prüfen was sich geändert hat +git log HEAD..origin/main --oneline + +# 3. Unterschiede anschauen +git diff HEAD origin/main + +# 4. Dann bewusst entscheiden +git merge origin/main +# oder +git rebase origin/main ``` ### Push