2015-01-29 3 views

답변

8

다음 bash 스크립트는 Alexander Mikhailian의 게시물 (http://mikhailian.mova.org/node/233)을 기반으로합니다. read-tree 대신 subtree add을 호출하기 위해 약간 수정했습니다. .gitmodule에서 서브 모듈 목록을 가져오고 모듈의 접두사, 이름 및 URL을 추출합니다. 그런 다음 각 하위 모듈을 제거하고 같은 위치의 하위 트리로 다시 추가합니다. 당신이를 가져올 경우 당신은 --squash 인수를 제거 할 수 있습니다 나중에

(즉 git subtree pull -P Foo Foo master --squash 대신 git subtree pull -P Foo https://example.com/foo.git master --squash의) 대신 URL의 이름을 제공하여 서브 트리를 업데이트 할 수 있도록 그것은 또한 원격으로 각 서브 모듈의 원격 추가 저장소에 하위 트리의 전체 내역. --squash을 사용하면 하위 트리의 머리글 만 저장소로 가져옵니다. 이것은 아마도 대부분의 사람들이 원하는 것이어야합니다.

자세한 내용은, 당신은 골드 피처에 의해이 게시물을 읽을 수 있습니다 : @GaspardP에 의해 수정 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

모든 지점에서 이러한 변환을 수행하는 방법의 예는 여기에서 찾을 수 있습니다; 전환 코드가 약간 수정되었습니다. 내 미러링 목적을위한 몇 가지 추가 코드가 있습니다.이를 무시하거나 자유롭게 사용하십시오. https://github.com/eallik/curry-kics2-sync –

+1

모든 명령을 에코하는 대신에 예를 들어를 사용하는 것이 좋습니다. ''#!/bin/bash -x''를 shebang으로 사용하십시오. –

+2

murl = $ (echo $ i | cut -d \ = -f2 | xargs) 을 사용하여 서브 모듈 줄의 공간이 없으면 서브 모듈 줄의 URL을 추출 할 수 없습니다. 은 더 안전합니다. – Wuvist

4

알렉산더 Mikhailian의 스크립트가 나를 위해 작동하지 않았다.

수정하여 개선했습니다. 이제 새 하위 트리는 이전 서브 모듈과 동일한 커밋을 가리 킵니다. 이전에는 스크립트가 대상 저장소에서 최신 커밋을 다운로드하기 만하면 호환성 문제가 발생할 수있었습니다.

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. 이 스크립트를 약간 조정해야했습니다. 어떤 이유로 든,'서브 모듈 상태'가 리턴하는 커밋 이름에는 그것에 하이픈 ('-')이 붙어있다. 나는 그 줄 끝에 "cut -d"- "-f2"를 추가하여 조각을 잘라야했습니다. –

관련 문제