본문으로 건너뛰기
개발 머꼬
개발 노트Git
hohyeon.dev20

git submodule을 clone했는데 커밋을 해도 부모 저장소에 안 잡히는 이유

  • #Engineering Note
  • #Git

문제 발생

서브모듈 안에서 수정 작업을 하고 커밋까지 했는데, 나중에 다시 그 저장소를 열어보니 방금 만든 커밋이 사라진 것처럼 보였습니다.

원인 분석

git submodule addgit submodule update로 서브모듈을 체크아웃하면, Git은 부모 저장소가 기록해둔 특정 커밋 하나를 그대로 체크아웃합니다 — 브랜치가 아니라 커밋을 직접 가리키므로 detached HEAD 상태가 됩니다.

detached HEAD 상태에서 커밋을 만들면, 그 커밋은 어떤 브랜치에도 속하지 않습니다. 이후 다른 브랜치를 체크아웃하거나(서브모듈 안에서), 부모 저장소가 서브모듈을 다시 업데이트하면, 브랜치에 속하지 않은 그 커밋은 어떤 참조로도 가리켜지지 않게 되어 결국 Git의 가비지 컬렉션 대상이 됩니다 — "사라진 것처럼 보이는" 이유입니다(완전히 삭제되기 전까지는 git reflog로 복구 가능한 경우도 있지만, 안전하게 의존할 방법은 아닙니다).

해결 방안

  1. 서브모듈 안에서 작업하기 전에 반드시 브랜치를 체크아웃합니다.
cd my-submodule
git checkout main    # 또는 작업할 브랜치
# 이제 커밋을 만들면 브랜치에 속함
  1. 서브모듈에서 만든 커밋은 서브모듈 자체의 원격 저장소에 별도로 push해야 합니다 — 부모 저장소에 커밋하는 것과 서브모듈 내용을 push하는 것은 별개의 작업입니다.
cd my-submodule
git push origin main   # 서브모듈 저장소에 push
cd ..
git add my-submodule   # 부모 저장소는 "이 커밋을 가리킨다"는 것만 기록
git commit -m "Update submodule reference"
  1. git submodule update --remote처럼 서브모듈을 최신 상태로 당겨오는 명령을 실행하기 전에, 그 서브모듈 안에 push하지 않은 커밋이 없는지 git status(서브모듈 디렉터리 안에서)로 항상 확인하는 습관이 필요합니다.
  2. 서브모듈이 실무에서 자주 예상치 못한 상태 관리 부담을 준다는 것은 잘 알려진 문제라, 팀에 따라 monorepo 구조나 패키지 매니저(pnpm workspace 등)로 대체하는 경우도 많습니다 — 정말로 독립된 버전 관리가 필요한 외부 저장소를 참조할 때만 서브모듈을 쓰는 것이 안전합니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.