Git: Wie löscht man einen Branch lokal und auf dem Remote?

Ein Branch existiert an bis zu drei Stellen: auf deinem Rechner, auf dem Remote, und als Tracking-Ref, der sich merkt wie der Remote beim letzten Nachfragen aussah. Ihn sauber zu löschen heißt, sich um alle drei zu kümmern.

Die beiden Befehle

user@pc:~$ git branch -d feature                 # lokal
user@pc:~$ git push origin --delete feature      # auf dem Remote

Sie sind tatsächlich unabhängig voneinander. Nach dem ersten:

local  : main
remote : feature main   <- still there

Den lokalen Branch zu löschen teilt dem Remote überhaupt nichts mit.

-d ist der, der dich schützt

git branch -d verweigert den Dienst, wenn der Branch Commits enthält, die nirgendwo sonst gemergt sind:

user@pc:~$ git branch -d risky
error: the branch 'risky' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D risky'

-D ist derselbe Befehl mit abgeschalteter Prüfung. Nimm standardmäßig -d und lass dich aufhalten — es ist das Einzige, was zwischen einem Tippfehler und einem Branch voller verlorener Arbeit steht.

Auch nach -D ist meist noch etwas zu retten

Erzwingst du es doch, sind die Commits nicht weg — der Branch war ja nur ein Zeiger darauf:

the deleted branch tip was 1602fda
user@pc:~$ git branch recovered 1602fda
1602fda unmerged work

Der Hash steht im git reflog, und git branch <name> <hash> setzt wieder einen Zeiger darauf. Unreferenzierte Commits werden irgendwann aufgeräumt — das ist also eine Rettung und kein Ablagesystem.

Woher veraltete Tracking-Refs wirklich kommen

Man liest, man solle nach dem Löschen eines Remote-Branches git fetch --prune ausführen. Das stimmt so nicht ganz, und es lohnt sich zu wissen, welcher Fall welcher ist.

Löschst du ihn selbst, räumt git den Tracking-Ref beim Push gleich mit auf. Es gibt nichts zu prunen.

Löscht ihn ein Kollege, überlebt dein origin/<name> — auch nach einem Fetch:

after they deleted it and we fetched:
  remote really has : main
  we still list     : origin/gone origin/main   <- stale

after 'git fetch --prune':
  we now list       : origin/main

Ein einfaches git fetch legt Refs an und aktualisiert sie, entfernt sie aber nicht. Ein von jemand anderem gelöschter Branch steht deshalb auf unbestimmte Zeit weiter in deiner Ausgabe von git branch -r. Genau dafür ist --prune da.

Wenn du nicht daran denken willst, mach es zur Voreinstellung:

user@pc:~$ git config --global fetch.prune true

Mehrere auf einmal löschen

Branches, die bereits in deinen aktuellen Branch gemergt sind:

user@pc:~$ git branch --merged | grep -v '\*' | xargs -r git branch -d

Das -d statt -D ist Absicht: Sollte sich --merged bei irgendetwas irren, willst du die Verweigerung und nicht die Löschung. Sieh dir die Liste an, bevor du sie irgendwohin weiterleitest.

Hinweis zu Netcup (Werbung)

Der deutsche Hoster Netcup bietet unter anderem günstige und zugleich leistungsstarke Webhosting Pakete, KVM-basierte Root Server und dezidierte Server an. Mit unseren Gutscheincodes kannst du noch mehr Geld sparen (6€ bei deiner ersten Bestellung, 30% Rabatt auf alle KVM-basierten Root Server, ...).