git-submodule
36
总安装量
37
周安装量
#5718
全站排名
安装命令
npx skills add https://github.com/supercent-io/skills-template --skill git-submodule
Agent 安装分布
opencode
32
gemini-cli
28
claude-code
28
github-copilot
23
antigravity
20
Skill 文档
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
Instructions
Step 1: Understanding submodules
Git submoduleì ë©ì¸ Git ì ì¥ì ë´ì ë¤ë¥¸ Git ì ì¥ì를 í¬í¨ìí¤ë 기ë¥ì ëë¤.
Key concepts:
- ìë¸ëª¨ëì í¹ì 커ë°ì 참조íì¬ ë²ì ì ê³ ì í©ëë¤
.gitmodulesíì¼ì ìë¸ëª¨ë ê²½ë¡ì URLì´ ê¸°ë¡ë©ëë¤- ìë¸ëª¨ë ë´ ë³ê²½ì ë³ë 커ë°ì¼ë¡ ê´ë¦¬ë©ëë¤
Step 2: Adding submodules
기본 ì¶ê°:
# ìë¸ëª¨ë ì¶ê°
git submodule add <repository-url> <path>
# ì: libs/lib ê²½ë¡ì ë¼ì´ë¸ë¬ë¦¬ ì¶ê°
git submodule add https://github.com/example/lib.git libs/lib
í¹ì ë¸ëì¹ ì¶ì :
# í¹ì ë¸ëì¹ë¥¼ ì¶ì íëë¡ ì¶ê°
git submodule add -b main https://github.com/example/lib.git libs/lib
ì¶ê° í 커ë°:
git add .gitmodules libs/lib
git commit -m "feat: add lib as submodule"
Step 3: Cloning with submodules
ì ê· í´ë¡ ì:
# ë°©ë² 1: í´ë¡ ì --recursive ìµì
git clone --recursive <repository-url>
# ë°©ë² 2: í´ë¡ í ì´ê¸°í
git clone <repository-url>
cd <repository>
git submodule init
git submodule update
í ì¤ë¡ ì´ê¸°í ë° ì ë°ì´í¸:
git submodule update --init --recursive
Step 4: Updating submodules
ì격 ìµì ë²ì ì¼ë¡ ì ë°ì´í¸:
# 모ë ìë¸ëª¨ëì ì격 ìµì ì¼ë¡ ì
ë°ì´í¸
git submodule update --remote
# í¹ì ìë¸ëª¨ëë§ ì
ë°ì´í¸
git submodule update --remote libs/lib
# ì
ë°ì´í¸ + 머ì§
git submodule update --remote --merge
# ì
ë°ì´í¸ + ë¦¬ë² ì´ì¤
git submodule update --remote --rebase
ìë¸ëª¨ë 참조 커ë°ì¼ë¡ ì²´í¬ìì:
# ë©ì¸ ì ì¥ìê° ì°¸ì¡°íë 커ë°ì¼ë¡ ìë¸ëª¨ë ì²´í¬ìì
git submodule update
Step 5: Working inside submodules
ìë¸ëª¨ë ë´ìì ìì :
# ìë¸ëª¨ë ëë í ë¦¬ë¡ ì´ë
cd libs/lib
# ë¸ëì¹ ì²´í¬ìì (detached HEAD í´ì )
git checkout main
# ë³ê²½ì¬í ìì
# ... make changes ...
# ìë¸ëª¨ë ë´ìì ì»¤ë° ë° í¸ì
git add .
git commit -m "feat: update library"
git push origin main
ë©ì¸ ì ì¥ììì ìë¸ëª¨ë ë³ê²½ ë°ì:
# ë©ì¸ ì ì¥ìë¡ ì´ë
cd ..
# ìë¸ëª¨ë 참조 ì
ë°ì´í¸
git add libs/lib
git commit -m "chore: update lib submodule reference"
git push
Step 6: Batch operations
모ë ìë¸ëª¨ëì ëª ë ¹ ì¤í:
# 모ë ìë¸ëª¨ëìì pull
git submodule foreach 'git pull origin main'
# 모ë ìë¸ëª¨ëìì ìí íì¸
git submodule foreach 'git status'
# 모ë ìë¸ëª¨ëìì ë¸ëì¹ ì²´í¬ìì
git submodule foreach 'git checkout main'
# ì¤ì²©ë ìë¸ëª¨ëìë ëª
ë ¹ ì¤í
git submodule foreach --recursive 'git fetch origin'
Step 7: Removing submodules
ìë¸ëª¨ë ìì ì ê±°:
# 1. ìë¸ëª¨ë ë±ë¡ í´ì
git submodule deinit <path>
# 2. Gitìì ì ê±°
git rm <path>
# 3. .git/modulesìì ìºì ì ê±°
rm -rf .git/modules/<path>
# 4. ë³ê²½ì¬í 커ë°
git commit -m "chore: remove submodule"
ìì: libs/lib ì ê±°:
git submodule deinit libs/lib
git rm libs/lib
rm -rf .git/modules/libs/lib
git commit -m "chore: remove lib submodule"
git push
Step 8: Checking submodule status
ìí íì¸:
# ìë¸ëª¨ë ìí íì¸
git submodule status
# ìì¸ ìí (ì¬ê·ì )
git submodule status --recursive
# ìì½ ì ë³´
git submodule summary
ì¶ë ¥ í´ì:
44d7d1... libs/lib (v1.0.0) # ì ì (참조 커ë°ê³¼ ì¼ì¹)
+44d7d1... libs/lib (v1.0.0-1-g...) # ë¡ì»¬ ë³ê²½ ìì
-44d7d1... libs/lib # ì´ê¸°í ì ë¨
Examples
Example 1: íë¡ì í¸ì ì¸ë¶ ë¼ì´ë¸ë¬ë¦¬ ì¶ê°
# 1. ìë¸ëª¨ë ì¶ê°
git submodule add https://github.com/lodash/lodash.git vendor/lodash
# 2. í¹ì ë²ì (íê·¸)ì¼ë¡ ê³ ì
cd vendor/lodash
git checkout v4.17.21
cd ../..
# 3. ë³ê²½ì¬í 커ë°
git add .
git commit -m "feat: add lodash v4.17.21 as submodule"
# 4. í¸ì
git push origin main
Example 2: ìë¸ëª¨ë í¬í¨ ì ì¥ì í´ë¡ í ì¤ì
# 1. ì ì¥ì í´ë¡
git clone https://github.com/myorg/myproject.git
cd myproject
# 2. ìë¸ëª¨ë ì´ê¸°í ë° ì
ë°ì´í¸
git submodule update --init --recursive
# 3. ìë¸ëª¨ë ìí íì¸
git submodule status
# 4. ìë¸ëª¨ë ë¸ëì¹ ì²´í¬ìì (ê°ë° ì)
git submodule foreach 'git checkout main || git checkout master'
Example 3: ìë¸ëª¨ëì ìµì ë²ì ì¼ë¡ ì ë°ì´í¸
# 1. 모ë ìë¸ëª¨ëì ì격 ìµì ì¼ë¡ ì
ë°ì´í¸
git submodule update --remote --merge
# 2. ë³ê²½ì¬í íì¸
git diff --submodule
# 3. ë³ê²½ì¬í 커ë°
git add .
git commit -m "chore: update all submodules to latest"
# 4. í¸ì
git push origin main
Example 4: ê³µì ì»´í¬ëí¸ë¥¼ ì¬ë¬ íë¡ì í¸ìì ì¬ì©
# íë¡ì í¸ Aìì
git submodule add https://github.com/myorg/shared-components.git src/shared
# íë¡ì í¸ Bìì
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"
Example 5: CI/CDìì ìë¸ëª¨ë ì²ë¦¬
# GitHub Actions
jobs:
build:
steps:
- uses: actions/checkout@v4
with:
submodules: recursive # ëë 'true'
# GitLab CI
variables:
GIT_SUBMODULE_STRATEGY: recursive
# Jenkins
checkout scm: [
$class: 'SubmoduleOption',
recursiveSubmodules: true
]
Advanced workflows
ì¤ì²© ìë¸ëª¨ë (Nested submodules)
# ì¤ì²©ë 모ë ìë¸ëª¨ë ì´ê¸°í
git submodule update --init --recursive
# ì¤ì²©ë 모ë ìë¸ëª¨ë ì
ë°ì´í¸
git submodule update --remote --recursive
ìë¸ëª¨ë URL ë³ê²½
# .gitmodules íì¼ ìì
git config -f .gitmodules submodule.libs/lib.url https://new-url.git
# ë¡ì»¬ ì¤ì ë기í
git submodule sync
# ìë¸ëª¨ë ì
ë°ì´í¸
git submodule update --init --recursive
ìë¸ëª¨ëì ì¼ë° ëë í ë¦¬ë¡ ë³í
# 1. ìë¸ëª¨ë ë´ì© ë°±ì
cp -r libs/lib libs/lib-backup
# 2. ìë¸ëª¨ë ì ê±°
git submodule deinit libs/lib
git rm libs/lib
rm -rf .git/modules/libs/lib
# 3. ë°±ì
ë³µì (.git ì ì¸)
rm -rf libs/lib-backup/.git
mv libs/lib-backup libs/lib
# 4. ì¼ë° íì¼ë¡ ì¶ê°
git add libs/lib
git commit -m "chore: convert submodule to regular directory"
shallow í´ë¡ ì¼ë¡ ê³µê° ì ì½
# ìì í´ë¡ ì¼ë¡ ìë¸ëª¨ë ì¶ê°
git submodule add --depth 1 https://github.com/large/repo.git libs/large
# 기존 ìë¸ëª¨ëì ìì í´ë¡ ì¼ë¡ ì
ë°ì´í¸
git submodule update --init --depth 1
Best practices
- ë²ì ê³ ì : ìë¸ëª¨ëì íì í¹ì 커ë°/íê·¸ë¡ ê³ ì íì¬ ì¬í ê°ë¥ì± íë³´
- 문ìí: READMEì ìë¸ëª¨ë ì´ê¸°í ë°©ë² ëª ì
- CI ì¤ì : CI/CD íì´íë¼ì¸ìì
--recursiveìµì ì¬ì© - ì 기 ì ë°ì´í¸: ë³´ì í¨ì¹ ë±ì ìí´ ì 기ì ì¼ë¡ ìë¸ëª¨ë ì ë°ì´í¸
- ë¸ëì¹ ì¶ì : ê°ë° ì¤ìë ë¸ëì¹ ì¶ì ì¤ì ì¼ë¡ í¸ìì± íë³´
- ê¶í ê´ë¦¬: ìë¸ëª¨ë ì ì¥ì ì ê·¼ ê¶í íì¸
- ìì í´ë¡ : ëì©ë ì ì¥ìë
--depthìµì ì¼ë¡ ê³µê° ì ì½ - ìí íì¸: ì»¤ë° ì
git submodule statusë¡ ìí íì¸
Common pitfalls
- detached HEAD: ìë¸ëª¨ëì 기본ì ì¼ë¡ detached HEAD ìí. ìì ì ë¸ëì¹ ì²´í¬ìì íì
- ì´ê¸°í ëë½: í´ë¡ í
git submodule update --initíì - 참조 ë¶ì¼ì¹: ìë¸ëª¨ë ë³ê²½ í ë©ì¸ ì ì¥ììì 참조 ì ë°ì´í¸ íì
- ê¶í 문ì : ë¹ê³µê° ìë¸ëª¨ëì SSH í¤ ëë í í° ì¤ì íì
- ìë ê²½ë¡:
.gitmodulesì ìë ê²½ë¡ ì¬ì© ì í¬í¬ìì 문ì ë°ì ê°ë¥ - ìì ë¶ìì : ìë¸ëª¨ë ì ê±° ì
.git/modulesìºìë ìì íì
Troubleshooting
ìë¸ëª¨ëì´ ì´ê¸°íëì§ ìì
# ê°ì ì´ê¸°í
git submodule update --init --force
ìë¸ëª¨ë ì¶©ë
# ìë¸ëª¨ë ìí íì¸
git submodule status
# ì¶©ë í´ê²° í ìíë 커ë°ì¼ë¡ ì²´í¬ìì
cd libs/lib
git checkout <desired-commit>
cd ..
git add libs/lib
git commit -m "fix: resolve submodule conflict"
ê¶í ì¤ë¥ (private repository)
# SSH URL ì¬ì©
git config -f .gitmodules submodule.libs/lib.url git@github.com:org/private-lib.git
git submodule sync
git submodule update --init
ìë¸ëª¨ë dirty ìí
# ìë¸ëª¨ë ë´ ë³ê²½ì¬í íì¸
cd libs/lib
git status
git diff
# ë³ê²½ì¬í ë²ë¦¬ê¸°
git checkout .
git clean -fd
# ëë 커ë°í기
git add .
git commit -m "fix: resolve changes"
git push
Configuration
ì ì©í ì¤ì
# diffìì ìë¸ëª¨ë ë³ê²½ íì
git config --global diff.submodule log
# statusìì ìë¸ëª¨ë ìì½ íì
git config --global status.submoduleSummary true
# push ì ìë¸ëª¨ë ë³ê²½ íì¸
git config --global push.recurseSubmodules check
# fetch ì ìë¸ëª¨ëë í¨ê» fetch
git config --global fetch.recurseSubmodules on-demand
.gitmodules ìì
[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