서브 모듈 추가하기
아래와 같은 2개의 별개 코드를 포함한 프로젝트를 생성하고자 할 경우,
- shot 프로젝트
- stick 코드
- band 코드
다른 저장소에 있는paper
이라는 프로젝트를 shot
저장소에 서브모듈로 추가하려고 할 경우, 아래와 같이 git submodule add <repository> [path]
을 사용하여 submodule을 add하면 됩니다.
git submodule add https://github.com/<user>/paper paper
git status
를 확인해보면, .gitmodule
과 paper
폴더가 추가된 것을 확인할 수 있고, .gitmodule
에는 git에서 관리되는 서브모듈에 정보가 들어있고, 아래 내용이 추가됩니다.
[submodule "paper"]
path = paper
url = https://github.com/<user>/paper.git
branch = master
.git/config
에도 아래 내용이 추가됩니다.
[submodule "paper"]
url = https://github.com/<user>/paper.git
이 때 shot
에는 paper
라 폴더가 생성되지만, 그 안에는 아무것도 없기 때문에, submodule update를 사용하여 paper
의 내용을 명시적으로 다운로드합니다 (새버전 git에서는 자동 다운로드합니다)
git submodule update --init --recursive
모든 것이 잘 되었다면, 변경점을 커밋하고 paper
폴더를 shot
저장소에 추가합니다.
gitHub
에 paper
폴더 아이콘에 작은 표시를 붙여 이것이 서브모듈임을 나타냅니다.
서브모듈로 변경하기
magician
이라는 신규 프로젝트를 시작하기로 했는데, 여기서 band
가 유용하다고 가정합니다.shot
을 위해 만든 band
를 독립적인 저장소로 분리한 후, 두 개의 프로젝트에 서브로 추가해 보겠습니다.
band
를 shot
에서 추출하려면, git filter-branch
명령으로 band
관련된 커밋만 남길 수 있습니다.
이는 저장소 이력을 재작성하여 band
가 원래 저장소에 포함되지 않은 것처럼 보이게 합니다.
(참고: https://help.github.com/articles/splitting-a-subfolder-out-into-a-new-repository/)
1. A이름의 local 저장소 생성
shot
안의 band
를 자체 저장소로 동작하게 하기 위해 shot
복사본을 band
이름으로 생성합니다.
cd ..
cp -r shot band
2. A관련 폴더 및 히스토리만 추출
이제 band
폴더의 파일과 커밋 히스토리만 남깁니다.
사용 방법은 git filter-branch --subdirectory-filter <folder name> <branch name>
입니다.
cd band
git filter-branch --subdirectory-filter band -- --all
3. A 이름의 remote 저장소 생성 및 update
github에서 band
라는 새로운 저장소를 만들고 remote를 band
로 update합니다.
git remote -v
git remote set-url origin https://github.com/<user>/band
git push -u origin master
4. 원본 저장소에서 A 폴더 삭제
shot
저장소에서 band
폴더를 삭제한다
git rm -r band
git commit -m "Remove band (preparing for submodule)"
5. A를 부모 저장소에 submodule로 추가
shot
에 band
를 서브모듈로 만듭니다
git submodule add https://github.com/<user>/band band
git commit -m "band submodule"
이제, 부모 저장소인 shot', 두개의 서브 저장소인
paper과
band`를 포함한 세개의 저장소가 됩니다.
shot
히스토리를 보면, band
가 폴더일때 만들었던 커밋들이 남아있습니다.
즉, 폴더를 삭제하더라도 히스토리가 삭제되지 않습니다.
submodule을 잘못 생성한 경우,
삭제는 deinit 명령으로 해당 모듈을 초기화하고, rm 명령으로 해당 폴더를 삭제후, git rm 명령으로 git에서도 해당 폴더를 제거합니다.
git submodule deinit -f band
rm -rf .git/modules/band
git rm -f band
submodule을 최신 버전으로 update한후, master를 push
cd band
git pull
git status
git add band
git commit -m "updated band"
git push
협업시 주의할 점은
이 시점에 협업자들이 shot
을 pull하게 되면, band
는 비어있게 됩니다.
따라서, 협업자들이 아래 명령을 실행하여, 서브모듈 내 모든 내용을 다운로드해야 합니다.
git submodule update --init --recursive
band
를 magician
에 서브모듈로 추가하고 싶다면 shot
에 paper
을 추가한 것처럼 반복하면 됩니다.
cd ~/projects/magician
git submodule add https://github.com/<user>/band band
git commit -m "band submodule"
git submodule update --init --recursive
부모 repo에서 자식 프로젝트 작업시 주의할 점은
자식 프로젝트 작업후, 리모트에 커밋하지 않고 git submodule update
하면,
부모 repo가 참조하는 커밋으로 체크아웃되어, 작업 내용이 삭제됩니다!!
커밋만 하고 푸시하지 않은 상태라면, 로컬 커밋에서 찾을 수 도 있습니다/
하지만, 별도 브랜치가 없으면 찾기 어려게 됩니다.
따라서, 부모 repo에서 자식 프로젝트 작업시, 반드시 별도 브랜치를 따서 작업할 것을 추천합니다.
submodule상태 확인
submoudle status명령은 현재 sub 모듈이 가리키는 커밋 상태를 확인합니다.
git submodule status
'작업 tools > git' 카테고리의 다른 글
gitignore not working (0) | 2023.04.07 |
---|---|
git 커밋: 특정 커밋 돌아가기, 되돌리기, 차이 확인하기, 날짜 바꾸기, 이슈처리 (0) | 2021.10.08 |
git 저장소: 복제하기, 합치기, 변경하기 (0) | 2021.09.26 |
git 브랜치: 가져오기, 합치기, 삭제하기 (0) | 2021.09.26 |
개인 억세스 토큰사용하여 사용자 인증 진행하기 (1) | 2021.08.18 |