Mittwoch, 21. Januar 2009

Einen Git-Branch löschen?

Da schreibe ich gerade noch, wie praktisch es bei Git ist, einfach einen Teil des Repositories als separates Projekt herauszulösen, und dann das: Ein zum Hochschieben der Tags abgesetztes git push --all schiebt alles, was im lokalen Repository ist, auf den github, darunter auch das komplette alte Projekt, aus dem ich das Teilprojekt gerade erst herausgelöst habe. Wie peinlich.

Jetzt gibt es zwei Fragen: Warum tauchen plötzlich die alten Commits wieder auf, und wie werde ich sie wieder los?

Die Antwort auf die erste Frage ist leicht: Der alte Branch war nach dem Zurechtschneiden immer noch in dem Repository vorhanden, das früher einmal das Monsterprojekt beherbergte. Er war nur eben abgehängt. Normalerweise war der Branch nicht sichtbar, und da nach den Anweisungen von github vom frisch geglaubte Projekt mittel git push origin master explizit nur den master-Branch hochgeladen wurde, fiel nicht gleich auf, welches Problem da noch wartete: Das remote Repository war tatsächlich schlank, das lokale Repository aber nicht.

Den Schlammassel lokal wieder loszuwerden ist dann doch nicht einfach. SCMs sind sehr gut darin, sich Sachen zu merken, und nicht sehr kooperativ, wenn sie etwas vergessen sollen -- Git ist da keine Ausnahme. Kurz, ich habe ewig probiert, und nichts hat geholfen. (Letztlich sollte es helfen, alle Referenzen auf die ungewollen Commits zu entfernen. Also alle Branches und Tags löschen, die dahin zeigen.) Viel wichtiger ist natürlich, die ungewollt hochgeschobenen Daten vom github wieder zu löschen.

Die Lösung ist allerdings verblüffend einfach: Zuerst werden die ungewollten Objekte (Tags und ggf. Branches) auf einem remote repository (z.B. github) gelöscht, dann wird von da ein frischer Clone gezogen:

# tag "stoertMich" und branch "obsolete" loswerden
git push origin :stoertMich
git push origin :obsolete
# irgendwohin, wo der frische Clone aufwachen soll
cd ..
# ...und frisch clonen
git clone

Die Seite, der ich diese Einsicht verdanke, ist, verglichen mit den Ausmaßen des Problems, irritierend schlicht: github's Guide: Remove a remote branch. Allzu leicht übersieht man die Doppelpunkte, die praktisch die Lösung des Problems sind. Ich habe sie daher mal rot eingefärbt.

Ein kurzer Blick in die Packs (unterhalb von .git) verrät, daß da kein uraltes, gigantisches Monster mehr schlummert, sondern nur ein schlankes, blankes Repository mit dem exakt herausgelösten ehemaligen Teilprojekt.

Und wieder gerettet.

2 Kommentare:

r2p2 hat gesagt…

Werden auch die dangling commits gelöscht? Ich dachte, das macht er nur beim git gc.

ketchup hat gesagt…

Eine gute Frage. Ich überlege nur, ob remote Repos nicht sowieso regelmäßig gc aufrufen sollten (meine selbstgebauten Remotes tun das einmal am Tag). Könnte man mal ausprobieren. Oder nachlesen. ;)