git worktree move submodule error가 나면 --force나 Finder 이동부터 하면 안 된다. 상위 worktree와 submodule의 변경을 각각 확인한 뒤 현재 경로를 유지하거나, 변경을 원격에 보존해 새 위치에 clone하거나, 로컬 주 저장소를 새 경로로 clone하는 방법을 고른다.

목차
먼저 두 저장소의 변경을 따로 확인하세요
Mac에서는 Command + Space를 누르고 터미널을 여세요. 아래 /현재/worktree/경로를 실제 경로로 바꿉니다.
git -C "/현재/worktree/경로" status --short --branch
git -C "/현재/worktree/경로" submodule status --recursive
git -C "/현재/worktree/경로" submodule foreach --recursive 'git status --short --branch'
첫 명령은 상위 worktree, 마지막 명령은 각 submodule 안의 변경을 보여 준다. 어느 쪽이든 변경이 나오면 먼저 각 저장소에서 별도로 커밋하거나 안전한 위치에 복사한다. 상위 저장소의 커밋만으로 submodule 내부의 아직 커밋하지 않은 파일이 자동 보존되지는 않는다.
clean인데도 왜 move가 실패하나요?
Git 공식 worktree 문서는 submodule을 포함한 linked worktree를 git worktree move로 옮길 수 없다고 설명한다. 2026-09-19 macOS Git 2.38.1 재현에서도 상위와 submodule이 모두 clean인 상태에서 move는 exit 128로 끝났다.
fatal: working trees containing submodules cannot be moved or removed
git submodule deinit -f --all 뒤에도 같은 오류가 났다. 따라서 deinit이나 force를 성공이 확인된 해결책처럼 반복하면 안 된다. git worktree repair도 수동으로 옮겨진 경로의 연결을 복구하는 명령이며, 이 move 제한을 허용하는 옵션은 아니다.
가장 안전한 선택은 무엇인가요?
경로 변경이 꼭 필요하지 않다면 현재 worktree를 그대로 쓰는 것이 가장 간단하다. 이미 사라진 경로의 등록만 남았다면 stale worktree를 prune하는 순서를 먼저 확인한다.
새 경로가 꼭 필요하고 원격 저장소를 사용할 수 있다면 다음 순서로 진행합니다.
- 각 submodule 안의 변경을 먼저 커밋하고, 원격 방식을 쓸 때는 그 submodule commit을 해당 원격에 push한다.
- 상위 worktree에서 바뀐 submodule 경로를
git add한 뒤 다시 커밋한다. 이 상위 commit이 새 submodule commit을 가리키는 gitlink를 보존한다. - 상위 저장소의 필요한 branch를 원격에 push하고 웹 저장소에서 상위·submodule commit이 모두 보이는지 확인한다.
- 새 경로에 저장소를 clone하고 해당 branch를 checkout한다.
git submodule update --init --recursive를 실행한다.- 새 경로에서 상위 commit과 각 submodule commit이 원래 값과 같은지 확인한다.
- 새 경로 검증이 끝난 뒤에만 기존 worktree 정리를 별도 작업으로 진행한다.
복사 가능한 검증 명령은 다음과 같습니다.
git -C "/현재/worktree/경로" rev-parse HEAD
git -C "/새/clone/경로" rev-parse HEAD
git -C "/현재/worktree/경로" submodule status --recursive
git -C "/새/clone/경로" submodule status --recursive
두 경로의 상위 commit과 submodule commit이 각각 같아야 한다. 원격을 쓸 수 없거나 아직 커밋할 수 없는 변경이 있다면 기존 폴더를 지우지 않고 현재 경로를 유지한다.
로컬 전용 branch는 어떻게 새 경로로 옮기나요?
상위 저장소의 branch를 외부 원격에 push하지 않았더라도 주 저장소를 로컬 원본으로 clone하면 새 경로에서 복원할 수 있다. 단, 이 설명은 상위 branch에만 해당한다. submodule의 새 commit은 상위 저장소 clone에 포함되지 않는다. 그 commit이 .gitmodules의 URL에서 실제로 접근 가능하지 않으면 아래 절차를 진행하지 말고 기존 경로를 보존한다.
git -C "/현재/worktree/경로" rev-parse --path-format=absolute --git-common-dir
출력이 /주/저장소/.git처럼 나오면 .git을 뺀 /주/저장소를 아래 원본 경로로 사용합니다. 현재 branch 이름도 기록합니다.
git -C "/현재/worktree/경로" branch --show-current
git clone --no-local "/주/저장소" "/새/clone/경로"
git -C "/새/clone/경로" switch "로컬-branch-이름"
git -C "/새/clone/경로" submodule update --init --recursive
--no-local은 하드링크 최적화 대신 실제 Git 객체를 복사해 새 clone을 독립시킨다. 이 명령은 외부 서버로 push하지 않는다. submodule URL이 사내 서버나 로컬 경로라면 새 경로에서 접근 가능한지 따로 확인해야 한다.
submodule update가 not our ref 또는 commit을 찾지 못했다는 오류로 끝나면 submodule의 로컬 전용 commit이 URL 쪽 저장소에 없는 상태일 수 있다. 이때 상위 gitlink를 이전 commit으로 되돌리거나 강제로 정리하면 안 된다. 기존 worktree와 submodule 폴더를 그대로 보존하고, 해당 submodule commit을 접근 가능한 원격에 보존하거나 submodule 원본을 별도로 안전하게 복제한 뒤 다시 진행한다. 이번 직접 재현은 submodule 원본에 이미 존재한 commit만 확인했으며, submodule의 미전송 새 commit 이동은 확인하지 않았다.
명령이 멈추면 다음처럼 분기한다.
| 오류 | 뜻 | 다음 행동 |
|---|---|---|
repository ... does not exist |
주 저장소 경로가 틀렸거나 접근할 수 없음 | rev-parse --git-common-dir 출력에서 .git을 뺀 경로를 다시 확인한다. |
invalid reference 또는 pathspec ... did not match |
새 clone에 branch가 없음 | 기존 worktree에서 branch 이름과 commit을 다시 확인하고 기존 폴더를 유지한다. |
| submodule clone 인증·경로 오류 | submodule URL에 접근할 수 없음 | .gitmodules의 URL과 로그인·로컬 경로를 해결할 때까지 기존 폴더를 지우지 않는다. |
새 경로가 완전한지 어떻게 확인하나요?
기존 경로를 정리하기 전에 상위 commit, submodule commit, 변경 상태를 모두 대조하세요.
git -C "/현재/worktree/경로" rev-parse HEAD
git -C "/새/clone/경로" rev-parse HEAD
git -C "/현재/worktree/경로" submodule status --recursive
git -C "/새/clone/경로" submodule status --recursive
git -C "/새/clone/경로" status --short --branch
두 rev-parse HEAD가 같고, submodule status --recursive의 경로별 commit이 같아야 한다. 새 경로의 status 출력에 예상하지 않은 변경이 있으면 기존 경로를 정리하면 안 된다.
기존 linked worktree는 언제 정리하나요?
검증이 끝난 뒤 주 저장소에서 일반 제거를 먼저 시도한다.
git -C "/주/저장소" worktree remove "/현재/worktree/경로"
일반 제거가 같은 submodule 제한으로 멈추면 기존 경로를 그대로 보존한다. remove --force는 폴더를 삭제하며 경로 오입력·중첩 경로·ignored 파일까지 함께 확인해야 하므로 이 초보자용 절차에서는 실행 명령을 제공하지 않는다. 디스크 정리가 꼭 필요하면 별도 백업 뒤 숙련자 검토를 받아 진행한다. 로컬 재현에서 remove --force는 exit 0을 반환했지만, 재현 스크립트의 후속 파싱 오류 때문에 폴더와 등록의 사후 상태를 확인하지 못했다. 이 결과를 완료 근거로 쓰지 않는다.
자주 묻는 질문
git worktree repair로 바로 해결할 수 있나요?
아니다. repair는 수동 이동 등으로 끊어진 연결을 복구하는 명령이다. submodule이 든 linked worktree의 move 제한을 해제하지 않는다.
remove --force를 두 번 써야 하나요?
횟수를 먼저 정하면 안 된다. 이 글의 재현은 사후 상태까지 확인하지 못했으므로 강제 제거를 해결 절차로 권하지 않는다. 새 clone을 검증한 뒤에도 기존 경로를 보존하고, 디스크 정리는 별도 백업과 숙련자 검토 뒤 진행한다.
검증 범위
- 확인일: 2026-09-19~20
- 환경: macOS, Git 2.38.1, 비민감 임시 저장소와 로컬 submodule
- 확인: 초기화된 submodule을 포함한 clean linked worktree에서 move exit 128, deinit 뒤 동일 오류, 로컬 주 저장소에서
--no-localclone 후 로컬 전용 branch checkout, 상위·submodule commit 일치, 일반 remove exit 128, commit 대조 후remove --forceexit 0 반환 - 미확인: 재현 스크립트의 후속 파싱 오류 때문에 강제 제거 직후 폴더와 worktree 등록의 사후 상태는 별도 확인하지 못함
- 미확인: 최신 Git 전체 버전, Codex Desktop의 자동 이동 동작, 정확 월간 검색량과 독자 직접 피드백
검증 기준
- 마지막 업데이트일: 2026-09-20
- 확인 환경: macOS Git 2.38.1, 비민감 임시 상위 저장소와 로컬 submodule
- 주요 근거: Git worktree 공식 문서 · Git clone 공식 문서 · Git submodule 공식 문서
직접 만든 실습 자료와 새 도구 소식
AI 도구로 만든 실습 자료, 달라진 기능과 강의 소식을 준비하고 있습니다. 발송을 시작하면 안내해 드려요. 먼저 확인 메일에서 본인 이메일을 확인해 주세요.
신청하기 전에 첫 소식 미리보기에서 내용과 자료를 확인해 보세요.