Nehmen wir an, ich habe ein Setup, das ungefähr so aussieht
phd/code/
phd/figures/
phd/thesis/
Aus historischen Gründen haben diese alle ihre eigenen Git-Repositories. Aber ich möchte sie zu einer einzigen kombinieren, um die Dinge ein wenig zu vereinfachen. Zum Beispiel könnte ich im Moment zwei Änderungssätze vornehmen und muss so etwas tun
cd phd/code
git commit
cd ../figures
git commit
Es wäre (jetzt) schön, nur aufzutreten
cd phd
git commit
Es scheint verschiedene Möglichkeiten zu geben, dies mit Submodulen zu tun oder aus meinen Sub-Repositorys zu ziehen, aber das ist etwas komplexer, als ich suche. Zumindest würde ich mich freuen
cd phd
git init
git add [[everything that's already in my other repositories]]
aber das scheint kein Einzeiler zu sein. Kann git
mir irgendetwas helfen?
Antworten:
Hier ist eine Lösung, die ich hier gegeben habe :
Machen Sie zuerst eine vollständige Sicherung Ihres Promotionsverzeichnisses: Ich möchte nicht dafür verantwortlich gemacht werden, dass Sie jahrelange harte Arbeit verloren haben! ;-);
Verschieben Sie den Inhalt von
phd/code
nachphd/code/code
und korrigieren Sie den Verlauf so, dass er immer dort war (dies verwendet den Filter-Branch- Befehl von git ):Das Gleiche gilt für den Inhalt
phd/figures
undphd/thesis
(ersetzen Sie einfachcode
mitfigures
undthesis
).Jetzt sollte Ihre Verzeichnisstruktur folgendermaßen aussehen:
Erstellen Sie dann ein Git-Repository im Stammverzeichnis, ziehen Sie alles hinein und entfernen Sie die alten Repositorys:
Schließlich sollten Sie jetzt haben, was Sie wollten:
Eine nette Seite dieses Verfahrens ist, dass nicht versionierte Dateien und Verzeichnisse an Ort und Stelle bleiben .
Hoffe das hilft.
Nur ein Wort der Warnung: Wenn Ihr
code
Verzeichnis bereits eincode
Unterverzeichnis oder eine Datei enthält, können Probleme auftreten (dasselbe gilt fürfigures
undthesis
natürlich). Wenn dies der Fall ist, benennen Sie das Verzeichnis oder die Datei einfach um, bevor Sie den gesamten Vorgang ausführen:Und wenn der Vorgang abgeschlossen ist, fügen Sie diesen letzten Schritt hinzu:
Wenn das
code
Unterverzeichnis oder die Datei nicht versioniert ist, verwenden Sie einfachmv
anstelle vongit mv
und vergessen Sie dasgit commit
s.quelle
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
und dann hat es super funktioniert!quelle
Vielleicht einfach (ähnlich wie in der vorherigen Antwort, aber mit einfacheren Befehlen) in jedem der separaten alten Repositorys ein Commit erstellen, das den Inhalt in ein entsprechend benanntes Unterverzeichnis verschiebt, z.
und dann die drei separaten Repos zu einem neuen zusammenführen, indem Sie Folgendes tun:
Dann speichern Sie Ihre Historien, fahren aber mit einem einzigen Repo fort.
quelle
Sie können die Strategie zum Zusammenführen von Teilbäumen ausprobieren . Damit können Sie Repo B mit Repo A zusammenführen. Der Vorteil gegenüber
git-filter-branch
ist, dass Sie Ihre Repo A-Historie nicht neu schreiben müssen (SHA1-Summen brechen).quelle
Die Git-Filter-Branch-Lösung funktioniert gut, aber beachten Sie, dass Ihr Git-Repo, wenn es aus einem SVN-Import stammt, möglicherweise mit einer Meldung wie der folgenden fehlschlägt:
In diesem Fall müssen Sie die Erstrevision aus dem Filterzweig ausschließen - dh
HEAD
am Ende ändern in[SHA of 2nd revision]..HEAD
- siehe:http://www.git.code-experiments.com/blog/2010/03/merging-git-repositories.html
quelle
Die @ MiniQuark-Lösung hat mir sehr geholfen, berücksichtigt jedoch leider keine Tags, die sich in Quell-Repositorys befinden (zumindest in meinem Fall). Unten ist meine Verbesserung auf @MiniQuark Antwort.
Erstellen Sie zuerst ein Verzeichnis, das zusammengesetztes Repo und zusammengeführte Repos enthält, und erstellen Sie ein Verzeichnis für jedes zusammengeführte.
Ziehen Sie jedes Repository ab und rufen Sie alle Tags ab. (Anweisungen nur für
code
Unterverzeichnis anzeigen)(Dies ist eine Verbesserung gegenüber Punkt 2 in der MiniQuark-Antwort.) Verschieben Sie den Inhalt von
new_phd/code
nachnew_phd/code/code
und fügencode_
Sie vor jedem Tag ein Präfix hinzuDanach gibt es doppelt so viele Tags wie vor der Filterverzweigung. Alte Tags bleiben im Repo und neue Tags mit
code_
Präfix werden hinzugefügt.Alte Tags manuell entfernen:
Wiederholen Sie Punkt 2,3,4 für andere Unterverzeichnisse
Jetzt haben wir die Struktur der Verzeichnisse wie in @MiniQuark Antwort Punkt 3.
Gehen Sie wie in Punkt 4 der MiniQuark-Antwort vor, rufen Sie jedoch nach dem Ziehen und vor dem Entfernen des Verzeichnisses
.git
Tags ab:Fortsetzen..
Dies ist nur eine andere Lösung. Hoffe es hilft jemandem, es hat mir geholfen :)
quelle
Git-Stitch-Repo aus der Antwort von Aristoteles Pagaltzis funktioniert nur für Repositories mit einfacher, linearer Historie.
Antwort von MiniQuark funktioniert für alle Repositorys, verarbeitet jedoch keine Tags und Zweige.
Ich habe ein Programm erstellt, das genauso funktioniert wie von MiniQuark beschrieben, aber ein Merge-Commit (mit N Eltern) verwendet und auch alle Tags und Zweige neu erstellt, um auf diese Merge-Commits zu verweisen.
Beispiele zur Verwendung finden Sie im git-merge-repos-Repository .
quelle
Ich habe ein Tool erstellt, das diese Aufgabe erledigt. Die verwendete Methode ist ähnlich (intern machen einige Dinge wie --filter-branch), ist aber freundlicher. Ist GPL 2.0
http://github.com/geppo12/GitCombineRepo
quelle
Tatsächlich unterstützt Git-Stitch-Repo jetzt Zweige und Tags, einschließlich kommentierter Tags (ich habe festgestellt, dass es einen Fehler gab, den ich gemeldet habe, und er wurde behoben). Was ich nützlich fand, ist mit Tags. Da Tags an Commits angehängt sind und einige der Lösungen (wie Eric Lees Ansatz) sich nicht mit Tags befassen. Sie versuchen, einen Zweig aus einem importierten Tag zu erstellen. Dadurch werden alle Zusammenführungen / Verschiebungen von Git rückgängig gemacht und Sie werden zurückgeschickt, als ob das konsolidierte Repository nahezu identisch mit dem Repository ist, aus dem das Tag stammt. Es gibt auch Probleme, wenn Sie dasselbe Tag in mehreren Repositorys verwenden, die Sie zusammengeführt / konsolidiert haben. Wenn Sie beispielsweise Repos A und B haben, haben beide das Tag rel_1.0. Sie führen Repo A und Repo B zu Repo AB zusammen. Da sich rel_1.0-Tags auf zwei verschiedenen Commits befinden (eines für A und eines für B), Welches Tag wird in AB sichtbar sein? Entweder das Tag aus dem importierten Repo A oder aus dem importierten Repo B, aber nicht beide.
Mit Git-Stitch-Repo können Sie dieses Problem beheben, indem Sie die Tags rel_1.0-A und rel_1.0-B erstellen. Möglicherweise können Sie das rel_1.0-Tag nicht auschecken und beide erwarten, aber zumindest können Sie beide sehen, und theoretisch können Sie sie zu einem gemeinsamen lokalen Zweig zusammenführen und dann ein rel_1.0-Tag für diesen zusammengeführten Zweig erstellen (vorausgesetzt, Sie haben nur Quellcode zusammenführen und nicht ändern). Es ist besser, mit Zweigen zu arbeiten, da Sie wie Zweige aus jedem Repo in lokalen Zweigen zusammenführen können. (dev-a und dev-b können zu einem lokalen dev-Zweig zusammengeführt werden, der dann zum Ursprung verschoben werden kann).
quelle
Die von Ihnen vorgeschlagene Reihenfolge
wird funktionieren, aber Sie werden Ihren Commit-Verlauf verlieren.
quelle
So führen Sie ein zweites Projekt in einem Hauptprojekt zusammen:
A) Im zweiten Projekt
B) Im Hauptprojekt:
Führen Sie in diesem Zweig alle wichtigen Transformationen durch, die Sie durchführen müssen, und legen Sie sie fest.
C) Dann zurück zum Meister und eine klassische Verschmelzung zwischen den beiden Zweigen:
quelle
Ich werde meine Lösung auch hier reinwerfen. Es ist im Grunde ein ziemlich einfacher Bash-Script-Wrapper
git filter-branch
. Wie bei anderen Lösungen werden nur Hauptzweige und keine Tags migriert. Die vollständigen Master-Commit-Historien werden jedoch migriert und es handelt sich um ein kurzes Bash-Skript, sodass es für Benutzer relativ einfach sein sollte, sie zu überprüfen oder zu optimieren.https://github.com/Oakleon/git-join-repos
quelle
Dieses Bash-Skript umgeht das Problem mit den Zeichen der Registerkarte "sed" (z. B. unter MacOS) und das Problem fehlender Dateien.
Dies ist eine Kombination von miniquark , marius-Butuc und ryan ‚s Beiträge. Prost auf sie!
quelle