Home

02 Übung: Git Pointer und Branches verstehen

chapter-02 exercise git branches pointers workflows

Chapter 02 Übung: Git Pointer und Branches verstehen

Anleitung


Frage 1: Einen neuen Branch erstellen

Du bist auf dem main Branch und führst git checkout -b feature/new-ui aus. Wie sieht der Git-Graph unmittelbar nach diesem Befehl aus?

Vorher:
"Add login"  "Fix bug"  "Add dashboard"
     ↓           ↓           ↓
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                           main ← HEAD

A)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                           main
                    feature/new-ui ← HEAD

B)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  m2n3o4p
                              ↑            ↑
                           main    feature/new-ui ← HEAD

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                    feature/new-ui ← HEAD

D)

  a1b2c3d  ←  e4f5g6h
                  ↑
                main

                    i7j8k9l
                        ↑
              feature/new-ui ← HEAD
Antwort anzeigen

Richtige Antwort: A

Einen neuen Branch mit git checkout -b zu erstellen, erzeugt einen neuen Pointer auf denselben Commit, auf dem du dich gerade befindest. Es wird kein neuer Commit erstellt. Sowohl main als auch feature/new-ui zeigen auf Commit i7j8k9l, und HEAD bewegt sich zum neuen Branch. Option B ist falsch, weil kein neuer Commit gemacht wurde. Option C ist falsch, weil main immer noch existiert. Option D ist falsch, weil der Branch keine Commits kopiert - er ist nur ein neuer Pointer auf denselben Commit.


Frage 2: Erster Commit auf dem Feature Branch

Nachdem du feature/new-ui erstellt hast, machst du einen Commit. Wie sieht der Graph aus?

Vor dem Commit:
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                           main
                    feature/new-ui ← HEAD

A)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s
                              ↑            ↑
                           main     feature/new-ui

B)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s
                                           ↑
                                         main
                                  feature/new-ui ← HEAD

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                           main

                          p9q8r7s
                              ↑
                    feature/new-ui ← HEAD

D)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s
                              ↑            ↑
                           main     feature/new-ui ← HEAD
Antwort anzeigen

Richtige Antwort: D

Wenn du einen Commit auf einem Branch machst, erstellt Git einen neuen Commit und bewegt NUR den aktuellen Branch-Pointer vorwärts. Der main Pointer bleibt bei i7j8k9l, weil wir nicht auf dem main Branch sind. Der neue Commit p9q8r7s wird zur neuen Spitze von feature/new-ui. Option A ist falsch, weil HEAD auf feature/new-ui zeigen sollte. Option B ist falsch, weil main sich bewegt hat (sollte es nicht). Option C ist falsch, weil Commits eine Kette bilden - der neue Commit hat i7j8k9l als Parent.


Frage 3: Mehrere Commits auf dem Feature Branch

Du machst zwei weitere Commits auf feature/new-ui. Was ist jetzt der Zustand?

Ausgangsposition:
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s
                              ↑            ↑
                           main     feature/new-ui ← HEAD

Nach 2 weiteren Commits:

A)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                                 main
                                                          feature/new-ui ← HEAD

B)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                              ↑                                       ↑
                           main                              feature/new-ui ← HEAD

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                           main

                          p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                       ↑
                                              feature/new-ui ← HEAD

D)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  t1u2v3w  ←  x4y5z6a
                              ↑                        ↑
                           main                 feature/new-ui ← HEAD
Antwort anzeigen

Richtige Antwort: B

Jeder Commit bewegt den aktuellen Branch-Pointer vorwärts. Nach zwei weiteren Commits zeigt feature/new-ui auf x4y5z6a (den neuesten Commit), während main bei i7j8k9l bleibt (wo wir abgezweigt sind). Die Commits bilden eine lineare Kette: i7j8k9lp9q8r7st1u2v3wx4y5z6a. Option A ist falsch, weil main sich nicht bewegen sollte. Option C ist falsch, weil sie die Commit-Kette unterbricht (p9q8r7s muss i7j8k9l als Parent haben). Option D ist falsch, weil sie Commit p9q8r7s in der Kette überspringt.


Frage 4: Zum Main Branch wechseln

Du führst git checkout main aus. Was passiert mit den Pointern?

Vor dem Checkout:
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                              ↑                                       ↑
                           main                              feature/new-ui ← HEAD

A)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                              ↑                                       ↑
                         main ← HEAD                          feature/new-ui

B)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                         main ← HEAD

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                         main ← HEAD

                          p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                       ↑
                                              feature/new-ui

