493 Stimmen

Wie kann man ein Git-Submodul aufheben?

Was sind die besten Praktiken für die Aufhebung der Submodulierung eines Git-Submoduls, um den gesamten Code zurück in das Kern-Repository zu bringen?

12voto

dvicino Punkte 1459

Es ist uns passiert, dass wir 2 Repositories für 2 Projekte erstellt haben, die so gekoppelt waren, dass es keinen Sinn machte, sie getrennt zu halten, also haben wir sie zusammengeführt.

Ich werde zeigen, wie man die Master-Zweige in jedem zuerst zusammenführt und dann werde ich erklären, wie man dies auf jeden Zweig, den man hat, ausdehnen kann, ich hoffe, es hilft Ihnen.

Wenn Sie das Submodul zum Laufen gebracht haben und es in ein Verzeichnis umwandeln wollen, können Sie das tun:

git clone project_uri project_name

Hier machen wir einen sauberen Klon zur Arbeit. Für diesen Prozess müssen Sie nicht initialisieren oder aktualisieren Sie die Submodule, so überspringen Sie es einfach.

cd project_name
vim .gitmodules

bearbeiten .gitmodules mit Ihrem Lieblingseditor (oder Vim), um das Submodul zu entfernen, das Sie ersetzen wollen. Die Zeilen, die Sie entfernen müssen, sollten in etwa wie folgt aussehen:

[submodule "lib/asi-http-request"]
    path = lib/asi-http-request
    url = https://github.com/pokeb/asi-http-request.git

Nach dem Speichern der Datei,

git rm --cached directory_of_submodule
git commit -am "Removed submodule_name as submodule"
rm -rf directory_of_submodule

Hier entfernen wir die Submodul-Beziehung vollständig, so dass wir das andere Repo an Ort und Stelle in das Projekt einbringen können.

git remote add -f submodule_origin submodule_uri
git fetch submodel_origin/master

Hier wird das Submodul-Repository abgerufen, das zusammengeführt werden soll.

git merge -s ours --no-commit submodule_origin/master

Hier starten wir einen Zusammenführungsvorgang der 2 Repositories, stoppen aber vor der Übergabe.

git read-tree --prefix=directory_of_submodule/ -u submodule_origin/master

Hier senden wir den Inhalt von master im Submodul in das Verzeichnis, in dem er sich vor dem Voranstellen eines Verzeichnisnamens befand

git commit -am "submodule_name is now part of main project"

Hier schließen wir die Prozedur ab, indem wir die Änderungen aus der Zusammenführung übertragen.

Nachdem Sie dies getan haben, können Sie die Änderungen pushen und mit einem beliebigen anderen Zweig neu beginnen. Checken Sie einfach den Zweig in Ihrem Repository aus, der die Änderungen erhalten soll, und ändern Sie den Zweig, den Sie in die Merge- und Read-Tree-Operationen bringen.

6voto

dataless Punkte 388

Hier ist eine leicht verbesserte Version (IMHO) der Antwort von @gyim. Er nimmt einen Haufen gefährlicher Änderungen an der Hauptarbeitskopie vor. Ich denke, dass es viel einfacher ist, mit separaten Klonen zu arbeiten und sie dann am Ende zusammenzuführen.

Prüfen Sie in einem separaten Verzeichnis (um Fehler leichter bereinigen und erneut versuchen zu können) sowohl das Top-Repo als auch das Sub-Repo.

git clone ../main_repo main.tmp
git clone ../main_repo/sub_repo sub.tmp

Bearbeiten Sie zunächst das Subrepo, um alle Dateien in das gewünschte Unterverzeichnis zu verschieben

cd sub.tmp
mkdir sub_repo_path
git mv `ls | grep -v sub_repo_path` sub_repo_path/
git commit -m "Moved entire subrepo into sub_repo_path"

Notieren Sie sich den HEAD

SUBREPO_HEAD=`git reflog | awk '{ print $1; exit; }'`

Entfernen Sie nun die Subrepo aus der Hauptrepo

cd ../main.tmp
rmdir sub_repo_path
vi .gitmodules  # remove config for submodule
git add -A
git commit -m "Removed submodule sub_repo_path in preparation for merge"

Und schließlich fügen Sie sie einfach zusammen

git fetch ../sub.tmp
# remove --allow-unrelated-histories if using git older than 2.9.0
git merge --allow-unrelated-histories $SUBREPO_HEAD

Und fertig! Sicher und ganz ohne Zauberei.

6voto

Luke H Punkte 2977

Die beste Antwort auf diese Frage habe ich hier gefunden:

http://x3ro.de/2013/09/01/Integrating-a-submodule-into-the-parent-repository.html

Dieser Artikel erklärt das Verfahren sehr gut.

3voto

brandones Punkte 1637

Denn wenn

git rm [-r] --cached submodule_path

gibt zurück.

fatal: pathspec 'emr/normalizers/' did not match any files

Kontext: Ich habe rm -r .git* in meinen Submodul-Ordnern, bevor ich merkte, dass sie im Hauptprojekt, dem ich sie gerade hinzugefügt hatte, de-submoduled werden mussten. Ich bekam den oben genannten Fehler, als ich einige, aber nicht alle, de-submodulierte. Wie auch immer, ich habe sie repariert, indem ich (natürlich nach dem rm -r .git* )

mv submodule_path submodule_path.temp
git add -A .
git commit -m "De-submodulization phase 1/2"
mv submodule_path.temp submodule_path
git add -A .
git commit -m "De-submodulization phase 2/2"

Beachten Sie, dass dadurch die Geschichte nicht erhalten bleibt.

3voto

void.pointer Punkte 22971

Basierend auf VonCs Antwort Ich habe ein einfaches Bash-Skript erstellt, das diese Aufgabe übernimmt. Die add am Ende muss Wildcards verwenden, sonst wird die vorherige Eingabe rückgängig gemacht rm für das Submodul selbst. Es ist wichtig, die Inhalt des Submodulverzeichnisses zu benennen und nicht das Verzeichnis selbst in der Datei add Befehl.

In einer Datei namens git-integrate-submodule :

#!/usr/bin/env bash
mv "$1" "${1}_"
git submodule deinit "$1"
git rm "$1"
mv "${1}_" "$1"
git add "$1/**"

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