Ich habe vor einigen Monaten ein Projekt gestartet und alles in einem Hauptverzeichnis gespeichert. In meinem Hauptverzeichnis "Projekt" gibt es mehrere Unterverzeichnisse, die verschiedene Dinge enthalten: Projekt / Papier enthält ein in LaTeX Project geschriebenes Dokument / Quellcode / RailsApp enthält meine Rails-App.
"Project" ist GITified und es gab viele Commits sowohl im "paper" - als auch im "RailsApp" -Verzeichnis. Da ich cruisecontrol.rb für meine "RailsApp" verwenden möchte, frage ich mich, ob es eine Möglichkeit gibt, aus "RailsApp" ein Submodul zu machen, ohne den Verlauf zu verlieren.
git
git-submodules
Cœur
quelle
quelle
Antworten:
Heutzutage gibt es einen viel einfacheren Weg als die manuelle Verwendung des Git-Filter-Zweigs: Git-Teilbaum
Installation
HINWEIS
git-subtree
ist jetzt Teil vongit
(wenn Sie Contrib installieren) ab 1.7.11, sodass Sie es möglicherweise bereits installiert haben. Sie können dies durch Ausführen überprüfengit subtree
.So installieren Sie git-subtree von der Quelle (für ältere Versionen von git):
Oder wenn Sie die Manpages und alles wollen
Verwendung
Teilen Sie einen größeren in kleinere Stücke:
Für eine detaillierte Dokumentation (Manpage) lesen Sie bitte
git-subtree.txt
.quelle
git rm -rf ./foo
entferntfoo
vonHEAD
aber nicht Filtermy-project
ist voller Geschichte. Danngit submodule add [email protected]:my-user/new-project.git foo
macht nurfoo
ein Submodul abHEAD
. In dieser Hinsichtfilter-branch
ist die Skripterstellung überlegen, da sie es ermöglicht, "so zu tun, als ob Subdir von Anfang an ein Submodul wäre"Kasse Git Filter-Zweig .
Der
Examples
Abschnitt der Manpage zeigt, wie Sie ein Unterverzeichnis in ein eigenes Projekt extrahieren und dabei den gesamten Verlauf beibehalten und den Verlauf anderer Dateien / Verzeichnisse verwerfen (genau das, wonach Sie suchen).quelle
Eine Möglichkeit, dies zu tun, ist die Umkehrung - entfernen Sie alles außer der Datei, die Sie behalten möchten.
Erstellen Sie im Grunde genommen eine Kopie des Repositorys und
git filter-branch
entfernen Sie dann alles außer den Dateien / Ordnern, die Sie behalten möchten.Zum Beispiel habe ich ein Projekt, aus dem ich die Datei
tvnamer.py
in ein neues Repository extrahieren möchte :Damit wird
git filter-branch --tree-filter
jedes Commit durchlaufen, der Befehl ausgeführt und der resultierende Verzeichnisinhalt erneut festgeschrieben. Dies ist äußerst destruktiv (Sie sollten dies also nur für eine Kopie Ihres Repositorys tun!) Und kann eine Weile dauern (ca. 1 Minute bei einem Repository mit 300 Commits und ca. 20 Dateien).Der obige Befehl führt nur das folgende Shell-Skript für jede Revision aus, das Sie natürlich ändern müssten (damit Ihr Unterverzeichnis stattdessen ausgeschlossen wird
tvnamer.py
):Das größte offensichtliche Problem ist, dass alle Festschreibungsnachrichten hinterlassen werden, auch wenn sie nicht mit der verbleibenden Datei zusammenhängen. Das Skript git-remove-empty-commits behebt dieses Problem.
Sie müssen das
-f
Force-Argument verwenden, dasfilter-branch
erneut ausgeführt wird, wenn etwas drin istrefs/original/
(was im Grunde eine Sicherung ist).Natürlich wird dies niemals perfekt sein, zum Beispiel wenn Ihre Commit-Nachrichten andere Dateien erwähnen, aber es ist ungefähr so nah, wie es ein Git-Strom zulässt (soweit mir sowieso bekannt ist).
Führen Sie dies immer nur auf einer Kopie Ihres Repositorys aus! - aber zusammenfassend, um alle Dateien außer "thisismyfilename.txt" zu entfernen:
quelle
git filter-branch
hat (heutzutage?) eine eingebaute Option, um leere Commits zu entfernen, nämlich--prune-empty
. Eine bessere Anleitung finden Siegit filter-branch
in den Antworten auf diese Frage: stackoverflow.com/questions/359424/…Sowohl CoolAJ86- als auch Apenwarr- Antworten sind sehr ähnlich. Ich ging zwischen den beiden hin und her und versuchte, Teile zu verstehen, die in beiden fehlten. Unten ist eine Kombination von ihnen.
Navigieren Sie zuerst mit Git Bash zum Stammverzeichnis des zu teilenden Git-Repos. In meinem Beispiel hier ist das
~/Documents/OriginalRepo (master)
Unten finden Sie eine Kopie von oben, wobei die anpassbaren Namen ersetzt wurden und stattdessen https verwendet werden. Stammordner ist jetzt
~/Documents/_Shawn/UnityProjects/SoProject (master)
quelle
Wenn Sie eine Teilmenge von Dateien in ein neues Repository übertragen möchten, aber den Verlauf beibehalten möchten, erhalten Sie im Grunde einen vollständig neuen Verlauf. Dies würde im Grunde wie folgt funktionieren:
Es sollte etwas unkompliziert sein, dies zu automatisieren, wenn es Ihnen nichts ausmacht, ein kleines, aber haariges Skript zu schreiben. Einfach, ja, aber auch schmerzhaft. Die Leute haben in der Vergangenheit in Git die Geschichte neu geschrieben. Sie können danach suchen.
Alternativ: Klonen Sie das Repository und löschen Sie das Papier im Klon. Löschen Sie die App im Original. Dies würde eine Minute dauern, es wird garantiert funktionieren und Sie können zu wichtigeren Dingen zurückkehren, als zu versuchen, Ihre Git-Geschichte zu bereinigen. Machen Sie sich keine Sorgen über den Festplattenspeicher, den redundante Kopien des Verlaufs belegen.
quelle