https://www.jannikbuschke.de/blog/git-submodules/

아래는 Jannik Buschke 블로그 글의 내용을 요약한 한국어 정리입니다.


여러 모노레포를 연결하는 Git 서브모듈 활용법

요약: Git 서브모듈은 여러 모노레포 간에 공유 모듈을 함께 개발할 수 있도록 해주는 강력하고 실용적인 방법입니다. "레포 안의 레포", 그것도 여러 겹으로 구성할 수 있어 매우 유용합니다!


1. 소개: 모노레포의 장점과 한계

모노레포(Monorepo)는 복잡한 앱 개발을 단순화해줍니다. 예를 들어, 다음과 같은 구조로 구성할 수 있습니다:

/app-repository
  /app1
  /app2
  /shared-module
  • app1app2는 비슷한 도메인을 다루며, shared-module은 공통 유틸리티를 담고 있습니다.
  • 이 구조에서는 shared-module소스 코드 수준에서 바로 연결할 수 있어, 개발 중인 기능을 즉시 사용하고 API 설계에 대한 빠른 피드백을 받을 수 있습니다.

한계점

  • shared-moduleapp1, app2 외에도 다른 앱(예: app3)에서도 유용할 수 있습니다.
  • 하지만 app3다른 저장소(repository)에 있고, 다른 조직이나 커뮤니티에서 관리한다면, shared-module을 공유하기 어렵습니다.
  • shared-module의 빌드 결과물(예: npm 패키지)을 배포하면 app3에서 사용할 수는 있지만, 함께 개발하거나 실시간으로 기여하기는 어렵습니다.

2. 해결책: Git 서브모듈(Submodules)

Git 서브모듈을 사용하면, 하나의 모듈이 여러 모노레포에 동시에 포함되어 개발될 수 있습니다.

구조 예시

  1. 먼저 shared-module을 독립된 저장소로 분리합니다:

    /module-repository
      /shared-module
  2. 이 저장소를 다른 모노레포에 서브모듈로 추가합니다:

    /mono-repository1
      /app1
      /app2
      /generic-module-as-a-git-submodule  ← 서브모듈
    
    /mono-repository2
      /app3
      /generic-module-as-a-git-submodule  ← 동일한 서브모듈
  • 서브모듈은 특정 커밋(commit)을 가리키는 링크일 뿐, 소스 코드 자체를 포함하지 않습니다.
  • 하지만 로컬에서 클론할 때, 서브모듈의 소스도 함께 체크아웃되므로, 마치 하나의 큰 저장소처럼 작업할 수 있습니다.

3. 서브모듈 작업 방법

  • 서브모듈 내부에서 명령어 실행: 서브모듈 저장소에 영향을 줍니다.
  • 부모 저장소에서 명령어 실행: 부모 저장소에 영향을 줍니다.
  • 두 저장소는 저장소 차원에서는 분리되어 있지만, 로컬 파일 시스템에서는 소스 코드가 함께 위치하므로 통합된 개발이 가능합니다.

서브모듈 추가하기

git submodule add <저장소-URL>
  • .gitmodules 파일이 생성되며, 서브모듈의 경로와 URL을 기록합니다.
  • 예:

    [submodule "my-module"]
      path = my-module
      url = https://github.com/jannikbuschke/my-module.git

서브모듈이 포함된 저장소 클론하기

git clone <저장소-URL> --recursive
  • --recursive 플래그를 꼭 사용해야 서브모듈도 함께 체크아웃됩니다.
  • 생략하면 서브모듈 폴더는 비어 있게 되며, 나중에 초기화하는 과정이 번거롭습니다.

서브모듈의 새로운 커밋 반영하기

  • 서브모듈에서 커밋을 하면, 부모 저장소는 자동으로 변경되지 않습니다.
  • 부모 저장소에서 다음과 같이 명시적으로 업데이트해야 합니다:

    git add <서브모듈-경로>
    git commit -m "Update submodule to latest commit"
  • git statusgit diff를 통해 어떤 커밋을 가리켜야 할지 확인할 수 있습니다.

4. 주의사항 및 팁

  • 서브모듈 커밋은 반드시 푸시해야 함:
    서브모듈에서 커밋했지만 푸시하지 않으면, 그 커밋은 로컬에만 존재합니다.
    이 상태에서 부모 저장소를 푸시하면, 다른 개발자나 CI/CD가 존재하지 않는 커밋을 체크아웃하려 해서 실패할 수 있습니다.
  • --recursive 플래그 필수:
    클론 시 --recursive를 빼먹지 마세요. 이후 수동 초기화는 다소 번거롭습니다.
  • 서브모듈 진입 시 브랜치 체크아웃:
    서브모듈은 기본적으로 detached HEAD 상태(커밋 해시 참조)로 시작합니다.
    작업하려면 git checkout main 또는 git switch - 등으로 브랜치를 명시적으로 체크아웃해야 합니다.
  • 서브모듈 경로 변경/삭제는 까다로움:
    이름 변경이나 삭제는 .gitmodules 파일을 직접 수정하거나, 새 위치에 클론하는 것이 가장 안전합니다.

5. 결론

  • Git 서브모듈은 종종 "사용하기 어려움", "문서 부족", "이상한 동작" 등으로 평가절하되지만, 실제로는 학습 곡선을 넘기면 매우 강력한 도구입니다.
  • 약간의 주의사항이 있지만, 그로 인한 이점이 훨씬 큽니다.
  • 여러 앱을 개발하면서 코드를 공유하거나, 오픈소스 프로젝트를 사용하면서 동시에 기여하고 싶다면, Git 서브모듈을 꼭 한번 시도해보세요!

핵심 메시지: 서브모듈은 "여러 모노레포에서 하나의 모듈을 함께 개발"하는 이상적인 솔루션입니다.

tag: none

댓글추가