D)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                            main ← HEAD
                                                            feature/new-ui
Antwort anzeigen

Richtige Antwort: A

git checkout (oder git switch) bewegt NUR den HEAD-Pointer. Branch-Pointer ändern sich nicht. HEAD bewegt sich vom Zeigen auf feature/new-ui zum Zeigen auf main. Beide Branches existieren immer noch und zeigen auf ihre jeweiligen Commits. Dein Arbeitsverzeichnis ändert sich, um den Zustand bei Commit i7j8k9l zu zeigen. Option B ist falsch, weil feature/new-ui immer noch existiert. Option C zeigt die Commits fälschlicherweise als separate Ketten. Option D ist falsch, weil main immer noch bei i7j8k9l ist, nicht bei x4y5z6a.


Frage 5: Fast-Forward Merge

Während du auf main bist, führst du git merge feature/new-ui aus und Git führt einen “Fast-Forward” Merge durch. Was ist das Ergebnis?

Vor dem Merge:
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                              ↑                                       ↑
                         main ← HEAD                          feature/new-ui

A)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←  merge-commit
                                                                               ↑
                                                                          main ← HEAD
                                                                          feature/new-ui

B)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                              main ← HEAD
                                                              feature/new-ui

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                              ↑                                       ↑
                         main ← HEAD                          feature/new-ui

D)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                         main ← HEAD
                         feature/new-ui
Antwort anzeigen

Richtige Antwort: B

Ein Fast-Forward Merge bewegt den Ziel-Branch-Pointer (main) vorwärts, um dem Quell-Branch (feature/new-ui) zu entsprechen. Es wird kein Merge-Commit erstellt, weil main einfach zu feature/new-ui “aufholt”. Beide Pointer zeigen jetzt auf denselben Commit x4y5z6a. Option A ist falsch, weil Fast-Forward keinen Merge-Commit erstellt. Option C ist falsch, weil main sich nicht bewegt hat. Option D ist falsch, weil sie alle Feature-Commits verliert.


Frage 6: Einen Tag hinzufügen

Nach dem Merge erstellst du einen Tag: git tag -a v1.0 -m "Release 1.0". Wohin zeigt der Tag-Pointer?

Vor dem Tag:
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                              main ← HEAD
                                                              feature/new-ui

A)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                              ↑                                       ↑
                           (v1.0)                                main ← HEAD
                                                              feature/new-ui

B)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                              main ← HEAD
                                                              feature/new-ui
                                                                 (v1.0)

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←  v1.0-tag
                                                                               ↑
                                                                          main ← HEAD
                                                                          feature/new-ui

D)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l
                              ↑
                           (v1.0)

                          p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                       ↑
                                                  main ← HEAD
                                                  feature/new-ui
Antwort anzeigen

Richtige Antwort: B

Tags sind Pointer auf Commits, genau wie Branches. Standardmäßig erstellt git tag einen Tag, der auf den Commit zeigt, auf den HEAD aktuell referenziert (was x4y5z6a ist, da HEAD → main → x4y5z6a). Der Tag, main und feature/new-ui zeigen jetzt alle auf denselben Commit. Option A ist falsch, weil der Tag auf den aktuellen HEAD-Commit zeigen sollte. Option C ist falsch, weil Tags keine neuen Commits erstellen. Option D zeigt fälschlicherweise getrennte Commit-Ketten.


Frage 7: Divergierende Branches (Teil 1)

Du wechselst zu main und machst einen Commit. Währenddessen bleibt feature/new-ui wo es ist. Was ist der Zustand?

Ausgangszustand:
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                              main ← HEAD
                                                              feature/new-ui
                                                                 (v1.0)

Nach: git checkout main, dann einen Commit machen

A)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←  b7c8d9e
                                                                   ↑            ↑
                                                           feature/new-ui  main ← HEAD
                                                              (v1.0)

B)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                           feature/new-ui
                                                              (v1.0)

                                                             b7c8d9e
                                                                 ↑
                                                            main ← HEAD

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←  b7c8d9e
                                                                   ↑            ↑
                                                           feature/new-ui  main ← HEAD
                                                              (v1.0)        feature/new-ui

D)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                              (v1.0)
                                                           feature/new-ui
                                                            main ← HEAD
Antwort anzeigen

Richtige Antwort: A

