2015-01-29 11 views

Odpowiedz

8

Poniższy skrypt bash oparty jest na poście Aleksandra Michaiła (http://mikhailian.mova.org/node/233). Zmodyfikowałem go nieznacznie, aby zadzwonić pod numer subtree add zamiast read-tree. Spowoduje to pobranie listy submodułów z .gitmodule i wyodrębnienie przedrostka modułu, nazwy i adresu URL. Następnie usuwa każdy moduł częściowy i dodaje je ponownie jako poddrzewa w tej samej lokalizacji. Dodaje również pilota każdego modułem jako pilota, dzięki czemu można zaktualizować poddrzewa poprzez dostarczanie jej nazwę zamiast jej adresu URL później (tj git subtree pull -P Foo Foo master --squash zamiast git subtree pull -P Foo https://example.com/foo.git master --squash)

Możesz usunąć --squash argument, jeśli chcesz zaimportować pełna historia poddrzewa do twojego repozytorium. Z --squash, zaimportuje tylko głowę poddrzewa do twojego repozytorium. To prawdopodobnie powinno być tym, czego większość ludzi chce.

Aby uzyskać więcej informacji na ten temat możesz przeczytać ten post przez Atlassian: 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

przykład jak zrobić te konwersje na wszystkich oddziałów można znaleźć tutaj; kod konwersji został nieco dostosowany; istnieje również dodatkowy kod do celów tworzenia kopii lustrzanych - zignoruj ​​go lub skorzystaj z niego. https://github.com/eallik/curry-kics2-sync –

+1

Zamiast powtarzać wszystkie polecenia, możesz rozważyć użycie np. '' #!/bin/bash -x'' jako shebang. –

+2

Wyodrębniony URL kodu modułu podstrony nie zadziała, jeśli brakuje miejsca w module kodu podjednostki, przy użyciu murl = $ (echo $ i | cut -d \ = -f2 | xargs) będzie bezpieczniejsze – Wuvist

4

skrypt Alexander Mikhailian jest modyfikowana przez @GaspardP nie działa dla mnie.

Zmodyfikowałem i ulepszyłem. Teraz nowe poddrzewa wskaże na to samo zatwierdzenie, co zrobiły stare submodules. Poprzednio skrypt po prostu pobierał najnowsze zatwierdzenia z docelowych repozytoriów, potencjalnie powodując problemy ze zgodnością.

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. Musiałem odrobinę poprawić ten skrypt; z jakiegoś powodu nazwa commit, która zwracała status "git submodule status" miała w sobie wiodący łącznik ('-'). Musiałem dodać 'cut-d" - "-f2' na końcu tej linii, aby ją uciąć. –

Powiązane problemy