Convert Git submodule to subtree

后端 未结 2 1571
再見小時候
再見小時候 2021-02-01 22:04

How can I convert a git submodule (with a folder in the local file system as a remote) to a git subtree, preferably preserving the commit history of the submodule?

2条回答
  •  独厮守ぢ
    2021-02-01 22:42

    The following bash script is based on Alexander Mikhailian's post (http://mikhailian.mova.org/node/233). I modified it slightly to call subtree add instead of read-tree. It will fetch the list of submodules from the .gitmodule and extract the module's prefix, name and url. It then removes each submodule and adds them back as a subtree at the same location. It also adds the remote of each submodule as a remote so you can update the subtree by providing its name instead of its url later on (i.e. git subtree pull -P Foo Foo master --squash instead of git subtree pull -P Foo https://example.com/foo.git master --squash)

    You may remove the --squash argument if you want to import the full history of the subtree to your repository. With --squash, will only import the head of the subtree into your repository. This should probably be what most people want.

    For more information, you may want to read this post by 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
    

提交回复
热议问题