Wenn du auf main bist und einen Commit machst, bewegt sich nur der main-Pointer vorwärts. Der neue Commit b7c8d9e hat x4y5z6a als Parent. feature/new-ui und der Tag v1.0 bleiben bei x4y5z6a. Dies erzeugt eine lineare History, in der main vorgerückt ist. Option B ist falsch, weil Commits Parents haben müssen (b7c8d9e sollte x4y5z6a als Parent haben). Option C ist falsch, weil feature/new-ui sich nicht bewegen sollte (es sollte nicht zweimal erscheinen). Option D ist falsch, weil sie zeigt, dass kein neuer Commit erstellt wurde - main ist immer noch bei x4y5z6a anstatt beim neuen Commit b7c8d9e.


Frage 8: Divergierende Branches erstellen

Ausgehend vom Ergebnis von Frage 7, wechselst du jetzt zu feature/new-ui und machst einen neuen Commit. Wie sieht das Repository aus?

Ausgangszustand (von Frage 7):
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←  b7c8d9e
                                                                   ↑            ↑
                                                              (v1.0)        main ← HEAD
                                                           feature/new-ui

Ausgeführte Befehle:
  git checkout feature/new-ui
  echo "new feature code" >> app.js
  git add app.js
  git commit -m "Add new UI feature"

Was ist das Ergebnis?

A)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←  b7c8d9e  ←  f1g2h3i
                                                                   ↑            ↑            ↑
                                                              (v1.0)         main    feature/new-ui ← HEAD

B)

                                                                        b7c8d9e
                                                                            ↑
                                                                          main
                                                                           /
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←
                                                                   ↑      \
                                                              (v1.0)       f1g2h3i
                                                                              ↑
                                                                      feature/new-ui ← HEAD

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                              (v1.0)

                          b7c8d9e                             f1g2h3i
                              ↑                                   ↑
                            main                          feature/new-ui ← HEAD

D)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←  b7c8d9e
                                                                   ↑            ↑
                                                              (v1.0)         main
                                                                                ↖
                                                                                 f1g2h3i
                                                                                    ↑
                                                                            feature/new-ui ← HEAD
Antwort anzeigen

Richtige Antwort: B

Die Branches haben divergiert von ihrem gemeinsamen Vorfahren x4y5z6a:

  1. Checkout bewegt HEAD: git checkout feature/new-ui bewegt HEAD von main zu feature/new-ui (jetzt bei x4y5z6a)
  2. Neuer Commit auf feature/new-ui: Der Commit erstellt f1g2h3i mit Parent x4y5z6a (wo feature/new-ui war)
  3. Ergebnis: Sowohl b7c8d9e (auf main) als auch f1g2h3i (auf feature/new-ui) zweigen von x4y5z6a ab

Dies erzeugt eine Gabelung in der History. Die wichtige Erkenntnis: feature/new-ui zeigte immer noch auf x4y5z6a (es hat sich nicht bewegt, als main den Commit b7c8d9e in Frage 7 bekam), also zweigt der neue Commit f1g2h3i von x4y5z6a ab, NICHT von b7c8d9e.

Warum andere Optionen falsch sind:

  • Option A: Zeigt lineare History (f1g2h3i nach b7c8d9e), aber feature/new-ui sollte von x4y5z6a abzweigen, wo es war, nicht von mains neuer Position
  • Option C: Trennt Commits von ihren Parents (Commits schweben im Raum)
  • Option D: Zeigt f1g2h3i als Abzweigung von b7c8d9e, aber feature/new-ui war bei x4y5z6a, als wir es ausgecheckt haben

Frage 9: Einen Commit auschecken (Detached HEAD)

Du führst git checkout x4y5z6a (der Commit mit Tag v1.0) aus. In welchem Zustand ist Git?

Vor dem Checkout:
                                                                        b7c8d9e
                                                                            ↑
                                                                        main ← HEAD
                                                                           /
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←
                                                                   ↑      \
                                                              (v1.0)       f1g2h3i
                                                                              ↑
                                                                      feature/new-ui

A)

                                                                        b7c8d9e
                                                                            ↑
                                                                       main ← HEAD
                                                                           /
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←
                                                                   ↑      \
                                                              (v1.0)       f1g2h3i
                                                                              ↑
                                                                      feature/new-ui

B)

                                                                        b7c8d9e
                                                                            ↑
                                                                          main
                                                                           /
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←
                                                        main ← HEAD ↑      \
                                                              (v1.0)       f1g2h3i
                                                                              ↑
                                                                      feature/new-ui

C)

  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a
                                                                   ↑
                                                                 HEAD
                                                              (v1.0) (detached)

