# Der Unterschied zwischen git fetch und git pull 🔄

Beide Befehle holen Daten von einem Remote-Repository (z. B. GitHub), aber sie tun es auf **sehr unterschiedliche Weise**. Das zu verstehen hilft dir, in verschiedenen Situationen die richtige Entscheidung zu treffen – und verhindert unerwartete Überraschungen in deinem Code.

---

## Das Grundprinzip

Um den Unterschied zu verstehen, ist es wichtig zu wissen, dass Git zwei Dinge getrennt voneinander betrachtet:

1. **Die Informationen über den Zustand des Remote-Repositories** – also welche Commits dort existieren
2. **Den tatsächlichen Zustand deiner lokalen Arbeitsdateien** – also dein Working Directory und dein lokaler Branch

```mermaid
flowchart TB
    subgraph Remote ["☁️ GitHub"]
        RC["Remote Commits"]
    end
    
    subgraph Lokal ["💻 Dein Computer"]
        TRACK["Remote-Tracking Branch\n(origin/main)"]
        LOCAL["Lokaler Branch\n(main)"]
        WD["Working Directory\nDeine Dateien"]
    end
    
    RC -->|git fetch| TRACK
    TRACK -->|git merge| LOCAL
    LOCAL --> WD
    RC -->|git pull| TRACK
    RC -->|git pull| LOCAL
    RC -->|git pull| WD
```

---

## `git fetch` – nur informieren, nichts verändern

Mit `git fetch` holst du dir die **neuesten Informationen** vom Remote-Repository, aber deine lokalen Branches und Dateien bleiben **komplett unverändert**. Git aktualisiert lediglich die sogenannten *Remote-Tracking-Branches* (z. B. `origin/main`), die wie ein Spiegel des Remote-Zustands funktionieren.

**Was passiert konkret?**

- Git verbindet sich mit GitHub und schaut nach, welche neuen Commits es dort gibt
- Diese Informationen werden heruntergeladen und in `origin/main` (oder entsprechend `origin/<branchname>`) gespeichert
- Dein lokaler `main`-Branch und deine Arbeitsdateien bleiben **unangetastet**

**Typische Ausgabe nach `git fetch`:**

```
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
From github.com:username/projekt
   a1b2c3d..e4f5g6h  main     -> origin/main
```

Das sagt dir: „Es gibt neue Commits auf GitHub, ich habe sie in `origin/main` gespeichert, aber dein lokaler `main` ist noch auf dem alten Stand."

---

## `git pull` – informieren *und* integrieren

`git pull` ist im Grunde **zwei Befehle in einem**:

$$
\texttt{git pull} = \texttt{git fetch} + \texttt{git merge}
$$

Es holt also nicht nur die Informationen, sondern **führt die Änderungen auch direkt in deinen aktuellen Branch ein**. Deine lokalen Dateien werden entsprechend aktualisiert.

**Was passiert konkret?**

1. Git führt zunächst einen `fetch` durch
2. Anschließend werden die neuen Commits automatisch in deinen lokalen Branch gemergt
3. Dein Working Directory wird aktualisiert – du siehst die Änderungen sofort in deinen Dateien

**Typische Ausgabe nach `git pull`:**

```
remote: Enumerating objects: 5, done.
From github.com:username/projekt
   a1b2c3d..e4f5g6h  main     -> origin/main
Updating a1b2c3d..e4f5g6h
Fast-forward
 src/login.php | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
```

---

## Wann welchen Befehl verwenden?

| Situation | Empfohlener Befehl | Begründung |
|-----------|-------------------|------------|
| Du möchtest **nur schauen**, ob es etwas Neues gibt | `git fetch` | Keine Änderungen an deinem Code, du behältst die Kontrolle |
| Du hast **ungespeicherte Arbeit** und willst nichts riskieren | `git fetch` | Kein Risiko von Merge-Konflikten mitten in der Arbeit |
| Du möchtest die **Unterschiede analysieren**, bevor du aktualisierst | `git fetch` + manueller Vergleich | Du kannst `origin/main` mit deinem `main` vergleichen |
| Du bist **bereit, die neuesten Änderungen** zu übernehmen | `git pull` | Schnell und praktisch, wenn du weißt, was kommt |
| Du startest **frisch in den Arbeitstag** und willst auf dem aktuellen Stand sein | `git pull` | Holt alles und bringt dich auf den neuesten Stand |
| Du arbeitest im **Team** und bist unsicher, was andere geändert haben | `git fetch` zuerst | Gibt dir die Möglichkeit, Änderungen zu prüfen |

