Ich muss zwei Git-Repositorys zu einem brandneuen dritten Repository zusammenführen. Ich habe viele Beschreibungen dazu gefunden, wie dies mithilfe einer Teilbaumzusammenführung durchgeführt wird (zum Beispiel Jakub Narębskis Antwort auf Wie führt man zwei Git-Repositorys zusammen? ), Und das Befolgen dieser Anweisungen funktioniert meistens, außer dass beim Festschreiben des Teilbaums alle Dateien zusammengeführt werden aus den alten Repositorys werden als neu hinzugefügte Dateien aufgezeichnet. Ich kann den Commit-Verlauf aus den alten Repositorys sehen git log
, wenn ich dies tue , aber wenn ich das tue git log <file>
, wird nur ein Commit für diese Datei angezeigt - das Zusammenführen von Teilbäumen. Nach den Kommentaren zu der obigen Antwort zu urteilen, bin ich nicht allein, wenn ich dieses Problem sehe, aber ich habe keine veröffentlichten Lösungen dafür gefunden.
Gibt es eine Möglichkeit, Repositorys zusammenzuführen und den Verlauf einzelner Dateien intakt zu lassen?
quelle
Antworten:
Es stellt sich heraus, dass die Antwort viel einfacher ist, wenn Sie einfach versuchen, zwei Repositorys zusammenzukleben und es so aussehen zu lassen, als wäre es die ganze Zeit so gewesen, anstatt eine externe Abhängigkeit zu verwalten. Sie müssen lediglich Ihren alten Repos Fernbedienungen hinzufügen, sie mit Ihrem neuen Master zusammenführen, die Dateien und Ordner in ein Unterverzeichnis verschieben, die Verschiebung festschreiben und für alle weiteren Repos wiederholen. Submodule, Teilbaumzusammenführungen und ausgefallene Rebases sollen ein etwas anderes Problem lösen und sind nicht für das geeignet, was ich versucht habe.
Hier ist ein Beispiel für ein Powershell-Skript zum Zusammenkleben von zwei Repositorys:
Natürlich können Sie stattdessen old_b in old_a zusammenführen (was zum neuen kombinierten Repo wird), wenn Sie dies lieber tun möchten - ändern Sie das Skript entsprechend.
Verwenden Sie Folgendes, wenn Sie auch laufende Feature-Zweige übernehmen möchten:
Dies ist der einzige nicht offensichtliche Teil des Prozesses - dies ist keine Zusammenführung von Teilbäumen, sondern ein Argument für die normale rekursive Zusammenführung, das Git mitteilt, dass wir das Ziel umbenannt haben und Git dabei hilft, alles richtig auszurichten.
Ich schrieb eine etwas ausführlichere Erklärung nach oben hier .
quelle
git mv
funktioniert nicht so gut. Wenn Sie später einegit log
für eine der verschobenen Dateien verwenden, erhalten Sie nur das Commit aus der Verschiebung. Die gesamte Vorgeschichte geht verloren. Das liegt daran, dassgit mv
es wirklichgit rm; git add
nur in einem Schritt geht .git log --follow
, oder alle GUI-Tools erledigen dies automatisch für Sie. Bei einer Teilbaumzusammenführung können Sie meines Wissens nicht den Verlauf einzelner Dateien abrufen, daher ist diese Methode besser.1
(die Nummer Eins) fürls
und Kapital "Auge" fürxargs
. Danke für diesen Tipp!Hier ist eine Methode, mit der kein Verlauf neu geschrieben wird, sodass alle Festschreibungs-IDs gültig bleiben. Das Endergebnis ist, dass die Dateien des zweiten Repos in einem Unterverzeichnis landen.
Fügen Sie das zweite Repo als Fernbedienung hinzu:
Stellen Sie sicher, dass Sie alle Commits von secondrepo heruntergeladen haben:
Erstellen Sie einen lokalen Zweig aus dem Zweig des zweiten Repos:
Verschieben Sie alle Dateien in ein Unterverzeichnis:
Führen Sie den zweiten Zweig in den Hauptzweig des ersten Repos ein:
Ihr Repository verfügt über mehr als ein Root-Commit, dies sollte jedoch kein Problem darstellen.
quelle
git remote show secondrepo
)--allow-unrelated-histories
. Siehe den Verlauf dieses Antwortbeitrags.Ein paar Jahre sind vergangen und es gibt gut abgestimmte Lösungen, aber ich möchte meine teilen, weil es ein bisschen anders war, weil ich 2 Remote-Repositorys zu einem neuen zusammenführen wollte, ohne den Verlauf aus den vorherigen Repositorys zu löschen.
Erstellen Sie ein neues Repository in Github.
Laden Sie das neu erstellte Repo herunter und fügen Sie das alte Remote-Repository hinzu.
Rufen Sie alle Dateien aus dem alten Repo ab, damit ein neuer Zweig erstellt wird.
Führen Sie im Hauptzweig eine Zusammenführung durch, um das alte Repo mit dem neu erstellten zu kombinieren.
Erstellen Sie einen neuen Ordner, um alle neu erstellten Inhalte zu speichern, die vom OldRepo hinzugefügt wurden, und verschieben Sie die Dateien in diesen neuen Ordner.
Zuletzt können Sie die Dateien aus den kombinierten Repos hochladen und das OldRepo sicher von GitHub löschen.
Ich hoffe, dies kann für alle nützlich sein, die sich mit dem Zusammenführen von Remote-Repositorys befassen.
quelle
git remote rm OldRepo
.Bitte schauen Sie sich die Verwendung an
zwei Geschichten früh in ihrem Leben zu verbinden.
Wenn Sie Pfade haben, die sich überlappen, korrigieren Sie sie mit
Wenn Sie log verwenden, stellen Sie sicher, dass Sie "Kopien schwerer finden" mit
Auf diese Weise finden Sie alle Bewegungen von Dateien im Pfad.
quelle
Ich habe die Lösung von @Flimm in eine solche umgewandelt
git alias
(zu meiner hinzugefügt~/.gitconfig
):quelle
$GIT_PREFIX
?Diese Funktion klont das Remote-Repo in das lokale Repo-Verzeichnis:
Wie benutzt man:
Beachten. Dieses Skript kann Commits neu schreiben, speichert jedoch alle Autoren und Daten. Dies bedeutet, dass neue Commits weitere Hashes enthalten. Wenn Sie versuchen, Änderungen auf den Remote-Server zu übertragen, kann es nur mit Force-Taste ausgeführt werden. Außerdem werden Commits auf dem Server neu geschrieben. Machen Sie also vor dem Start Backups.
Profitieren!
quelle
git filter-branch --index-filter
zur Arbeit kommen. Normalerweise erhalte ich die Fehlermeldung, dass die neue Indexdatei nicht vorhanden ist. Läutet das irgendwelche Glocken?git-add-repo.sh
mit der obigen Funktion erstellen , am Ende der Datei setzen Sie diese Zeilegit-add-repo "$@"
. Danach können Sie es von zsh wiecd current/git/package
undbash path/to/git-add-repo.sh https://github.com/example/example dir/to/save
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"
schlägt manchmal fehl, daher müssen Sie eine hinzufügenif test
.Befolgen Sie die Schritte, um ein Repo in ein anderes Repo einzubetten, indem Sie einen einzelnen Git-Verlauf erstellen, indem Sie beide Git-Verlaufs zusammenführen.
my/new/subdir
(3 Vorkommen) durch die Verzeichnisstruktur, in der Sie das untergeordnete Repo haben möchten.Wenn Sie das Git-Protokoll jetzt im übergeordneten Repo überprüfen, sollten die untergeordneten Repo-Commits zusammengeführt werden. Sie können auch das Tag sehen, das von der Commit-Quelle angezeigt wird.
Der folgende Artikel hat mir geholfen, ein Repo in ein anderes Repo einzubetten und einen einzigen Git-Verlauf zu haben, indem beide Git-Verlaufs zusammengeführt wurden.
http://ericlathrop.com/2014/01/combining-git-repositories/
Hoffe das hilft. Viel Spaß beim Codieren!
quelle
git filter-branch --prune-empty --tree-filter ' if [ ! -e my/new/subdir ]; then mkdir -p my/new/subdir; git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files my/new/subdir; fi'
Sagen Sie bitte Repository zusammenführen möchten
a
inb
(Ich gehe davon aus sie nebeneinander angeordnet sind):Wenn Sie
a
ein Unterverzeichnis erstellen möchten, gehen Sie vor den obigen Befehlen wie folgt vor:Hierfür müssen Sie
git-filter-repo
installiert haben (filter-branch
wird davon abgeraten ).Ein Beispiel für das Zusammenführen von zwei großen Repositorys, wobei eines davon in einem Unterverzeichnis abgelegt wird: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731
Mehr dazu hier .
quelle