Frage Wie machst du zwei Git-Repositories zusammen?


Stellen Sie sich das folgende Szenario vor:

Ich habe ein kleines experimentelles Projekt A in seinem eigenen Git Repo entwickelt. Es ist jetzt gereift, und ich möchte, dass A Teil des größeren Projekts B ist, das sein eigenes großes Repository hat. Ich möchte jetzt A als Unterverzeichnis von B hinzufügen.

Wie füge ich A in B zusammen, ohne Geschichte auf irgendeiner Seite zu verlieren?


1220
2017-09-15 08:31


Ursprung


Antworten:


Ein einzelner Zweig eines anderen Repositorys kann leicht unter einem Unterverzeichnis platziert werden, das seinen Verlauf behält. Beispielsweise:

git subtree add --prefix=rails git://github.com/rails/rails.git master

Dies wird als ein einzelner Commit angezeigt, bei dem alle Dateien des Rails-Master-Zweigs zum "rails" -Verzeichnis hinzugefügt werden. Der Titel des Commits enthält jedoch einen Verweis auf den alten Verlaufsbaum:

Fügen Sie 'rails /' von commit hinzu <rev>

Woher <rev> ist ein SHA-1-Commit-Hash. Sie können immer noch die Geschichte sehen, einige Änderungen verantwortlich machen.

git log <rev>
git blame <rev> -- README.md

Beachten Sie, dass Sie das Verzeichnis-Präfix von hier nicht sehen können, da dies ein tatsächlich alter Zweig ist, der intakt geblieben ist. Sie sollten dies wie ein gewöhnliches File-Move-Commit behandeln: Sie benötigen einen zusätzlichen Sprung, wenn Sie es erreichen.

# finishes with all files added at once commit
git log rails/README.md

# then continue from original tree
git log <rev> -- README.md

Es gibt komplexere Lösungen, z. B. manuell oder den Verlauf neu schreiben, wie in anderen Antworten beschrieben.

Der Befehl git-subtree ist Teil des offiziellen git-contrib, einige Paketmanager installieren ihn standardmäßig (OS X Homebrew). Aber Sie müssen es möglicherweise zusätzlich zu Git installieren.


326
2018-02-20 23:44



Wenn Sie zusammenführen möchten project-a in project-b:

cd path/to/project-b
git remote add project-a path/to/project-a
git fetch project-a
git merge --allow-unrelated-histories project-a/master # or whichever branch you want to merge
git remote remove project-a

Genommen von: Git verschiedene Repositories zusammenführen?

Diese Methode hat für mich sehr gut funktioniert, sie ist kürzer und meiner Meinung nach viel sauberer.

Hinweis: Das --allow-unrelated-histories Parameter existiert nur seit git> = 2.9. Sehen Git - git merge Dokumentation / --allow-unrelated-histories 


1279
2018-05-11 09:37



Hier sind zwei mögliche Lösungen:

Submodule

Kopieren Sie entweder das Repository A in ein separates Verzeichnis im größeren Projekt B oder klonen Sie Repository A in das Unterverzeichnis in Projekt B. git Submodul um dieses Repository zu machen Submodul eines Repositorys B.

Dies ist eine gute Lösung für lose gekoppelte Repositories, bei denen die Entwicklung in Repository A fortgesetzt wird, und ein wesentlicher Teil der Entwicklung ist eine separate eigenständige Entwicklung in A. Siehe auch SubmodulSupport und GitSubmoduleTutorial Seiten auf Git Wiki.

Teilbaum zusammenführen

Sie können das Repository A mit Hilfe des Verzeichnisses in ein Unterverzeichnis eines Projekts B zusammenführen Teilbaum zusammenführen Strategie. Dies wird in beschrieben Subtree Merging und Sie von Markus Prinz.

git remote add -f Bproject /path/to/B
git merge -s ours --allow-unrelated-histories --no-commit Bproject/master
git read-tree --prefix=dir-B/ -u Bproject/master
git commit -m "Merge B project as our subdirectory"
git pull -s subtree Bproject master

(Möglichkeit --allow-unrelated-histories wird benötigt für git> = 2.9.0)

Oder du kannst es benutzen Git Unterbaum Werkzeug (Repository auf GitHub) von apenwarr (Avery Pennarun), angekündigt zum Beispiel in seinem Blogpost Eine neue Alternative zu Git Submodulen: git subtree.