D)

                                                                        b7c8d9e
                                                                            ↑
                                                                          main
                                                                           /
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a  ←
                                                             ↑   ↑      \
                                                           HEAD           f1g2h3i
                                                        (detached)           ↑
                                                              (v1.0)   feature/new-ui
Antwort anzeigen

Richtige Antwort: D

Wenn du einen bestimmten Commit auscheckst (nicht einen Branch), zeigt HEAD direkt auf diesen Commit statt auf einen Branch-Pointer. Dies nennt man “detached HEAD”-Zustand. Git warnt dich, weil Commits, die in diesem Zustand gemacht werden, zu keinem Branch gehören.

Warum D richtig ist:

  • HEAD zeigt jetzt direkt auf Commit x4y5z6a
  • HEAD ist als “(detached)” markiert, weil es nicht durch einen Branch zeigt
  • Die Graph-Struktur ändert sich nicht - Branches bleiben wo sie waren

Warum andere Optionen falsch sind:

  • Option A: Zeigt HEAD immer noch an main gebunden (der bei b7c8d9e blieb). Falsch! Das Auschecken eines Commit-Hashes löst HEAD von Branches
  • Option B: Zeigt sowohl “main ← HEAD”-Label UND main zeigt auf x4y5z6a. Verwirrend und falsch - main hat sich nicht bewegt, nur HEAD
  • Option C: Fehlen die divergierenden Commits (b7c8d9e und f1g2h3i). Das Auschecken eines alten Commits löscht keine neueren Commits!

Frage 10: Einen Branch umbenennen

Du benennst einen Branch mit git branch -m old-name new-name um. Was ändert sich tatsächlich?

Vor dem Umbenennen:
                                                              ↱  b7c8d9e
                                                             /       ↑
  a1b2c3d  ←  e4f5g6h  ←  i7j8k9l  ←  p9q8r7s  ←  t1u2v3w  ←  x4y5z6a     main
                                                                   ↑  ↖
                                                              (v1.0)    f1g2h3i
                                                                           ↑
                                                                   feature/old-name ← HEAD

A) Der Commit f1g2h3i bekommt einen neuen Hash, weil der Branch-Name Teil des Commits ist

B) Ein neuer Commit wird mit dem neuen Branch-Namen erstellt, und der alte Commit wird gelöscht

C) Nur der Name des Branch-Pointers ändert sich; der Commit f1g2h3i und der Tag v1.0 bleiben unverändert

D) Der Tag v1.0 wird zur Spitze des umbenannten Branches verschoben, um den neuen Namen zu verfolgen

Antwort anzeigen

Richtige Antwort: C

Das Umbenennen eines Branches ändert nur die Bezeichnung des Branch-Pointers. Git erstellt einen neuen Pointer mit dem neuen Namen, der auf denselben Commit zeigt, und löscht dann den alten Pointer. Keine Commits werden modifiziert oder erstellt. Tags wie v1.0 sind nicht betroffen, weil sie auf Commits zeigen, nicht auf Branch-Namen. Deshalb ist das Umbenennen von Branches sicher und sofort - du änderst nur ein Label, nicht die tatsächliche History. Option A ist falsch, weil Commit-Hashes auf Inhalt basieren, nicht auf Branch-Namen. Option B ist falsch, weil keine Commits erstellt oder gelöscht werden. Option D ist falsch, weil Tags auf Commits zeigen und unabhängig von Branch-Namen sind.


Frage 11: Remote-Tracking Branches verstehen

Du führst git branch -a aus und siehst diese Ausgabe. Was sind die drei Arten von Referenzen, die gezeigt werden?

$ git branch -a
  main
  feature/new-feature
  remotes/origin/main
  remotes/origin/feature/old-pr

A) Alle vier sind lokale Branches, zu denen du direkt committen kannst

B) main und feature/new-feature sind lokale Branches; remotes/origin/main und remotes/origin/feature/old-pr sind Remote-Branches auf GitHub

C) main und feature/new-feature sind lokale Branches, wo du arbeitest; remotes/origin/main und remotes/origin/feature/old-pr sind lokale Lesezeichen, die GitHubs Zustand zeigen

