583 Stimmen

Wie importiert man ein bestehendes Git-Repository in ein anderes?

Ich habe ein Git-Repository in einem Ordner namens XXX und ich habe ein zweites Git-Repository namens YYY .

Ich möchte die XXX Repository in das YYY Repository als ein Unterverzeichnis mit dem Namen ZZZ und fügen Sie alle XXX die Änderungshistorie zu YYY .

Ordnerstruktur vorher:

 XXX
    .git
    (project files)
 YYY
     .git
     (project files)

Ordnerstruktur nach:

YYY
 .git  <-- This now contains the change history from XXX
  ZZZ  <-- This was originally XXX
     (project files)
  (project files)

Ist dies möglich, oder muss ich auf Untermodule zurückgreifen?

508voto

ebneter Punkte 19247

Am einfachsten wäre es wohl, wenn Sie die XXX Sachen in eine Verzweigung in YYY und fügen Sie es dann in Master ein:

En YYY :

git remote add other /path/to/XXX
git fetch other
git checkout -b ZZZ other/master
mkdir ZZZ
git mv stuff ZZZ/stuff                      # repeat as necessary for each file/dir
git commit -m "Moved stuff to ZZZ"
git checkout master                
git merge ZZZ --allow-unrelated-histories   # should add ZZZ/ to master
git commit
git remote rm other
git branch -d ZZZ                           # to get rid of the extra branch before pushing
git push                                    # if you have a remote, that is

Ich habe das gerade mit ein paar meiner Repos ausprobiert und es funktioniert. Im Gegensatz zu Jörgs Antwort können Sie das andere Repository nicht weiter verwenden, aber ich glaube nicht, dass Sie das ohnehin angegeben haben.

Hinweis: Seit dies ursprünglich 2009 geschrieben wurde, hat Git die in der Antwort unten erwähnte Zusammenführung von Teilbäumen hinzugefügt. Ich würde heute wahrscheinlich diese Methode verwenden, obwohl diese Methode natürlich immer noch funktioniert.

405voto

ColinM Punkte 12601

Wenn Sie die exakte Commit-Historie des zweiten Repositorys beibehalten wollen und somit auch die Möglichkeit haben wollen, Upstream-Änderungen in Zukunft einfach zusammenzuführen, dann ist dies die richtige Methode für Sie. Sie führt dazu, dass die unveränderte Historie des Unterbaums in Ihr Projektarchiv importiert wird und ein Merge-Commit durchgeführt wird, um das zusammengeführte Projektarchiv in das Unterverzeichnis zu verschieben.

git remote add XXX_remote <path-or-url-to-XXX-repo>
git fetch XXX_remote
git merge -s ours --no-commit --allow-unrelated-histories XXX_remote/master
git read-tree --prefix=ZZZ/ -u XXX_remote/master
git commit -m "Imported XXX as a subtree."

Sie können Upstream-Änderungen wie folgt verfolgen:

git pull -s subtree XXX_remote master

Git findet vor dem Zusammenführen selbst heraus, wo die Wurzeln liegen, so dass Sie das Präfix bei späteren Zusammenführungen nicht mehr angeben müssen.

El Nachteil ist, dass die Dateien in der zusammengeführten Historie ohne Präfixe sind (nicht in einem Unterverzeichnis). Infolgedessen git log ZZZ/a zeigt Ihnen alle Änderungen (falls vorhanden) mit Ausnahme derjenigen in der zusammengeführten Historie. Das können Sie tun:

git log --follow -- a

aber dadurch werden die Änderungen nur in der zusammengeführten Historie angezeigt.

Mit anderen Worten: Wenn Sie nicht ändern ZZZ Dateien im Repository XXX dann müssen Sie Folgendes angeben --follow und einem nicht vorangestellten Pfad. Wenn Sie diese in beiden Repositories ändern, haben Sie 2 Befehle, von denen keiner alle Änderungen anzeigt.

Git-Versionen vor 2.9 : Sie müssen nicht die --allow-unrelated-histories Option zu git merge .

Die Methode in der anderen Antwort, die die read-tree und überspringt die merge -s ours Schritt ist im Grunde nichts anderes als das Kopieren der Dateien mit cp und das Übertragen des Ergebnisses.

