2015-01-29 8 views

risposta

8

Il seguente script bash si basa sul post di Alexander Mikhailian (http://mikhailian.mova.org/node/233). Ho modificato leggermente per chiamare subtree add invece di read-tree. Si recupererà l'elenco dei sottomoduli dal .gitmodule ed estrarre il prefisso, il nome e l'URL del modulo. Quindi rimuove ciascun sottomodulo e li aggiunge come sottostruttura nella stessa posizione. Si aggiunge anche il telecomando di ogni modulo come un telecomando in modo da poter aggiornare la sottostruttura fornendo il suo nome al posto dell'URL in seguito (cioè git subtree pull -P Foo Foo master --squash invece di git subtree pull -P Foo https://example.com/foo.git master --squash)

È possibile rimuovere l'argomento --squash se si desidera importare il cronologia completa della sottostruttura nel repository. Con --squash, verrà importato solo il capo della sottostruttura nel repository. Questo dovrebbe probabilmente essere ciò che la maggior parte della gente vuole.

Per ulteriori informazioni, si consiglia di leggere questo post di 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

un esempio di come fare queste conversioni su tutti i rami può essere trovato qui; il codice di conversione è stato leggermente adattato; c'è anche del codice extra per i miei scopi di mirroring: ignoralo o sentiti libero di usarlo. https://github.com/eallik/curry-kics2-sync –

+1

Invece di eco tutti i comandi si può prendere in considerazione l'utilizzo ad esempio '' #!/bin/bash -x'' come shebang. –

+2

L'estratto dell'URL della riga del sottomodulo non funzionerà se manca spazio dall'URL del sottomodulo, usando murl = $ (echo $ i | cut -d \ = -f2 | xargs) sarà più sicuro – Wuvist

4

sceneggiatura di Alexander Mikhailian modificato da @GaspardP non ha funzionato per me.

ho modificato, e ha fatto un miglioramento. Ora, le nuove sottostrutture punteranno allo stesso commit dei vecchi sottomoduli. In precedenza, lo script scaricava l'ultimo commit dai repository di destinazione, causando potenzialmente problemi di compatibilità.

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. Ho dovuto modificare questo script solo un po '; per qualsiasi motivo, il nome di commit che 'git submodule status' stava restituendo aveva un trattino principale (' -') in esso. Ho dovuto aggiungere un 'cut -d" - "-f2' alla fine di quella linea per troncarlo. –

Problemi correlati