Aufteilung eines Unterverzeichnisses mit Submodule in ein separates Git -Repository

StackOverflow https://stackoverflow.com/questions/3411364

  •  25-09-2019
  •  | 
  •  

Frage

Als Teilmenge der Frage Abschlüsse Bereits zuvor gemacht und unter Berücksichtigung der Tatsache, dass ich, obwohl viele Fragen zur Aufteilung und Verschmelzung von Git -Repositorys gestellt wurden, nicht finden konnte, das das Thema der Aufteilung berührt, wenn Submodule vorhanden sind.

Also im folgenden Szenario:

.git/
.gitmodules
folder/
    data/
    content/
        other_data/
        submoduleA/
        submoduleB/

Ich möchte zwei Repositorys mit der folgenden Struktur bekommen:

.git/
data/

und

.git/
.gitmodules
content/
    other_data/
    submoduleA/
    submoduleB/

Der erste Fall ist kein Problem und kann mit der in beschriebenen Methode leicht gelöst werden Abschlüsse.

Die zweite nicht so sehr. Die Existenz von Submodules und die Tatsache, dass .Gitmodules den vollen Weg für folder/content/submoduleA und folder/content/submoduleB bewirkt, dass ein Teil der Geschichte inkonsistent ist, da sich .gitmodules auf eine nicht vorhandene Verzeichnisstruktur bezieht (sobald die Filterbranch verwendet wird).

Ich würde gerne wissen, ob es eine Möglichkeit gibt, dies zu tun, ohne eine inkonsistente Geschichte zu verursachen.

War es hilfreich?

Lösung

Ich vermute (nicht getestet), dass eine Sekunde git filter-branch hätte die Möglichkeit, die zu ändern .gitmodules Inhalt für jeden Commit des neuen Repo.

Aber eigentlich ein git submodule split Das Kommando war Anfang 2009 in Diskussion.

Vorgeschlagene Verwendung:

git submodule split [--url submodule_repo_url] submodule_dir \
    [alternate_dir...]

Ersetzen submodule_dir mit einem neu geschaffenen Submodul, die die gesamte Geschichte von behalten submodule_dir.
Dieser Befehl schreibt auch jeden Commit im aktuellen Repository -Verlauf um, um die korrekte Überarbeitung von zu enthalten sumodule_dir und die angemessen .gitmodules Einträge.

Ich sehe es jedoch nicht in der LETZT, was kocht.
Das Skript im vorgeschlagenen Patch kann Ihnen eine Vorstellung von der Art des Umschreibens für die Aktualisierung des Baumes geben .gitmodules Datei jedoch.

Andere Tipps

Ich hatte genau das gleiche Problem wie Unode und gelang es, es mit der folgenden Prozedur zu lösen:

git clone git@github.com:kdeldycke/kev-code.git
cd kev-code
git filter-branch --tree-filter "test -f ./.gitmodules && mv ./.gitmodules ./cool-cavemen/gitmodules || echo 'No .gitmodules file found'" -- --all
git filter-branch --force --prune-empty --subdirectory-filter cool-cavemen --tag-name-filter cat -- --all init..HEAD
git filter-branch --force --tree-filter "test -f ./gitmodules && mv ./gitmodules ./.gitmodules || echo 'No gitmodules file found'" -- --all
git filter-branch --force --tree-filter "test -f ./.gitmodules && sed -i 's/cool-cavemen\///g' ./.gitmodules || echo 'No .gitmodules file found'" -- --all
git remote rm origin
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
git remote add origin git@github.com:kdeldycke/cool-cavemen.git
git push -u origin master --force --tags

Wie Sie sehen, besteht der Trick darin, die vorübergehend umzubenennen .gitmodules Datei und Verwendung sed Um seinen Inhalt neu zu schreiben. Sie können alle Details und die erhalten Kontext dieses Prozesses in meinem Blog.

Um Kevins Antwort zu erläutern: Angenommen, es gab keine Submodules jemals draußen cool/cavemen - Der Ordner, der abgelöst wird (ansonsten aufwändigere Bearbeitung von .gitmodules wird benötigt, um diese zusätzlichen Abschnitte zu entfernen), kann dies erreicht werden viel schneller und in einem Schritt mit einem index-filter:

$ git filter-branch --subdirectory-filter cool/cavemen --index-filter $'
hash=$(git rev-parse --verify $GIT_COMMIT:.gitmodules 2>/dev/null) &&
 git update-index --add --cacheinfo 100644 $(git cat-file -p $hash |
 sed \'s/cool\\/cavemen\\///g\' | git hash-object -w --stdin) .gitmodules ||
true' --tag-name-filter cat --prune-empty -- --all

Als zusätzlicher Vorteil, wenn cool/cavemen existierte nicht in jeder Revision oder Niederlass cool/cavemen wird betrachtet.

Wenn dies der Fall ist, möchten Sie möglicherweise Folgendes ausführen, um unveränderte Referenzen zu entfernen:

$ git for-each-ref --format='%(refname)' | 
 grep -vF "$(git for-each-ref --format='%(refname)' refs/original |
 sed 's/refs\/original\///g')" | xargs -n 1 git update-ref -d
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top