Die Originalquelle stammt von github's "Teilbaum-Zusammenführung" Hilfe-Artikel . Und ein weiterer nützlicher Link .

176voto

kynan Punkte 12437

git-subtree ist ein Skript, das für genau diesen Anwendungsfall entwickelt wurde, nämlich das Zusammenführen mehrerer Repositories zu einem einzigen unter Beibehaltung der Historie (und/oder das Aufteilen der Historie von Teilbäumen, obwohl das für diese Frage irrelevant zu sein scheint). Es wird als Teil des Git-Baums verteilt seit Version 1.7.11 .

So führen Sie ein Repository zusammen <repo> bei Revision <rev> als Unterverzeichnis <prefix> を使用します。 git subtree add wie folgt:

git subtree add -P <prefix> <repo> <rev>

git-subtree implementiert die Teilbaum-Zusammenführungsstrategie in einer benutzerfreundlicheren Weise.

In Ihrem Fall würden Sie innerhalb des Repository YYY ausführen:

git subtree add -P ZZZ /path/to/XXX.git master

El Nachteil ist, dass die Dateien in der zusammengeführten Historie ohne Präfixe sind (nicht in einem Unterverzeichnis). Infolgedessen git log ZZZ/a zeigt Ihnen alle Änderungen (falls vorhanden) mit Ausnahme derjenigen in der zusammengeführten Historie. Das können Sie tun:

git log --follow -- a

aber dadurch werden die Änderungen nur in der zusammengeführten Historie angezeigt.

Mit anderen Worten: Wenn Sie nicht ändern ZZZ Dateien im Repository XXX dann müssen Sie Folgendes angeben --follow und einem nicht vorangestellten Pfad. Wenn Sie diese in beiden Repositories ändern, haben Sie 2 Befehle, von denen keiner alle Änderungen anzeigt.

Mehr dazu aquí .

52voto

Jörg W Mittag Punkte 349574

Ein bekanntes Beispiel hierfür ist das Git-Repository selbst, das in der Git-Gemeinschaft unter dem Namen " die coolste Verschmelzung aller Zeiten " (nach der Betreffzeile, die Linus Torvalds in der E-Mail an die Git-Mailingliste verwendet hat, die diese Zusammenführung beschreibt). In diesem Fall ist die gitk Git GUI, das jetzt Teil von Git selbst ist, war eigentlich ein separates Projekt. Linus hat es geschafft, dieses Repository in das Git-Repository einzubinden, und zwar so, dass

  • erscheint es im Git-Repository, als wäre es schon immer als Teil von Git entwickelt worden,
  • die gesamte Geschichte bleibt intakt und
  • kann es weiterhin unabhängig in seinem alten Repository entwickelt werden, wobei Änderungen einfach git pull Hrsg.

Die E-Mail enthält die Schritte, die für die Reproduktion erforderlich sind, aber sie ist nichts für schwache Nerven: Zunächst muss Linus schrieb Git, also weiß er wahrscheinlich ein bisschen mehr darüber als Sie oder ich, und zweitens war dies vor fast 5 Jahren und Git hat sich verbessert erheblich Seitdem ist es vielleicht viel einfacher geworden.

Heutzutage würde man in diesem speziellen Fall wohl ein gitk-Submodul verwenden.

19voto

x-yuri Punkte 13561

Ich möchte Namen verwenden a (anstelle von XXX y ZZZ ) und b (anstelle von YYY ), da die Beschreibung dadurch etwas leichter zu lesen ist.

Angenommen, Sie möchten das Repository zusammenführen a en b (Ich nehme an, sie befinden sich nebeneinander):

cd a
git filter-repo --to-subdirectory-filter a
cd ..
cd b
git remote add a ../a
git fetch a
git merge --allow-unrelated-histories a/master
git remote remove a

Hierfür benötigen Sie git-filter-repo installiert ( filter-branch est entmutigt ).

Ein Beispiel für das Zusammenführen von 2 großen Repositories, wobei eines davon in ein Unterverzeichnis gelegt wird: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731

Mehr dazu aquí .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X