Skip to content

IT의 모든것

개발 하는 사람들에게 도움이 될 만한 정보를 제공합니다.

Menu
Menu

Git 서브모듈(Submodule) 개념 완벽 정리: 다른 프로젝트 깔끔하게 포함시키는 법

Posted on 2026년 10월 09일2026년 10월 06일 by steve

 

Git 서브모듈(Submodule) 완벽 가이드: 다른 프로젝트를 내 저장소 안에 깔끔하게 포함시키고, 복사-붙여넣기 없는 스마트한 공통 모듈 관리 비법을 10분 만에 마스터해 보세요!

 

여러 프로젝트를 동시에 개발하다 보면 공통 유틸리티 함수나 디자인 시스템, 공용 라이브러리를 여러 리포지토리에서 함께 써야 하는 순간이 꼭 찾아오죠. 예전의 저는 별다른 고민 없이 코드를 이리저리 ‘복사-붙여넣기’ 하곤 했답니다. 그런데 라이브러리 코드에 치명적인 버그가 하나 발견되자마자 서너 군데 저장소를 일일이 찾아다니며 수정하느라 밤샘 작업을 피하지 못했던 뼈아픈 기억이 있어요… 😭 솔직히 말해서 코드 동기화 지옥이 따로 없더라고요.

이런 번거로움과 유지보수의 악몽을 한 번에 해결해 주는 도구가 바로 Git의 서브모듈(Submodule) 기능이에요. 하나의 Git 저장소 안에서 또 다른 독립된 Git 저장소를 마치 일반 하위 폴더처럼 품어 관리할 수 있도록 도와준답니다. 오늘 포스팅에서는 서브모듈의 핵심 개념부터 프로젝트에 추가하고 클론하는 실전 명령어, 그리고 실무에서 자주 겪는 주의사항까지 친절하게 알려드릴게요! 😊

 

서브모듈(Submodule)이란? 왜 필요할까요? 🤔

서브모듈은 쉽게 말해 ‘저장소 안의 또 다른 저장소’라고 이해하시면 돼요. 메인 프로젝트(상위 저장소)의 형상 관리를 유지하면서도, 특정 디렉터리를 외부의 독립된 깃 저장소의 특정 커밋과 다이렉트로 연결해 주는 깃의 내장 기능입니다.

단순히 외부 코드를 다운로드해서 파일째로 커밋하는 것과 서브모듈은 무엇이 다를까요? 코드를 직접 복사해 두면 원본 저장소에서 새로운 기능이 추가되거나 버그가 고쳐졌을 때 내 프로젝트로 가져오기가 매우 번거롭고 충돌 위험도 큽니다. 반면 서브모듈을 사용하면 외부 프로젝트의 고유한 커밋 이력(Git History)을 온전히 보존하면서, 언제든지 원하는 최신 커밋이나 안정적인 특정 버전으로 자유롭게 동기화할 수 있어요.

💡 알아두세요!
상위 저장소는 서브모듈 디렉터리의 실제 파일 내용 전체를 추적하지 않습니다. 대신 서브모듈의 원격 주소 정보가 담긴 .gitmodules 파일과 서브모듈 저장소의 ‘특정 커밋 해시(Commit Hash)’만을 포인터 형태로 기록합니다. 따라서 외부 저장소에 새 커밋이 올라와도 상위 프로젝트가 명시적으로 갱신하지 않는 한 기존 상태가 안정적으로 유지됩니다.

 

다른 프로젝트를 쏙! 서브모듈 추가 및 클론 명령어 📊

서브모듈을 사용할 때 실무에서 마주치는 작업은 크게 두 가지로 나뉩니다. 첫째는 기존 프로젝트에 외부 저장소를 새롭게 서브모듈로 추가하는 것이고, 둘째는 이미 서브모듈이 구성된 프로젝트를 새 환경이나 다른 팀원이 내려받는(Clone) 것이에요.

명령어 구조 자체는 간단하지만 옵션을 빠뜨리면 빈 폴더만 생성되어 당황하기 쉬워요. 상황별 필수 명령어와 핵심 역할을 표로 정리해 드릴게요.

상황별 서브모듈 필수 명령어 비교

구분 핵심 명령어 작업 설명 핵심 주의점
서브모듈 신규 추가 git submodule add <URL> [경로] 외부 저장소를 지정 경로에 하위 모듈로 등록 .gitmodules 파일 생성 확인 필수
저장소 전체 클론 git clone --recurse-submodules <URL> 메인 저장소와 하위 서브모듈을 한 번에 일괄 다운로드 옵션 누락 시 서브모듈 폴더가 비어있음
사후 서브모듈 다운 git submodule update --init --recursive 일반 클론 후 비어있는 서브모듈 초기화 및 동기화 중첩 서브모듈까지 받으려면 –recursive 필요
최신 원격 커밋 반영 git submodule update --remote 서브모듈 원격 저장소의 최신 변경 내용을 가져옴 갱신 후 메인 저장소에서도 커밋 필요
⚠️ 주의하세요!
서브모듈이 포함된 프로젝트를 평소처럼 일반적인 git clone <URL>로만 내려받으면 서브모듈 디렉터리는 내용이 전혀 없는 텅 빈 껍데기 폴더로 생성됩니다. 프로젝트를 한 번에 온전히 빌드하려면 반드시 --recurse-submodules 플래그를 붙여 클론해 주셔야 합니다!

 

