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, ...).