D) remotes/origin/* sind Remote-Branches, zu denen du mit git push committen kannst

Antwort anzeigen

Richtige Antwort: C

Remote-Tracking Branches (wie remotes/origin/main) sind lokale Kopien, die als Lesezeichen dienen und zeigen, was auf GitHub existiert. Sie sind nicht die tatsächlichen Remote-Branches - sie sind deine lokale Git-Aufzeichnung dessen, was beim letzten Fetch auf GitHub war. Du kannst nicht direkt zu ihnen committen. Option A ist falsch, weil Remote-Tracking Branches schreibgeschützte Lesezeichen sind. Option B ist falsch, weil sie keine Remote-Branches sind - sie sind lokale Referenzen auf Remote-Branches. Option D ist falsch, weil du nicht zu Remote-Tracking Branches commitest; sie werden automatisch durch git fetch oder git pull aktualisiert.


Frage 12: Was passiert nach git fetch

Du führst git fetch origin aus. Was aktualisiert dieser Befehl?

Vor dem Fetch:
GitHub (origin):
  main → x4y5z6a (neuester Commit)

Dein lokales Git:
  main → i7j8k9l (veraltet)
  remotes/origin/main → i7j8k9l (veraltetes Lesezeichen)

Nach dem Fetch:

A) Nur dein lokaler main Branch aktualisiert sich auf x4y5z6a

B) Nur remotes/origin/main aktualisiert sich auf x4y5z6a; dein lokaler main bleibt bei i7j8k9l

C) Sowohl main als auch remotes/origin/main aktualisieren sich auf x4y5z6a

D) Keiner aktualisiert sich; du brauchst git pull, um etwas zu aktualisieren

Antwort anzeigen

Richtige Antwort: B

git fetch lädt neue Commits von GitHub herunter und aktualisiert Remote-Tracking Branches (remotes/origin/main), aber es aktualisiert NICHT deine lokalen Branches. Dein lokaler main bleibt bei i7j8k9l, bis du manuell mergst oder git pull verwendest (was fetch + merge ist). Dies ist der sichere Weg, um zu sehen, was sich auf GitHub geändert hat, ohne deine Arbeit zu beeinflussen. Option A ist falsch, weil fetch lokale Branches nicht berührt. Option C ist falsch, weil sich nur das Lesezeichen aktualisiert. Option D ist falsch, weil fetch Remote-Tracking Branches AKTUALISIERT.


Frage 13: Veraltete Remote-Tracking Branches

Ein PR wurde gemergt und der Feature-Branch wurde auf GitHub gelöscht. Du führst lokal git branch -a aus. Was siehst du?

GitHub (origin):
  main (einziger Branch, der existiert)

Dein lokales Git hat noch nicht gefetcht:

A)

  main
  remotes/origin/main

B)

  main
  remotes/origin/main
  remotes/origin/feature/old-pr  ← Wird immer noch angezeigt!

C)

  main
  feature/old-pr (automatisch gelöscht)
  remotes/origin/main

D) Git erkennt die Löschung automatisch und entfernt remotes/origin/feature/old-pr

Antwort anzeigen

Richtige Antwort: B

Dein lokales Git hat immer noch die remotes/origin/feature/old-pr Referenz, weil Git Remote-Tracking Branches nicht automatisch entfernt. Sie sind veraltet (zeigen auf einen Branch, der nicht mehr auf GitHub existiert), bis du git fetch --prune oder git remote prune origin ausführst. Dies ist beabsichtigt - Git irrt auf der Seite des Behaltens von Informationen. Option A ist falsch, weil die veraltete Referenz bestehen bleibt. Option C ist falsch, weil lokale Branches nicht automatisch gelöscht werden. Option D ist falsch, weil Git Löschungen nicht ohne Fetchen automatisch erkennt.


Frage 14: git fetch –prune verstehen

Was macht git fetch --prune anders als git fetch?

Situation:
- GitHub hat feature/old-pr gelöscht
- Dein lokales Git hat immer noch remotes/origin/feature/old-pr

Du führst aus: git fetch --prune

A) Lädt neue Commits herunter und löscht zwangsweise deinen lokalen feature/old-pr Branch

B) Lädt neue Commits herunter und entfernt die veraltete remotes/origin/feature/old-pr Referenz

C) Entfernt nur veraltete Remote-Tracking Branches ohne neue Commits herunterzuladen

D) Löscht sowohl den lokalen Branch als auch den Remote-Tracking Branch für feature/old-pr

Antwort anzeigen

Richtige Antwort: B

git fetch --prune macht ZWEI Dinge: (1) lädt neue Commits/Branches von GitHub herunter, und (2) entfernt Remote-Tracking Branches, die auf GitHub nicht mehr existieren. Es berührt NICHT deine lokalen Branches - die musst du separat mit git branch -d löschen. Option A ist falsch, weil lokale Branches nicht von prune betroffen sind. Option C ist falsch, weil --prune ein Zusatz zu fetch ist, kein Ersatz. Option D ist falsch, weil lokale Branches nie automatisch gelöscht werden.


Frage 15: git pull –prune Workflow

Du hast gerade einen PR auf GitHub gemergt und der Feature-Branch wurde automatisch gelöscht. Du führst git checkout main und dann git pull --prune aus. Was passiert?

Vorher:
GitHub: main → x4y5z6a (hat gemergten PR)
        feature/old-pr gelöscht ✅

Lokal:  main → i7j8k9l (veraltet)
        feature/old-pr → p9q8r7s (existiert noch lokal)
        remotes/origin/main → i7j8k9l (veraltet)
        remotes/origin/feature/old-pr → p9q8r7s (veraltet!)

Nach git pull --prune:

A)

Lokal:  main → x4y5z6a (aktualisiert)
        remotes/origin/main → x4y5z6a (aktualisiert)

B)

Lokal:  main → x4y5z6a (aktualisiert)
        feature/old-pr gelöscht
        remotes/origin/main → x4y5z6a (aktualisiert)

C)

Lokal:  main → x4y5z6a (aktualisiert)
        feature/old-pr → p9q8r7s (existiert noch)
        remotes/origin/main → x4y5z6a (aktualisiert)

D)

Lokal:  main → i7j8k9l (unverändert)
        remotes/origin/main → x4y5z6a (aktualisiert)
        remotes/origin/feature/old-pr gelöscht
Antwort anzeigen

Richtige Antwort: C

git pull --prune kombiniert drei Aktionen: (1) git fetch --prune (herunterladen + veraltete Remote-Tracking Branches entfernen), (2) Merge in den aktuellen Branch (main führt Fast-Forward zu x4y5z6a durch). Dein LOKALER feature/old-pr Branch wird NICHT gelöscht - das musst du separat mit git branch -d feature/old-pr tun. Nur der Remote-Tracking Branch remotes/origin/feature/old-pr wird durch --prune entfernt. Option A ist falsch, weil sie den lokalen Feature-Branch nicht zeigt. Option B ist falsch, weil lokale Branches nicht automatisch gelöscht werden. Option D ist falsch, weil main sich AKTUALISIERT (das macht pull).


Frage 16: Die Lesezeichen-Analogie

Laut der “Lesezeichen-Analogie” der Vorlesung, was repräsentieren Remote-Tracking Branches?

GitHub (die Websites) hat:
  - main Branch
  - feature/xyz Branch

Dein lokales Git hat:
  - Lokale Branches (main, feature/xyz)
  - Remote-Tracking Branches (remotes/origin/main, remotes/origin/feature/xyz)

A) Remote-Tracking Branches SIND die tatsächlichen Remote-Branches, nur mit einem anderen Namen

B) Remote-Tracking Branches sind wie Lesezeichen in deinem Browser - sie zeigen darauf, wo GitHubs Branches waren, als du zuletzt nachgesehen hast

C) Remote-Tracking Branches sind Backups deiner lokalen Branches, falls du deine Arbeit verlierst

D) Remote-Tracking Branches sind temporäre Referenzen, die nach dem Merge verschwinden

Antwort anzeigen

Richtige Antwort: B

Die Vorlesung vergleicht Remote-Tracking Branches mit Browser-Lesezeichen: GitHub ist wie tatsächliche Websites, und Remote-Tracking Branches sind deine lokalen Lesezeichen, die auf GitHubs Branches zeigen. Genau wie Lesezeichen veraltet sein können, wenn sich eine Website ändert, werden Remote-Tracking Branches veraltet, wenn sich GitHubs Branches ändern, ohne dass du fetchst. Option A ist falsch, weil sie lokale Kopien sind, nicht die tatsächlichen Remote-Branches. Option C ist falsch, weil sie den Remote-Zustand verfolgen, keine lokalen Backups. Option D ist falsch, weil sie bestehen bleiben, bis sie explizit gepruned werden.


Frage 17: Veraltete Referenzen verhindern

Du möchtest, dass Git automatisch veraltete Remote-Tracking Branches jedes Mal entfernt, wenn du fetchst. Was solltest du konfigurieren?

A) git config --global fetch.prune true

B) git config --global branch.autocleanup true

C) git config --global remote.pruneOnFetch true

D) git branch --set-upstream-to=origin/main

Antwort anzeigen

Richtige Antwort: A

git config --global fetch.prune true auszuführen lässt jeden git fetch und git pull automatisch veraltete Remote-Tracking Branches aufräumen. Dies ist das empfohlene Setup aus der Vorlesung, weil es “eine Sache weniger ist, an die man sich erinnern muss”. Option B ist keine gültige Git-Konfiguration. Option C ist nicht der richtige Konfigurationsname. Option D setzt Upstream-Tracking für Branches, was nichts mit Pruning zu tun hat.


Frage 18: Gemergte Branches prüfen

Du möchtest sehen, welche lokalen Branches in main gemergt wurden, bevor du sie löschst. Welcher Befehl zeigt das?

A) git branch --merged main

B) git branch --no-merged

C) git remote prune origin --dry-run

D) git log --merged

Antwort anzeigen

Richtige Antwort: A

git branch --merged main listet alle lokalen Branches auf, deren Commits von main aus erreichbar sind (das heißt, sie wurden gemergt). Du kannst diese sicher mit git branch -d löschen. Option B zeigt Branches, die noch NICHT gemergt wurden (Gegenteil von dem, was du willst). Option C zeigt Remote-Tracking Branches, die gepruned würden, nicht lokale Branches. Option D ist kein gültiges git log Flag.


Frage 19: Squash Merge Branch-Löschung

Dein PR wurde mit “Squash and merge” auf GitHub gemergt. Der Branch wurde dort gelöscht. Jetzt versuchst du, deinen lokalen Branch zu löschen:

$ git branch -d feature/squashed
error: The branch 'feature/squashed' is not fully merged.

Warum sagt Git das, und was solltest du tun?

A) Git liegt falsch; führe git branch -D feature/squashed (erzwungenes Löschen) aus, nachdem du bestätigt hast, dass der PR gemergt wurde

B) Der PR wurde nicht wirklich gemergt; prüfe GitHub nochmal

C) Du musst zuerst git pull --rebase ausführen, um den Squash-Commit zu synchronisieren

D) Lokale Branches können nicht gelöscht werden, wenn sie mit Squash gemergt wurden; lass ihn stehen

Antwort anzeigen

Richtige Antwort: A

“Squash and merge” erstellt einen NEUEN Commit mit all deinen Änderungen kombiniert, anstatt deine ursprünglichen Commits zu verwenden. Git sieht deine lokalen Commits als “nicht gemergt”, weil sie in der History von main nicht existieren (nur die gesquashte Version existiert). Nachdem du auf GitHub bestätigt hast, dass der PR tatsächlich gemergt wurde, ist es sicher, mit git branch -D feature/squashed zwangsweise zu löschen. Option B ist falsch - der PR IST gemergt, nur in einer anderen Form. Option C ist falsch - Rebase hilft hier nicht. Option D ist falsch - du kannst und solltest gemergte Branches löschen.


Frage 20: Vollständiges Aufräumen nach PR-Merge

Dein PR wurde mit “Create a merge commit” (nicht Squash) gemergt und GitHub hat den Remote-Branch automatisch gelöscht. Was ist der vollständige Aufräum-Workflow?

Ausgangszustand:
- GitHub: main (aktualisiert mit deinem PR durch Merge-Commit), feature/xyz gelöscht
- Lokal: main (veraltet), feature/xyz (existiert noch),
         remotes/origin/feature/xyz (veraltet)

A)

git checkout main
git branch -d feature/xyz

B)

git fetch --prune
git checkout main
git pull

C)

git checkout main
git pull --prune
git branch -d feature/xyz

D)

git remote prune origin
git branch -D feature/xyz
Antwort anzeigen

Richtige Antwort: C

Der vollständige Workflow ist: (1) git checkout main um zu main zu wechseln, (2) git pull --prune um main zu aktualisieren UND veraltete Remote-Tracking Branches zu entfernen, (3) git branch -d feature/xyz um deinen lokalen Branch zu löschen. Dies räumt alle drei auf: lokaler Branch, lokaler main und veraltete Remote-Tracking Referenzen. Da der PR mit “Create a merge commit” (nicht Squash) gemergt wurde, erkennt Git den Branch als gemergt und -d funktioniert sicher. Option A ist falsch, weil sie main nicht aktualisiert oder pruned. Option B ist falsch, weil sie den lokalen Branch nicht löscht. Option D ist falsch, weil sie main nicht aktualisiert und erzwungenes Löschen (-D) verwendet, was unnötig ist, wenn der Branch ordentlich gemergt wurde.


Bewertungsrichtlinie


Wichtige Erkenntnisse zum Merken

  1. Branches sind Pointer - Sie sind leichtgewichtige Referenzen auf Commits, keine Kopien von Commits
  2. HEAD zeigt deine Position - HEAD zeigt auf deinen aktuellen Branch (oder Commit im detached-Zustand)
  3. Einen Branch zu erstellen ist günstig - Es wird nur ein neuer Pointer erstellt, keine Dateien werden kopiert
  4. Nur der aktuelle Branch bewegt sich - Wenn du commitest, bewegt sich nur der Branch, auf den HEAD zeigt, vorwärts
  5. Branches zu wechseln bewegt HEAD - git checkout/git switch bewegt nur den HEAD-Pointer
  6. Tags sind permanente Pointer - Im Gegensatz zu Branches bewegen sie sich nicht, wenn du commitest
  7. Fast-Forward vs. Three-Way Merge - Fast-Forward bei linearer History; Three-Way bei divergierter
  8. Merge-Commits haben zwei Parents - Das macht die History nicht-linear
  9. Einen Branch zu löschen entfernt den Pointer - Commits bleiben, wenn sie von anderen Branches aus erreichbar sind
  10. Detached HEAD ist direkte Commit-Referenz - HEAD zeigt auf einen Commit, nicht auf einen Branch
  11. Drei Arten von Branches - Lokale Branches (wo du arbeitest), Remote-Tracking Branches (lokale Lesezeichen des GitHub-Zustands) und tatsächliche Remote-Branches (auf GitHub)
  12. Remote-Tracking Branches sind Lesezeichen - Sie sind lokale Referenzen, die GitHubs Zustand beim letzten Fetch zeigen
  13. git fetch aktualisiert Lesezeichen - Lädt Commits herunter und aktualisiert Remote-Tracking Branches, aber nicht lokale Branches
  14. Veraltete Referenzen brauchen Pruning - Verwende git fetch --prune um Remote-Tracking Branches für gelöschte Remote-Branches zu entfernen
  15. Automatisches Pruning aktivieren - Führe git config --global fetch.prune true aus, um veraltete Referenzen immer aufzuräumen
  16. Vollständiger Aufräum-Workflow - Nach PR-Merge: git checkout main, git pull --prune, git branch -d feature/xyz
  17. Squash Merges brauchen erzwungenes Löschen - Nach Squash Merge verwende git branch -D, weil Git den Merge nicht erkennt
  18. Lokale Branches müssen manuell gelöscht werden - Pruning betrifft nur Remote-Tracking Branches, nicht lokale Branches

Praxis-Empfehlung

Nach dem Abschließen dieser Übung versuche diese Befehle in einem Test-Repository:

Teil 1: Lokale Branches und Pointer

# Erstelle ein Test-Repository
git init test-branches
cd test-branches

# Mache einige Commits und Branches
echo "file1" > file.txt && git add . && git commit -m "commit 1"
echo "file2" > file.txt && git add . && git commit -m "commit 2"
git checkout -b feature
echo "file3" > file.txt && git add . && git commit -m "commit 3"

# Visualisiere den Graphen
git log --oneline --graph --all --decorate

# Experimentiere mit dem Wechseln von Branches und dem Machen von Commits
# Beobachte, wie sich die Pointer bewegen!

Teil 2: Remote-Tracking Branches (Üben mit einem GitHub-Repository)

# Klone eines deiner GitHub-Repositories
git clone https://github.com/yourusername/yourrepo.git
cd yourrepo

# Zeige alle Branches an (einschließlich Remote-Tracking)
git branch -a

# Erstelle und pushe einen Feature-Branch
git checkout -b test-cleanup
echo "test" > test.txt && git add . && git commit -m "test"
git push -u origin test-cleanup

# Simuliere PR-Merge: Gehe zu GitHub, merge den PR, lösche den Branch

# Jetzt zurück in deinem Terminal - sieh die veraltete Referenz
git branch -a  # Zeigt immer noch remotes/origin/test-cleanup

# Räume ordentlich auf
git checkout main
git pull --prune  # Aktualisiert main UND entfernt veraltete Referenz
git branch -d test-cleanup  # Löscht lokalen Branch

# Verifiziere das Aufräumen
git branch -a  # Sollte sauber sein!

# Aktiviere automatisches Pruning für die Zukunft
git config --global fetch.prune true

Diese praktische Übung wird dein Verständnis der in dieser Übung getesteten Konzepte festigen, besonders den Unterschied zwischen lokalen Branches und Remote-Tracking Branches!

© 2026 Dominik Mueller   •  Powered by Soopr   •  Theme  Moonwalk