실전 적용을 돕는 서브모듈 명령어 가이드 및 도구 🧮

서브모듈을 추가할 때 실행되는 기본 공식과 내부 원리를 명확히 짚고 넘어가면 터미널 작업이 훨씬 쉬워집니다.

📝 서브모듈 신규 추가 기본 공식

기본 명령어 구조 = git submodule add [원격 저장소 URL] [설치할 로컬 폴더 경로]

실제 터미널에서 작업이 진행되는 흐름은 다음과 같습니다:

1) 첫 번째 단계: 메인 프로젝트 루트 디렉터리로 터미널 위치를 이동합니다.

2) 두 번째 단계: 외부 라이브러리 저장소 URL과 배치할 폴더명을 지정하여 add 명령어를 실행합니다.

→ 실행 결과: 로컬에 폴더가 복제되고, URL과 경로를 매핑한 .gitmodules 파일이 자동 생성됩니다.

🔢 Git 서브모듈 명령어 자동 생성기

작업 유형:

저장소 URL:

로컬 경로(선택):

실행 명령어:

명령어 설명:

 

실무 작업 시 필수 꿀팁과 Detached HEAD 주의점 👩💼👨💻

서브모듈을 처음 쓰시는 분들이 가장 흔하게 겪는 패닉 상황이 있어요. 바로 서브모듈 폴더 안으로 이동해 터미널에 git status를 입력했을 때 나타나는 ‘HEAD detached at…’이라는 경고 메시지예요! 😱

이것은 오류가 아니라 서브모듈의 지극히 정상적인 작동 원리입니다. 서브모듈은 특정 브랜치의 최신 상태를 따라가는 것이 아니라, 상위 저장소가 기록해 둔 ‘특정 커밋 해시’에 고정되어 체크아웃되기 때문이에요. 하지만 브랜치가 없는 상태(Detached HEAD)에서 코드를 수정하고 커밋해 버리면, 나중에 다른 브랜치로 이동했을 때 해당 커밋이 공중에 붕 떠버려서 소중한 작업물이 유실될 수 있습니다.

따라서 서브모듈 디렉터리 내부에서 코드를 수정해야 할 때는 반드시 해당 폴더로 진입한 뒤 git checkout main(또는 작업용 브랜치)을 실행하여 정상 브랜치 상태로 만든 다음 작업을 진행해야 합니다.

📌 알아두세요!
수정 사항을 원격 저장소에 푸시(Push)할 때는 반드시 ‘서브모듈 커밋/푸시 → 메인 프로젝트 커밋/푸시’의 황금 순서를 지켜야 합니다! 만약 메인 프로젝트를 먼저 푸시해 버리면, 팀원들은 원격 저장소에 아직 존재하지 않는 서브모듈 커밋 포인터를 바라보게 되어 빌드 실패 오류를 겪게 됩니다.

 

실전 예시: 공통 UI 라이브러리(Common-UI) 분리 적용기 📚

실제 서비스 환경에서 서브모듈이 어떻게 프로젝트 구조를 깔끔하게 만들어주는지 구체적인 실무 시나리오로 살펴볼게요.

개발팀의 실제 고민 상황

  • 상황: 사용자 웹 서비스(Web-Client)와 관리자 백오피스(Admin-Web)에서 버튼, 모달 등 동일한 UI 컴포넌트를 사용 중
  • 문제점: 두 프로젝트에 UI 코드를 복붙해 두었더니, 버튼 색상 하나를 변경할 때마다 양쪽 프로젝트에서 중복 수정 발생

서브모듈 적용 과정

1) 공통 컴포넌트만 모아 common-ui.git이라는 별도의 독립 저장소를 새롭게 생성

2) 웹 서비스 프로젝트 루트에서 git submodule add https://github.com/myteam/common-ui.git src/shared/ui 실행

3) 관리자 프로젝트 루트에서도 동일하게 서브모듈 추가 명령어 실행

도입 후 최종 결과

– 코드 중복 제거: 공통 UI 코드베이스가 단 한 곳으로 통합되어 관리 포인트 일원화

– 동기화 효율 극대화: 공통 UI 저장소에서 기능 수정 후, 각 프로젝트는 git submodule update --remote 한 줄로 즉시 반영 완료