> 💡 **Faustregel:** Im Zweifel ist `git fetch` die „sicherere" Wahl, weil es deine lokale Arbeit nicht antastet. Du kannst danach immer noch entscheiden, ob und wann du die Änderungen übernimmst.

---

## Der typische Workflow mit `git fetch`

Wenn du vorsichtig vorgehen möchtest, sieht ein typischer Ablauf so aus:

1. **Fetch ausführen** – Hole die neuesten Informationen:
   ```bash
   git fetch
   ```

2. **Vergleichen** – Schau dir an, was sich geändert hat:
   ```bash
   git log main..origin/main --oneline
   ```
   Das zeigt dir alle Commits, die auf `origin/main` sind, aber noch nicht in deinem lokalen `main`.

3. **Entscheiden und mergen** – Wenn alles gut aussieht:
   ```bash
   git merge origin/main
   ```

---

## So machst du es in PhpStorm

PhpStorm bietet dir beide Optionen komfortabel über die Benutzeroberfläche an.

### Fetch in PhpStorm

1. Gehe im Menü zu **Git → Fetch** (oder nutze die Tastenkombination, die du in den Einstellungen findest)
2. PhpStorm verbindet sich mit GitHub und aktualisiert die Remote-Tracking-Branches
3. Im **Git-Log** (unten im Git-Tool-Fenster) siehst du nun, ob `origin/main` weiter ist als dein lokaler `main`
4. Du erkennst das an einer Anzeige wie „main ← 3 commits behind origin/main"

### Pull in PhpStorm

1. Gehe im Menü zu **Git → Pull** (oder klicke auf den blauen Pfeil nach unten in der Toolbar)
2. Es öffnet sich ein Dialog, in dem du auswählen kannst:
   - **Von welchem Remote** du pullen möchtest (normalerweise `origin`)
   - **Welchen Branch** du holen möchtest
   - Ob du einen **Merge** oder **Rebase** verwenden willst (als Anfänger: bleib bei Merge)
3. Klicke auf **Pull**, und PhpStorm holt die Änderungen und integriert sie

### Update Project – die komfortable Alternative

PhpStorm bietet auch die Option **Git → Update Project** (oder `Ctrl+T` / `Cmd+T`). Diese öffnet einen Dialog, der dir verschiedene Optionen gibt:

- **Merge incoming changes into the current branch** – entspricht `git pull` mit Merge
- **Rebase the current branch on top of incoming changes** – fortgeschrittene Option
- Du kannst auch wählen, ob PhpStorm vorher automatisch uncommittete Änderungen „stashen" soll

---

## Was passiert bei Konflikten?

Sowohl nach `git pull` als auch nach einem manuellen `git merge` (nach `fetch`) kann es zu **Merge-Konflikten** kommen, wenn dieselben Stellen in einer Datei unterschiedlich geändert wurden.

- Bei `git fetch` allein passiert das **nie**, weil keine Änderungen integriert werden
- Bei `git pull` kann der Konflikt **sofort** auftreten, und du musst ihn lösen, bevor du weiterarbeiten kannst

PhpStorm zeigt dir Konflikte im Merge-Tool an und hilft dir, sie visuell zu lösen – das kennst du vielleicht schon aus dem Kapitel zu Merge-Konflikten.

---

## Zusammenfassung

| Aspekt | `git fetch` | `git pull` |
|--------|-------------|------------|
| **Holt Daten vom Remote** | ✅ Ja | ✅ Ja |
| **Ändert deinen lokalen Branch** | ❌ Nein | ✅ Ja |
| **Ändert deine Arbeitsdateien** | ❌ Nein | ✅ Ja |
| **Kann Merge-Konflikte auslösen** | ❌ Nein | ✅ Ja, möglich |
| **Risiko für laufende Arbeit** | 🟢 Keins | 🟡 Mittel |
| **Kontrolle über den Prozess** | 🟢 Volle Kontrolle | 🟡 Automatisiert |

> 🎯 **Merke dir:** `git fetch` ist wie „Nachrichten lesen, ohne zu antworten" – du informierst dich, ohne dich festzulegen. `git pull` ist wie „Nachrichten lesen und sofort darauf reagieren" – praktisch, aber du solltest wissen, was dich erwartet.