Ich denke in Ihrem Fall (A ist Teil eines größeren Projekts B) wäre die richtige Lösung zu verwenden Teilbaum zusammenführen


581
2017-09-15 08:38



Der Submodulansatz ist gut, wenn Sie das Projekt separat pflegen wollen. Wenn Sie jedoch beide Projekte in dasselbe Repository zusammenführen möchten, müssen Sie etwas mehr tun.

Das erste wäre, zu benutzen git filter-branch Um die Namen von allem im zweiten Repository neu zu schreiben, um in dem Unterverzeichnis zu sein, in dem sie enden sollen. Also statt foo.c, bar.html, du würdest haben projb/foo.c und projb/bar.html.

Dann sollten Sie in der Lage sein, Folgendes zu tun:

git remote add projb [wherever]
git pull projb

Das git pull werde tun git fetch gefolgt von einem git merge. Es sollte keine Konflikte geben, wenn das Repository, an das Sie ziehen, noch nicht über eine projb/ Verzeichnis.

Weitere Suche zeigt an, dass etwas Ähnliches zum Zusammenführen gemacht wurde gitk in git. Junio ​​C Hamano schreibt darüber hier: http://www.mail-archive.com/git@vger.kernel.org/msg03395.html


187
2018-02-01 08:10



git-subtree ist nett, aber es ist wahrscheinlich nicht derjenige, den Sie wollen.

Zum Beispiel, wenn projectA ist das in B erstellte Verzeichnis nach git subtree,

git log projectA

Listen einziger commit: die Zusammenführung. Die Commits des zusammengeführten Projekts gelten für verschiedene Pfade, sodass sie nicht angezeigt werden.

Greg Hewgills Antwort kommt ihr am nächsten, obwohl sie nicht sagt, wie man die Wege umschreiben soll.


Die Lösung ist überraschend einfach.

(1) In A,

PREFIX=projectA #adjust this

git filter-branch --index-filter '
    git ls-files -s |
    sed "s,\t,&'"$PREFIX"'/," |
    GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info &&
    mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE
' HEAD

Hinweis: Dadurch wird der Verlauf neu geschrieben. Wenn Sie also diesen Repo A weiter verwenden möchten, möchten Sie möglicherweise zuerst eine Wegwerfkopie kopieren (kopieren).

(2) Dann in B, lauf

git pull path/to/A

Voila! Du hast ein projectA Verzeichnis in B. Wenn Sie laufen git log projectA, Sie werden alle Commits von A sehen.


In meinem Fall wollte ich zwei Unterverzeichnisse, projectA und projectB. In diesem Fall habe ich auch Schritt (1) nach B getan.


62
2018-06-11 14:31



Wenn beide Repositorys die gleiche Art von Dateien haben (wie zwei Rails-Repositories für unterschiedliche Projekte), können Sie Daten des sekundären Repositorys in Ihr aktuelles Repository holen:

git fetch git://repository.url/repo.git master:branch_name

und dann zum aktuellen Repository zusammenführen:

git merge --allow-unrelated-histories branch_name

Wenn Ihre Git-Version kleiner als 2,9 ist, entfernen Sie sie --allow-unrelated-histories.

Danach können Konflikte auftreten. Sie können sie zum Beispiel mit lösen git mergetool. kdiff3 kann nur mit Tastatur verwendet werden, also 5 Konflikt Datei dauert beim Lesen des Codes nur wenige Minuten.

Denken Sie daran, die Zusammenführung zu beenden:

git commit

39
2018-02-27 03:09



Ich habe immer wieder Geschichte verloren, als ich Merge benutzt habe, und deshalb habe ich Rebase verwendet, da in meinem Fall die beiden Repositories unterschiedlich genug sind, um nicht bei jedem Commit zu verschmelzen:

git clone git@gitorious/projA.git projA
git clone git@gitorious/projB.git projB

cd projB
git remote add projA ../projA/
git fetch projA 
git rebase projA/master HEAD

=> Konflikte lösen, dann so oft wie nötig fortfahren ...

git rebase --continue

Dies führt dazu, dass ein Projekt alle Commits von projA hat, gefolgt von commits von projB


19
2017-08-18 21:06