이처럼 서브모듈을 활용하면 사내 패키지 매니저(NPM Private Registry 등)를 거창하게 구축하지 않고도 손쉽게 여러 프로젝트 간의 공통 코드를 모듈화하여 관리할 수 있습니다.

 

마무리: 핵심 내용 요약 📝

오늘은 Git 서브모듈의 탄생 배경부터 프로젝트에 외부 저장소를 포함시키는 구체적인 방법, 그리고 실무자가 꼭 기억해야 할 협업 노하우까지 차근차근 살펴보았습니다.

처음에는 커밋 포인터라는 개념이나 Detached HEAD 상태가 다소 낯설고 까다롭게 느껴질 수 있지만, 저장소를 깔끔하게 분리하고 공통 코드를 체계적으로 다루는 데 있어 서브모듈만큼 강력한 기본기도 드뭅니다. 작은 프로젝트의 공통 유틸리티부터 직접 서브모듈로 분리해 보며 개발 생산성을 한 단계 높여보시는 것은 어떨까요? 실습해 보시다가 잘 안 풀리는 점이나 궁금한 내용이 있다면 언제든 편하게 댓글로 물어봐주세요~ 😊

💡

서브모듈 핵심 정리 카드

✨ 개념 요약: 독립된 외부 저장소를 특정 커밋 시점으로 연결하여 복사-붙여넣기 없이 공통 코드를 공유합니다.
📊 클론 필수 옵션: –recurse-submodules 플래그를 붙여야 빈 폴더가 아닌 실제 파일까지 온전히 받아집니다.
🧮 핵심 추가 공식:

git submodule add [원격 URL] [로컬 경로]

👩💻 푸시 규칙: 서브모듈을 먼저 푸시한 뒤 메인 프로젝트를 푸시해야 동료 개발자의 빌드 오류를 방지할 수 있습니다.

서브모듈 내부 수정 시에는 반드시 Detached HEAD를 벗어나 정상 브랜치를 체크아웃 후 작업하세요!

자주 묻는 질문 ❓

Q: 서브모듈이 포함된 프로젝트를 이미 일반 git clone으로 받아버렸는데 어떻게 하나요?
A: 프로젝트를 다시 클론할 필요 없이 터미널에서 git submodule update --init --recursive 명령어를 실행하시면 비어있던 서브모듈 파일들을 즉시 정상 다운로드할 수 있습니다.

Q: 서브모듈 원격 저장소에 새로운 커밋이 생기면 내 프로젝트에 자동 반영되나요?
A: 자동으로 반영되지 않습니다. 메인 프로젝트는 고정된 커밋 해시 포인터를 바라보고 있기 때문에, 최신 버전을 적용하려면 git submodule update --remote 명령어를 실행한 후 메인 프로젝트에서 변경된 커밋 포인터를 새롭게 커밋 및 푸시해 주어야 합니다.

Q: 서브모듈 폴더 안에서 코드를 바로 수정하고 커밋해도 되나요?
A: 가능하지만 주의가 필요합니다. 서브모듈 진입 시 기본적으로 브랜치가 없는 Detached HEAD 상태이므로, 먼저 git checkout main 등으로 작업 브랜치로 전환한 후 커밋과 푸시를 진행해야 작업 내용 유실을 막을 수 있습니다.

Q: 등록했던 서브모듈을 깔끔하게 완전히 삭제하려면 어떻게 해야 하나요?
A: git submodule deinit -f [경로]를 실행해 서브모듈 등록을 해제하고, git rm -f [경로]를 통해 작업 트리 및 .gitmodules에서 제거한 뒤 .git/modules/[경로] 캐시를 삭제해 주시면 완전히 제거됩니다.

Q: Git 서브모듈과 서브트리(Subtree)의 차이점은 무엇인가요?
A: 서브모듈은 외부 저장소의 커밋 해시만 가리키는 포인터 방식인 반면, 서브트리는 외부 저장소의 코드 파일 자체를 상위 저장소의 단일 커밋 이력 안으로 직접 병합하여 관리하는 방식입니다. 팀원들이 서브모듈 명령어에 익숙하지 않다면 서브트리가 대안이 될 수 있습니다.

최신 글

  • 외부 라이브러리 소스 코드 디버깅법: console.log 없이 F11로 파헤치기
  • JetBrains 라이브 템플릿(Live Templates)으로 코딩 속도 2배 올리는 비법
  • console.log 그만! 브레이크포인트와 조건부 중단점으로 버그 10배 빨리 잡는 법
  • 자바와 C# 프로젝트 빌드 속도 70% 단축하는 필수 설정 꿀팁
  • JetBrains에서 Git 완벽 연동하기: 터미널 없이 끝내는 개발 생산성 가이드

보관함

  • 2026년 10월

카테고리

  • IT

소개 및 문의 · 개인정보처리방침 · 면책조항

©2026 IT의 모든것 | Design: Newspaperly WordPress Theme