Wie kann ich Git-Zweige archivieren?

305

Ich habe einige alte Zweige in meinem Git-Repository, die sich nicht mehr in der aktiven Entwicklung befinden. Ich möchte die Zweige archivieren, damit sie beim Ausführen nicht standardmäßig angezeigt werden git branch -l -r. Ich möchte sie nicht löschen, weil ich den Verlauf behalten möchte. Wie kann ich das machen?

Ich weiß, dass es möglich ist, einen Schiedsrichter außerhalb von Schiedsrichtern / Köpfen zu erstellen. Zum Beispiel refs/archive/old_branch. Gibt es irgendwelche Konsequenzen dafür?

Dan-Manges
quelle
git-rm löscht keine Ressourcen aus dem Repository, sondern entfernt sie nur aus dem Index kernel.org/pub/software/scm/git/docs/git-rm.html. Sie können diese Ressourcen einfach mitgit checkout [rev] file
Dana the Sane
1
Nicht, dass ich davon Wüste. Ich verwende jedoch Attic/<branchname>leichte Tags, um Zweige zu archivieren.
Jakub Narębski
Tags sind die schnelle, sichere und vernünftige Wahl.
kch

Antworten:

401

Ich glaube, der richtige Weg, dies zu tun, besteht darin, den Zweig zu markieren. Wenn Sie den Zweig löschen, nachdem Sie ihn markiert haben, haben Sie den Zweig effektiv beibehalten, aber Ihre Zweiglistenliste wird dadurch nicht überladen.

Wenn Sie zum Zweig zurückkehren müssen, überprüfen Sie einfach das Tag. Der Zweig aus dem Tag wird effektiv wiederhergestellt.

So archivieren und löschen Sie den Zweig:

git tag archive/<branchname> <branchname>
git branch -d <branchname>

So stellen Sie den Zweig einige Zeit später wieder her:

git checkout -b <branchname> archive/<branchname>

Der Verlauf des Zweigs bleibt genau so erhalten, wie er war, als Sie ihn markiert haben.

Jeremy Wall
quelle
11
Ich bin ein Git-Neuling, aber wenn ich das versuche, denke ich, ist der richtige Befehl zum Wiederherstellen des Zweigs:git checkout -b <branchname> archive/<branchname>
Steve
6
Gibt es in diesem Fall einen Grund, kein Objekt-Tag zu verwenden? Zu sehen, wer den Zweig wann archiviert hat, könnte interessant sein.
Grégory Joseph
7
@ GrégoryJoseph: Das ist ein sogenanntes "annotiertes Tag". Und ja, das zu verwenden kann sehr viel Sinn machen, würde ich sagen.
Onnodb
22
kleine Notiz, die Sie wahrscheinlich wollen, branch -Dda es wahrscheinlich nicht vollständig zusammengeführt wird, wenn Sie es auf diese Weise archivieren
Arkadiy Kukarkin
5
Sehr schön. Hier ist ein vollständiges Tutorial mit Erklärungen.
Guyaloni
123

Jeremys Antwort ist im Prinzip richtig, aber meiner Meinung nach sind die von ihm angegebenen Befehle nicht ganz richtig.

So archivieren Sie einen Zweig in einem Tag, ohne den Zweig auschecken zu müssen (und daher nicht in einen anderen Zweig auschecken zu müssen, bevor Sie diesen Zweig löschen können):

> git tag archive/<branchname> <branchname>
> git branch -D <branchname>

Und so stellen Sie einen Zweig wieder her:

> git checkout -b <branchname> archive/<branchname>
Steve
quelle
18
Ich denke, Sie hatten noch nicht genug Punkte, aber es wäre besser, wenn Sie nur die vorhandene Antwort bearbeiten - +1 trotzdem :)
jkp
5
@jkp Das Bearbeiten des Codes und der Befehle anderer Benutzer ist normalerweise verpönt, da subtile Änderungen an einem git-Befehl drastisch andere Dinge bewirken können und Sie möglicherweise nicht verstehen, warum der ursprüngliche Autor etwas so geschrieben hat, wie sie es getan haben. Besser einfach eine eigene Antwort geben oder einen Kommentar hinterlassen.
Dan Bechard
Oder noch schlimmer als drastisch andere Dinge, eine subtile Änderung von Befehlen oder Code könnte zu subtil unterschiedlichen Ergebnissen führen, was sehr schwer herauszufinden sein könnte. Ich würde vorschlagen, als Kommentar zu hinterlassen, damit das Poster der Antwort sich selbst bearbeiten oder antworten kann mit einer Gegenforderung, die auf die möglicherweise unterschiedlichen Ergebnisse verweist (welche solchen Gegenansprüche eher häufig sind)
Nicholas Pipitone,
22

