git-submodule
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGit Submodule
Git Submodule
When to use this skill
何时使用该技能
- Including external Git repositories within your main project
- Managing shared libraries or modules across multiple projects
- Locking external dependencies to specific versions
- Working with monorepo-style architectures with independent components
- Cloning repositories that contain submodules
- Updating submodules to newer versions
- Removing submodules from a project
- 在主项目中引入外部Git仓库
- 在多个项目间管理共享库或模块
- 将外部依赖锁定到特定版本
- 处理包含独立组件的单体仓库风格架构
- 克隆包含子模块的仓库
- 将子模块更新到新版本
- 从项目中移除子模块
Instructions
操作指南
Step 1: Understanding submodules
步骤1:理解子模块
Git submodule은 메인 Git 저장소 내에 다른 Git 저장소를 포함시키는 기능입니다.
Key concepts:
- 서브모듈은 특정 커밋을 참조하여 버전을 고정합니다
- 파일에 서브모듈 경로와 URL이 기록됩니다
.gitmodules - 서브모듈 내 변경은 별도 커밋으로 관리됩니다
Git submodule是一种可以在主Git仓库中包含其他Git仓库的功能。
核心概念:
- 子模块通过引用特定提交来固定版本
- 子模块的路径和URL会记录在文件中
.gitmodules - 子模块内的变更会作为独立提交进行管理
Step 2: Adding submodules
步骤2:添加子模块
기본 추가:
bash
undefined基础添加:
bash
undefined서브모듈 추가
子模块添加
git submodule add <repository-url> <path>
git submodule add <repository-url> <path>
예: libs/lib 경로에 라이브러리 추가
示例: 在libs/lib路径下添加库
git submodule add https://github.com/example/lib.git libs/lib
**특정 브랜치 추적**:
```bashgit submodule add https://github.com/example/lib.git libs/lib
**跟踪特定分支**:
```bash특정 브랜치를 추적하도록 추가
添加时设置跟踪特定分支
git submodule add -b main https://github.com/example/lib.git libs/lib
**추가 후 커밋**:
```bash
git add .gitmodules libs/lib
git commit -m "feat: add lib as submodule"git submodule add -b main https://github.com/example/lib.git libs/lib
**添加后提交**:
```bash
git add .gitmodules libs/lib
git commit -m "feat: add lib as submodule"Step 3: Cloning with submodules
步骤3:克隆包含子模块的仓库
신규 클론 시:
bash
undefined首次克隆时:
bash
undefined방법 1: 클론 시 --recursive 옵션
方法1:克隆时使用--recursive选项
git clone --recursive <repository-url>
git clone --recursive <repository-url>
방법 2: 클론 후 초기화
方法2:克隆后初始化
git clone <repository-url>
cd <repository>
git submodule init
git submodule update
**한 줄로 초기화 및 업데이트**:
```bash
git submodule update --init --recursivegit clone <repository-url>
cd <repository>
git submodule init
git submodule update
**一键完成初始化和更新**:
```bash
git submodule update --init --recursiveStep 4: Updating submodules
步骤4:更新子模块
원격 최신 버전으로 업데이트:
bash
undefined更新到远程最新版本:
bash
undefined모든 서브모듈을 원격 최신으로 업데이트
将所有子模块更新到远程最新版本
git submodule update --remote
git submodule update --remote
특정 서브모듈만 업데이트
仅更新特定子模块
git submodule update --remote libs/lib
git submodule update --remote libs/lib
업데이트 + 머지
更新并合并
git submodule update --remote --merge
git submodule update --remote --merge
업데이트 + 리베이스
更新并变基
git submodule update --remote --rebase
**서브모듈 참조 커밋으로 체크아웃**:
```bashgit submodule update --remote --rebase
**切换到子模块引用的提交**:
```bash메인 저장소가 참조하는 커밋으로 서브모듈 체크아웃
将子模块切换到主仓库引用的提交
git submodule update
undefinedgit submodule update
undefinedStep 5: Working inside submodules
步骤5:在子模块内工作
서브모듈 내에서 작업:
bash
undefined在子模块目录内操作:
bash
undefined서브모듈 디렉토리로 이동
进入子模块目录
cd libs/lib
cd libs/lib
브랜치 체크아웃 (detached HEAD 해제)
切换分支(脱离分离头指针状态)
git checkout main
git checkout main
변경사항 작업
进行变更操作
... make changes ...
... make changes ...
서브모듈 내에서 커밋 및 푸시
在子模块内提交并推送
git add .
git commit -m "feat: update library"
git push origin main
**메인 저장소에서 서브모듈 변경 반영**:
```bashgit add .
git commit -m "feat: update library"
git push origin main
**在主仓库中同步子模块变更**:
```bash메인 저장소로 이동
返回主仓库
cd ..
cd ..
서브모듈 참조 업데이트
更新子模块引用
git add libs/lib
git commit -m "chore: update lib submodule reference"
git push
undefinedgit add libs/lib
git commit -m "chore: update lib submodule reference"
git push
undefinedStep 6: Batch operations
步骤6:批量操作
모든 서브모듈에 명령 실행:
bash
undefined对所有子模块执行命令:
bash
undefined모든 서브모듈에서 pull
在所有子模块中执行pull操作
git submodule foreach 'git pull origin main'
git submodule foreach 'git pull origin main'
모든 서브모듈에서 상태 확인
查看所有子模块的状态
git submodule foreach 'git status'
git submodule foreach 'git status'
모든 서브모듈에서 브랜치 체크아웃
在所有子模块中切换分支
git submodule foreach 'git checkout main'
git submodule foreach 'git checkout main'
중첩된 서브모듈에도 명령 실행
对嵌套子模块也执行命令
git submodule foreach --recursive 'git fetch origin'
undefinedgit submodule foreach --recursive 'git fetch origin'
undefinedStep 7: Removing submodules
步骤7:移除子模块
서브모듈 완전 제거:
bash
undefined完全移除子模块:
bash
undefined1. 서브모듈 등록 해제
1. 取消子模块注册
git submodule deinit <path>
git submodule deinit <path>
2. Git에서 제거
2. 从Git中移除
git rm <path>
git rm <path>
3. .git/modules에서 캐시 제거
3. 从.git/modules中删除缓存
rm -rf .git/modules/<path>
rm -rf .git/modules/<path>
4. 변경사항 커밋
4. 提交变更
git commit -m "chore: remove submodule"
**예시: libs/lib 제거**:
```bash
git submodule deinit libs/lib
git rm libs/lib
rm -rf .git/modules/libs/lib
git commit -m "chore: remove lib submodule"
git pushgit commit -m "chore: remove submodule"
**示例:移除libs/lib**:
```bash
git submodule deinit libs/lib
git rm libs/lib
rm -rf .git/modules/libs/lib
git commit -m "chore: remove lib submodule"
git pushStep 8: Checking submodule status
步骤8:查看子模块状态
상태 확인:
bash
undefined查看状态:
bash
undefined서브모듈 상태 확인
查看子模块状态
git submodule status
git submodule status
상세 상태 (재귀적)
查看详细状态(递归)
git submodule status --recursive
git submodule status --recursive
요약 정보
查看摘要信息
git submodule summary
**출력 해석**:44d7d1... libs/lib (v1.0.0) # 정상 (참조 커밋과 일치)
+44d7d1... libs/lib (v1.0.0-1-g...) # 로컬 변경 있음
-44d7d1... libs/lib # 초기화 안 됨
undefinedgit submodule summary
**输出说明**:44d7d1... libs/lib (v1.0.0) # 正常(与引用提交一致)
+44d7d1... libs/lib (v1.0.0-1-g...) # 存在本地变更
-44d7d1... libs/lib # 未初始化
undefinedExamples
示例
Example 1: 프로젝트에 외부 라이브러리 추가
示例1:向项目中添加外部库
bash
undefinedbash
undefined1. 서브모듈 추가
1. 添加子模块
git submodule add https://github.com/lodash/lodash.git vendor/lodash
git submodule add https://github.com/lodash/lodash.git vendor/lodash
2. 특정 버전(태그)으로 고정
2. 固定到特定版本(标签)
cd vendor/lodash
git checkout v4.17.21
cd ../..
cd vendor/lodash
git checkout v4.17.21
cd ../..
3. 변경사항 커밋
3. 提交变更
git add .
git commit -m "feat: add lodash v4.17.21 as submodule"
git add .
git commit -m "feat: add lodash v4.17.21 as submodule"
4. 푸시
4. 推送
git push origin main
undefinedgit push origin main
undefinedExample 2: 서브모듈 포함 저장소 클론 후 설정
示例2:克隆包含子模块的仓库后进行配置
bash
undefinedbash
undefined1. 저장소 클론
1. 克隆仓库
git clone https://github.com/myorg/myproject.git
cd myproject
git clone https://github.com/myorg/myproject.git
cd myproject
2. 서브모듈 초기화 및 업데이트
2. 初始化并更新子模块
git submodule update --init --recursive
git submodule update --init --recursive
3. 서브모듈 상태 확인
3. 查看子模块状态
git submodule status
git submodule status
4. 서브모듈 브랜치 체크아웃 (개발 시)
4. 切换子模块分支(开发时)
git submodule foreach 'git checkout main || git checkout master'
undefinedgit submodule foreach 'git checkout main || git checkout master'
undefinedExample 3: 서브모듈을 최신 버전으로 업데이트
示例3:将子模块更新到最新版本
bash
undefinedbash
undefined1. 모든 서브모듈을 원격 최신으로 업데이트
1. 将所有子模块更新到远程最新版本
git submodule update --remote --merge
git submodule update --remote --merge
2. 변경사항 확인
2. 查看变更
git diff --submodule
git diff --submodule
3. 변경사항 커밋
3. 提交变更
git add .
git commit -m "chore: update all submodules to latest"
git add .
git commit -m "chore: update all submodules to latest"
4. 푸시
4. 推送
git push origin main
undefinedgit push origin main
undefinedExample 4: 공유 컴포넌트를 여러 프로젝트에서 사용
示例4:在多个项目中使用共享组件
bash
undefinedbash
undefined프로젝트 A에서
在项目A中
git submodule add https://github.com/myorg/shared-components.git src/shared
git submodule add https://github.com/myorg/shared-components.git src/shared
프로젝트 B에서
在项目B中
git submodule add https://github.com/myorg/shared-components.git src/shared
git submodule add https://github.com/myorg/shared-components.git src/shared
공유 컴포넌트 업데이트 시 (각 프로젝트에서)
共享组件更新时(在每个项目中执行)
git submodule update --remote src/shared
git add src/shared
git commit -m "chore: update shared-components"
undefinedgit submodule update --remote src/shared
git add src/shared
git commit -m "chore: update shared-components"
undefinedExample 5: CI/CD에서 서브모듈 처리
示例5:在CI/CD中处理子模块
yaml
undefinedyaml
undefinedGitHub Actions
GitHub Actions
jobs:
build:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive # 또는 'true'
jobs:
build:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive # 或 'true'
GitLab CI
GitLab CI
variables:
GIT_SUBMODULE_STRATEGY: recursive
variables:
GIT_SUBMODULE_STRATEGY: recursive
Jenkins
Jenkins
checkout scm: [
$class: 'SubmoduleOption',
recursiveSubmodules: true
]
undefinedcheckout scm: [
$class: 'SubmoduleOption',
recursiveSubmodules: true
]
undefinedAdvanced workflows
高级工作流
중첩 서브모듈 (Nested submodules)
嵌套子模块(Nested submodules)
bash
undefinedbash
undefined중첩된 모든 서브모듈 초기화
初始化所有嵌套子模块
git submodule update --init --recursive
git submodule update --init --recursive
중첩된 모든 서브모듈 업데이트
更新所有嵌套子模块
git submodule update --remote --recursive
undefinedgit submodule update --remote --recursive
undefined서브모듈 URL 변경
修改子模块URL
bash
undefinedbash
undefined.gitmodules 파일 수정
修改.gitmodules文件
git config -f .gitmodules submodule.libs/lib.url https://new-url.git
git config -f .gitmodules submodule.libs/lib.url https://new-url.git
로컬 설정 동기화
同步本地配置
git submodule sync
git submodule sync
서브모듈 업데이트
更新子模块
git submodule update --init --recursive
undefinedgit submodule update --init --recursive
undefined서브모듈을 일반 디렉토리로 변환
将子模块转换为普通目录
bash
undefinedbash
undefined1. 서브모듈 내용 백업
1. 备份子模块内容
cp -r libs/lib libs/lib-backup
cp -r libs/lib libs/lib-backup
2. 서브모듈 제거
2. 移除子模块
git submodule deinit libs/lib
git rm libs/lib
rm -rf .git/modules/libs/lib
git submodule deinit libs/lib
git rm libs/lib
rm -rf .git/modules/libs/lib
3. 백업 복원 (.git 제외)
3. 恢复备份(排除.git目录)
rm -rf libs/lib-backup/.git
mv libs/lib-backup libs/lib
rm -rf libs/lib-backup/.git
mv libs/lib-backup libs/lib
4. 일반 파일로 추가
4. 作为普通文件添加
git add libs/lib
git commit -m "chore: convert submodule to regular directory"
undefinedgit add libs/lib
git commit -m "chore: convert submodule to regular directory"
undefinedshallow 클론으로 공간 절약
使用浅克隆节省空间
bash
undefinedbash
undefined얕은 클론으로 서브모듈 추가
通过浅克隆添加子模块
git submodule add --depth 1 https://github.com/large/repo.git libs/large
git submodule add --depth 1 https://github.com/large/repo.git libs/large
기존 서브모듈을 얕은 클론으로 업데이트
将现有子模块更新为浅克隆
git submodule update --init --depth 1
undefinedgit submodule update --init --depth 1
undefinedBest practices
最佳实践
- 버전 고정: 서브모듈은 항상 특정 커밋/태그로 고정하여 재현 가능성 확보
- 문서화: README에 서브모듈 초기화 방법 명시
- CI 설정: CI/CD 파이프라인에서 옵션 사용
--recursive - 정기 업데이트: 보안 패치 등을 위해 정기적으로 서브모듈 업데이트
- 브랜치 추적: 개발 중에는 브랜치 추적 설정으로 편의성 확보
- 권한 관리: 서브모듈 저장소 접근 권한 확인
- 얕은 클론: 대용량 저장소는 옵션으로 공간 절약
--depth - 상태 확인: 커밋 전 로 상태 확인
git submodule status
- 版本固定: 子模块应始终固定到特定提交/标签,确保可复现性
- 文档说明: 在README中明确子模块的初始化方法
- CI配置: 在CI/CD流水线中使用选项
--recursive - 定期更新: 为了获取安全补丁等,定期更新子模块
- 分支跟踪: 开发期间设置分支跟踪以提升便利性
- 权限管理: 确认子模块仓库的访问权限
- 浅克隆: 对于大容量仓库,使用选项节省空间
--depth - 状态检查: 提交前使用检查状态
git submodule status
Common pitfalls
常见陷阱
- detached HEAD: 서브모듈은 기본적으로 detached HEAD 상태. 작업 시 브랜치 체크아웃 필요
- 초기화 누락: 클론 후 필수
git submodule update --init - 참조 불일치: 서브모듈 변경 후 메인 저장소에서 참조 업데이트 필요
- 권한 문제: 비공개 서브모듈은 SSH 키 또는 토큰 설정 필요
- 상대 경로: 의 상대 경로 사용 시 포크에서 문제 발생 가능
.gitmodules - 삭제 불완전: 서브모듈 제거 시 캐시도 삭제 필요
.git/modules
- 分离头指针: 子模块默认处于分离头指针状态,工作时需要切换到分支
- 初始化遗漏: 克隆后必须执行
git submodule update --init - 引用不一致: 子模块变更后,需要在主仓库中更新引用
- 权限问题: 私有子模块需要配置SSH密钥或令牌
- 相对路径: 在中使用相对路径可能会在复刻仓库时引发问题
.gitmodules - 移除不彻底: 移除子模块时,还需要删除中的缓存
.git/modules
Troubleshooting
故障排除
서브모듈이 초기화되지 않음
子模块未初始化
bash
undefinedbash
undefined강제 초기화
强制初始化
git submodule update --init --force
undefinedgit submodule update --init --force
undefined서브모듈 충돌
子模块冲突
bash
undefinedbash
undefined서브모듈 상태 확인
查看子模块状态
git submodule status
git submodule status
충돌 해결 후 원하는 커밋으로 체크아웃
解决冲突后切换到目标提交
cd libs/lib
git checkout <desired-commit>
cd ..
git add libs/lib
git commit -m "fix: resolve submodule conflict"
undefinedcd libs/lib
git checkout <desired-commit>
cd ..
git add libs/lib
git commit -m "fix: resolve submodule conflict"
undefined권한 오류 (private repository)
权限错误(私有仓库)
bash
undefinedbash
undefinedSSH URL 사용
使用SSH URL
git config -f .gitmodules submodule.libs/lib.url git@github.com:org/private-lib.git
git submodule sync
git submodule update --init
undefinedgit config -f .gitmodules submodule.libs/lib.url git@github.com:org/private-lib.git
git submodule sync
git submodule update --init
undefined서브모듈 dirty 상태
子模块处于脏状态
bash
undefinedbash
undefined서브모듈 내 변경사항 확인
查看子模块内的变更
cd libs/lib
git status
git diff
cd libs/lib
git status
git diff
변경사항 버리기
丢弃变更
git checkout .
git clean -fd
git checkout .
git clean -fd
또는 커밋하기
或提交变更
git add .
git commit -m "fix: resolve changes"
git push
undefinedgit add .
git commit -m "fix: resolve changes"
git push
undefinedConfiguration
配置
유용한 설정
实用配置
bash
undefinedbash
undefineddiff에서 서브모듈 변경 표시
在diff中显示子模块变更
git config --global diff.submodule log
git config --global diff.submodule log
status에서 서브모듈 요약 표시
在status中显示子模块摘要
git config --global status.submoduleSummary true
git config --global status.submoduleSummary true
push 시 서브모듈 변경 확인
推送时检查子模块变更
git config --global push.recurseSubmodules check
git config --global push.recurseSubmodules check
fetch 시 서브모듈도 함께 fetch
fetch时同时获取子模块内容
git config --global fetch.recurseSubmodules on-demand
undefinedgit config --global fetch.recurseSubmodules on-demand
undefined.gitmodules 예시
.gitmodules示例
ini
[submodule "libs/lib"]
path = libs/lib
url = https://github.com/example/lib.git
branch = main
[submodule "vendor/tool"]
path = vendor/tool
url = git@github.com:example/tool.git
shallow = trueini
[submodule "libs/lib"]
path = libs/lib
url = https://github.com/example/lib.git
branch = main
[submodule "vendor/tool"]
path = vendor/tool
url = git@github.com:example/tool.git
shallow = true