2015-01-29 10 views

Antwort

8

Das folgende Bash-Skript basiert auf Alexander Mikhailis Beitrag (http://mikhailian.mova.org/node/233). Ich änderte es leicht, um subtree add anstelle von read-tree zu benennen. Es wird die Liste der Submodule aus der .gitmodule abrufen und das Präfix, den Namen und die URL des Moduls extrahieren. Es entfernt dann jedes Submodul und fügt sie als Teilbaum an der gleichen Stelle wieder hinzu. Es fügt auch die Fernbedienung jedes Modul als Remote, so dass Sie den Teilbaum statt dessen URL, indem sie ihren Namen später aktualisieren kann (dh git subtree pull -P Foo Foo master --squash statt git subtree pull -P Foo https://example.com/foo.git master --squash)

Sie können das --squash Argument entfernen, wenn Sie das importierende vollständige Geschichte des Teilbaums zu Ihrem Repository. Mit --squash wird nur der Kopf des Unterbaums in Ihr Repository importiert. Dies sollte wahrscheinlich sein, was die meisten Leute wollen.

Für weitere Informationen, können Sie diesen Beitrag von Atlassian lesen möchten: http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/

#!/bin/bash -x 
# extract the list of submodules from .gitmodule 
cat .gitmodules |while read i 
do 
if [[ $i == \[submodule* ]]; then 
    echo converting $i 

    # extract the module's prefix 
    mpath=$(echo $i | cut -d\" -f2) 

    # skip two lines 
    read i; read i; 

    # extract the url of the submodule 
    murl=$(echo $i|cut -d\= -f2|xargs) 

    # extract the module name 
    mname=$(basename $mpath) 

    # deinit the module 
    git submodule deinit $mpath 

    # remove the module from git 
    git rm -r --cached $mpath 

    # remove the module from the filesystem 
    rm -rf $mpath 

    # commit the change 
    git commit -m "Removed $mpath submodule" 

    # add the remote 
    git remote add -f $mname $murl 

    # add the subtree 
    git subtree add --prefix $mpath $mname master --squash 

    # fetch the files 
    git fetch $murl master 
fi 
done 
git rm .gitmodules 
+0

ein Beispiel dafür, wie diese Konvertierungen auf alle Branchen zu tun, sind hier zu finden; der Conversion-Code wurde leicht angepasst; Es gibt auch einen zusätzlichen Code für meine Spiegelungszwecke - ignoriere ihn oder fühle mich frei, ihn zu benutzen. https://github.com/eallik/curry-kics2-sync –

+1

Anstatt alle Befehle zu wiederholen, die Sie vielleicht in Erwägung ziehen, z. '' #!/bin/bash -x'' als Shebang. –

+2

Der Auszug die URL der Submodullinie wird nicht funktionieren, wenn Speicherplatz von Submodul URL fehlt, mit murl = $ (echo $ i | geschnitten -d \ = -f2 | xargs) wird sicherer – Wuvist

4

Alexander Mikhailian Drehbuch von @GaspardP geändert nicht für mich nicht funktioniert.

Ich modifizierte es und machte eine Verbesserung. Jetzt zeigen die neuen Teilbäume auf das gleiche Commit wie die alten Submodule. Zuvor wurde das Skript einfach die neuesten Commits von den Ziel-Repositorys herunterladen, was möglicherweise Kompatibilitätsprobleme zur Folge hatte.

https://gist.github.com/Nikita240/0c98cea8f53a15e69699cd8bc40657c4

#!/bin/bash -x 
# This script will convert all your git submodules into git subtrees. 
# This script ensures that your new subtrees point to the same commits as the 
# old submodules did, unlike most other scripts that do this. 
# THIS SCRIPT MUST BE PLACED OUTSIDE OF YOUR REPOSITORY!!!!!!!!!! 
# Otherwise, the script will interfere with the git commits. 
# Save the script in your home directory as `~/subtrees.sh` 
# `cd` into your repository 
# Run `~/subtrees.sh` 
# Enjoy! 

# extract the list of submodules from .gitmodule 
cat .gitmodules |while read i 
do 
if [[ $i == \[submodule* ]]; then 
    echo converting $i 

    read i 

    # extract the module's prefix 
    mpath=$(echo $i | grep -E "(\S+)$" -o) 

    echo path: $mpath 

    read i 

    # extract the url of the submodule 
    murl=$(echo $i|cut -d\= -f2|xargs) 

    echo url: $murl 

    # extract the module name 
    mname=$(basename $mpath) 

    echo name: $mname 

    # extract the referenced commit 
    mcommit=$(git submodule status $mpath | grep -E "\S+" -o | head -1) 

    echo commit: $mcommit 

    # deinit the module 
    git submodule deinit $mpath 

    # remove the module from git 
    git rm -r --cached $mpath 

    # remove the module from the filesystem 
    rm -rf $mpath 

    # commit the change 
    git commit -m "Removed $mpath submodule at commit $mcommit" 

    # add the remote 
    git remote add -f $mname $murl 

    # add the subtree 
    git subtree add --prefix $mpath $mcommit --squash 

    # commit any left over uncommited changes 
    git commit -a -m "$mname cleaned up" 

    # fetch the files 
    git fetch $murl master 

    echo 
fi 
done 
git rm .gitmodules 
git commit -a -m "Removed .gitmodules" 
+2

+1. Ich musste dieses Skript nur ein wenig optimieren; Aus irgendeinem Grund hatte der Commit-Name, den 'git submodule status 'zurückgab, einen führenden Bindestrich (' -'). Ich musste am Ende dieser Zeile ein "cut -d" - "-f2" hinzufügen, um es abzuschneiden. –