Ja, Sie können eine Referenz mit einem nicht standardmäßigen Präfix erstellen git update-ref. z.B

  • Archivieren Sie den Zweig: git update-ref refs/archive/old-topic topic && git branch -D topic
  • Stellen Sie den Zweig wieder her (falls erforderlich): git branch topic refs/archive/old-topic

Refs mit Nicht-Standard - Präfix (hier refs/archive) zeigt nicht auf übliche up git branch, git lognoch git tag. Trotzdem können Sie sie mit auflisten git for-each-ref.

Ich verwende folgende Aliase:

[alias]
    add-archive = "!git update-ref refs/archive/$(date '+%Y%m%d-%s')"
    list-archive = for-each-ref --sort=-authordate --format='%(refname) %(objectname:short) %(contents:subject)' refs/archive/
    rem = !git add-archive
    lsrem = !git list-archive

Möglicherweise möchten Sie auch Fernbedienungen so konfigurierenpush = +refs/archive/*:refs/archive/* , dass archivierte Zweige automatisch (oder git push origin refs/archive/*:refs/archive/*einmalig) übertragen werden.

Eine andere Möglichkeit besteht darin, SHA1 irgendwo vor dem Löschen des Zweigs aufzuschreiben, es gibt jedoch Einschränkungen. Commits ohne Ref werden nach 3 Monaten (oder ein paar Wochen ohne Reflog) durchgeführt , geschweige denn manuell git gc --prune. Commits, auf die durch Refs hingewiesen wird, sind vor GC sicher.

Bearbeiten: Eine Perl-Implementierung derselben Idee von @ap gefunden :git-attic

Bearbeiten ^ 2: Gefunden einen Blog - Post , wo Gitster sich mit der gleichen Technik.

snipsnipsnip
quelle
3
Ausgezeichnet, abgesehen von allen anderen in diesem Thread, haben Sie die Frage tatsächlich beantwortet.
Tzrlk
20

Ich habe Steves Antwort erweitert , um die Änderungen auf der Fernbedienung widerzuspiegeln

 git tag archive/<branchname> <branchname>
 git branch -D <branchname>
 git branch -d -r origin/<branchname>
 git push --tags
 git push origin :<branchname>

Informationen zum Wiederherstellen von der Fernbedienung finden Sie in dieser Frage .

Liam
quelle
18

Sie können die Zweige in einem anderen Repository archivieren. Nicht ganz so elegant, aber ich würde sagen, es ist eine praktikable Alternative.

git push git://yourthing.com/myproject-archive-branches.git yourbranch
git branch -d yourbranch
August Lilleaas
quelle
4
Sie können git-bundleanstelle eines separaten Repositorys erstellen .
Jakub Narębski
9

Hier ist ein Alias ​​dafür:

arc    = "! f() { git tag archive/$1 $1 && git branch -D $1;}; f"

Fügen Sie es so hinzu:

git config --global alias.arc '! f() { git tag archive/$1 $1 && git branch -D $1;}; f'

Beachten Sie, dass git archivebereits ein Befehl vorhanden ist , den Sie nicht archiveals Aliasnamen verwenden können.

Sie können auch einen Alias ​​definieren, um die Liste der 'archivierten' Zweige anzuzeigen:

arcl   = "! f() { git tag | grep '^archive/';}; f"

über das Hinzufügen von Aliasen

Alexey
quelle
3
Mit neueren Versionen von Git (wie hier vorgeschlagen ) gibt dieser Alias ​​Vervollständigung:!git tag archive/$1 $1 && git branch -D
Mangel
5

Ich verwende folgende Aliase, um archivierte Zweige auszublenden:

[alias]
    br = branch --no-merge master # show only branches not merged into master
    bra = branch                  # show all branches

So git brzeigen Sie aktiv entwickelte Zweige und git braalle Zweige einschließlich "archivierter" .

Pitr
quelle
5
Ob ein Zweig zum Master zusammengeführt wurde, hat nichts mit seinem Archivstatus zu tun. Zum Beispiel haben wir in meinem Entwicklerteam einige Zweige, die speziell zum Testen erstellt wurden. Wir möchten diese Zweige in unserem Archiv behalten, aber wir möchten sie definitiv nicht zum Master zusammenführen.
Bart
4

Ich würde keine Zweige archivieren. Anders ausgedrückt, Zweige archivieren sich. Sie möchten sicherstellen, dass die für Archäologen relevanten Informationen auf zuverlässige Weise gefunden werden können. Sie sind zuverlässig, da sie die tägliche Entwicklung unterstützen und dem Prozess der Erledigung der Arbeit keinen zusätzlichen Schritt hinzufügen. Das heißt, ich glaube nicht, dass die Leute daran denken werden, ein Tag hinzuzufügen, wenn sie mit einem Zweig fertig sind.

Hier sind zwei einfache Schritte, die der Archäologie und Entwicklung sehr helfen .

  1. Verknüpfen Sie jeden Aufgabenzweig mit einem zugehörigen Problem im Issue-Tracker mithilfe einer einfachen Namenskonvention .
  2. Verwenden Sie git merge --no-ffdiese Option immer zum Zusammenführen von Aufgabenzweigen. Sie möchten, dass das Zusammenführungs-Commit und die Verlaufsblase auch nur für ein Commit ausgeführt werden.

Das ist es. Warum? Weil ich als Code-Archäologe selten anfange zu wissen, was an einem Zweig gearbeitet wurde. Viel häufiger ist es der Grund, warum in all den schreienden neun Höllen der Code so geschrieben ist?! Ich muss den Code ändern, aber er hat einige seltsame Funktionen, und ich muss sie rätseln, um zu vermeiden, dass etwas Wichtiges kaputt geht.

Der nächste Schritt besteht git blamedarin, die zugehörigen Commits zu finden und dann zu hoffen, dass die Protokollnachricht erklärend ist. Wenn ich tiefer graben muss, werde ich herausfinden, ob die Arbeit in einem Zweig erledigt wurde, und den Zweig als Ganzes lesen (zusammen mit seinem Kommentar im Issue-Tracker).

Sagen wir git blamePunkte bei Commit XYZ. Ich öffne einen Git-Verlaufsbrowser (gitk, GitX git log --decorate --graphusw.), finde Commit XYZ und sehe ...

AA - BB - CC - DD - EE - FF - GG - II ...
     \                       /
      QQ - UU - XYZ - JJ - MM

Da ist meine Filiale! Ich weiß, dass QQ, UU, XYZ, JJ und MM alle Teil desselben Zweigs sind, und ich sollte in ihren Protokollnachrichten nach Einzelheiten suchen. Ich weiß, dass GG ein Merge-Commit sein wird und den Namen des Zweigs hat, der hoffentlich mit einem Problem im Tracker verbunden ist.

Wenn ich aus irgendeinem Grund einen alten Zweig finden möchte, kann ich ihn ausführen git logund im Merge-Commit nach dem Zweignamen suchen. Es ist selbst in sehr großen Repositories schnell genug.

Das meine ich, wenn ich sage, dass Filialen sich selbst archivieren.

Das Markieren jedes Zweigs fügt unnötige Arbeit hinzu, um Dinge zu erledigen (ein kritischer Prozess, der rücksichtslos rationalisiert werden sollte), fasst die Tag-Liste (nicht von Leistung, sondern menschlicher Lesbarkeit) mit Hunderten von Tags zusammen, die nur sehr gelegentlich nützlich sind und nicht. Es ist sogar sehr nützlich für die Archäologie.

Schwern
quelle
2
Aber was ist mit der Unordnung? Vielleicht, wenn es eine Möglichkeit gäbe, die alten Zweige unter 10 Kubikmeter Erde zu verstecken.
bvj
1
Dies ist nützlich, gilt jedoch nicht für nicht zusammengeführte Zweige. Manchmal wurde ein Experiment an einem Zweig durchgeführt, und Sie möchten den Inhalt behalten, falls ein Teil davon später nützlich wird.
Neil Mayhew
1
@bvj Ich denke, diese Antwort schlägt vor, dass Sie zusammengeführte Zweige immer löschen sollten, da Sie jederzeit über das Zusammenführungs-Commit zu ihnen zurückkehren können. Ich stimme dem zu.
Neil Mayhew
@NeilMayhew Ja, ich habe ungefähr 10 solche nicht zusammengefügten Zweige selbst geöffnet. Jeder ist mit einer offenen Aufgabe verbunden, damit ich mich daran erinnern kann, was ich getan habe. Ich werde entweder etwas mit ihnen machen oder sie sind so veraltet, dass sie nicht mehr relevant sind, und ich werde sie löschen. Ich habe an einem Projekt gearbeitet, das in den Filialen "Ich könnte es später brauchen" völlig ertrunken ist, sodass wir kaum sehen konnten, was wir taten. Es war wirklich eine Ausrede für einige Entwickler, nicht nach sich selbst aufräumen zu müssen. Ein bisschen Spielraum ist in Ordnung, aber lassen Sie es nicht außer Kontrolle geraten.
Schwern
@Schwern stimme ich zu. Ich war auch an solchen Projekten beteiligt. Ich denke, das Konvertieren der Zweige in Tags ist ein guter Weg, um die Unordnung zu beseitigen, da die Liste der Tags immer größer wird, während die Liste der Zweige nicht wachsen sollte (weil sie den Arbeitsaufwand darstellt). Die Verwendung des Namespaces für Tags macht die Liste übersichtlicher, aber Packrat-Tendenzen müssen definitiv widerstanden werden. Ein Entwickler sollte die Commits auf seinem eigenen Computer behalten, es sei denn, es besteht eine gute Chance, dass jemand anderes sie irgendwann verwendet.
Neil Mayhew
2

Mein Ansatz ist es, alle Zweige, die mir egal sind, mit dem Präfix "trash_" umzubenennen und dann Folgendes zu verwenden:

git branch | grep -v trash

(mit einer Shell-Schlüsselbindung)

Um die Farbe des aktiven Zweigs beizubehalten, müsste man:

git branch --color=always | grep --color=never --invert-match trash
Sridhar Sarnobat
quelle
2
Wenn Sie Zweige umbenennen, können Sie sie auch in einen Namespace "archive /"
qneill
1

Sie können ein Skript verwenden, das den Zweig für Sie archiviert

Erzzweig

Es erstellt ein Tag für Sie mit dem Präfixarchiv / und löscht dann den Zweig. Überprüfen Sie jedoch den Code, bevor Sie ihn verwenden.


Verwendung - $/your/location/of/script/archbranch [branchname] [defaultbranch]

Wenn Sie das Skript ausführen möchten, ohne den Speicherort darauf zu schreiben, fügen Sie es Ihrem Pfad hinzu

Dann können Sie es anrufen

$ archbranch [branchname] [defaultbranch]

Dies [defaultbranch]ist der Zweig, in den es nach Abschluss der Archivierung verschoben wird. Es gibt einige Probleme mit der Farbcodierung, aber andere, dass es funktionieren sollte. Ich habe es schon lange in Projekten verwendet, aber es befindet sich noch in der Entwicklung.

Banezaka
quelle
1
In der Stack Overflow- Hilfe müssen Sie Ihre Zugehörigkeit zu Ihrem Produkt offenlegen.
LittleBobbyTables - Au Revoir
Oh, sorry, wusste es nicht. Ich bin der Autor des Drehbuchs.
Banezaka
0

Ich archiviere manchmal Zweige wie folgt:

  1. Generieren Sie Patch-Dateien, z. B. format-patch <branchName> <firstHash>^..<lastHash>(holen Sie sich firstHash und lastHash mitgit log <branchName> .
  2. Verschieben Sie die generierten Patch-Dateien in ein Verzeichnis auf einem Dateiserver.
  3. Löschen Sie den Zweig, z. git branch -D <branchName>

Wenden Sie den Patch an, wenn Sie den Zweig erneut verwenden müssen. Das Anwenden der Patch-Dateien (siehe git am) kann jedoch je nach Status des Zielzweigs eine Herausforderung darstellen. Auf der positiven Seite hat dieser Ansatz den Vorteil, dass die Commits der Filiale durch Müll gesammelt werden können und Platz in Ihrem Repo gespart wird.

Bill Hoag
quelle