🚨 문제 요약
- GitHub 리포지토리에서 폴더 옆에 화살표(→) 아이콘이 표시됨
→ 이건 **해당 폴더가 서브모듈(submodule)**로 잘못 추가되어 있기 때문에 발생한 문제입니다. - git rm --cached 명령어로 서브모듈을 삭제하고 나서 푸시(push)하려 했을 때 에러 발생
→ error: failed to push some refs 에러가 발생한 이유는 원격 리포지토리와 로컬 리포지토리의 기록이 일치하지 않기 때문입니다.
🔎 왜 화살표(→) 표시가 발생했나요?
화살표(→) 아이콘은 **Git 서브모듈(submodule)**을 나타냅니다.
💡 서브모듈이란?
- 서브모듈은 Git 리포지토리 안에 또 다른 Git 리포지토리를 포함할 때 사용됩니다.
- 서브모듈은 **바로가기(링크)**처럼 동작합니다. 실제 폴더가 리포지토리에 포함되지 않고, 참조 경로만 저장됩니다.
- 서브모듈이 있는 상태에서 리포지토리를 복제(clone)하면, 내부 폴더의 내용은 비어있고 해당 경로가 다른 리포지토리를 가리키는 링크로 남아있습니다.
💡 왜 서브모듈이 추가되었나요?
이 문제는 보통 다음과 같은 실수로 발생합니다:
- 다른 리포지토리를 복사해왔을 때
예를 들어, LearnReactNative라는 폴더가 이미 다른 Git 리포지토리였는데, 이를 현재 리포지토리에 복사했을 경우. - 👉 이 경우, LearnReactNative 폴더 안에 .git 폴더가 그대로 남아있어 Git이 이를 별도의 리포지토리로 인식하고, 자동으로 서브모듈로 추가됩니다.
- 실수로 git submodule add 명령어를 사용했을 때이런 명령어를 사용하면 해당 폴더가 서브모듈로 추가됩니다.
git submodule add <url> LearnReactNative
💡 화살표(→) 표시의 의미
GitHub에서 폴더 옆에 화살표(→) 표시가 있는 이유는:
- 해당 폴더가 서브모듈로 추가되었기 때문입니다.
- 서브모듈은 참조만 포함하고, 실제 파일은 포함되지 않기 때문에 화살표로 표시됩니다.
🛠 어떻게 문제를 해결했나요?
📝 문제 해결 과정 요약
- 서브모듈로 잘못 추가된 LearnReactNative 폴더를 Git에서 제거했습니다.
- 서브모듈의 잔여 메타데이터와 캐시를 삭제했습니다.
- 일반 폴더로 다시 추가하고 GitHub에 푸시했습니다.
✅ 문제 해결 단계별 설명
1단계: 서브모듈 제거
먼저, LearnReactNative 폴더를 Git의 인덱스에서 제거했습니다.
(--cached 옵션을 사용했기 때문에 디스크에서 삭제되지는 않고, Git에서만 제거됨)
git rm --cached LearnReactNative
➤ 이 명령어가 하는 일:
- --cached 옵션을 사용하면, Git이 해당 폴더를 추적하지 않게 됩니다.
- 폴더 자체는 디스크에 남아있지만, Git 기록에서는 해당 폴더가 삭제됩니다.
2단계: 서브모듈 메타데이터 삭제
서브모듈은 Git 내부에 메타데이터 정보로 관리됩니다.
이 메타데이터는 .git/modules/ 디렉토리에 저장되므로, 해당 폴더를 삭제했습니다.
내부에 폴더에 .git 이 있다면 삭제
rm -rf .git/modules/LearnReactNative
rm -rf LearnReactNative/.git
➤ 이 명령어가 하는 일:
- Git 내부에서 서브모듈에 대한 모든 기록을 삭제합니다.
3단계: 변경사항 커밋
서브모듈 삭제 후 변경사항을 커밋했습니다.
git commit -m "Removed LearnReactNative submodule"
4단계: 폴더를 일반 폴더로 다시 추가
이제 LearnReactNative 폴더를 일반 폴더로 다시 추가했습니다.
d LearnReactNative git commit -m "Added LearnReactNative as a regular folder"
5단계: 원격 변경사항과 병합
GitHub에서 원격 리포지토리에 이미 변경사항이 있었기 때문에, 먼저 원격 변경사항을 pull해서 로컬과 원격 기록을 병합했습니다.
git pull origin master --rebase
6단계: 변경사항 푸시
마지막으로 변경사항을 GitHub에 푸시했습니다.
git push origin khs-branch
🔎 왜 git push가 처음에 실패했나요?
이유: 원격 리포지토리와 로컬 리포지토리의 기록이 일치하지 않았기 때문입니다.
- Git은 원격 리포지토리의 최신 상태와 로컬 리포지토리의 상태가 일치하지 않으면 푸시를 거부합니다.
- 이런 경우, git pull로 최신 변경사항을 가져와 병합한 후에 푸시해야 합니다.
✅ 최종 요약
문제 원인해결 방법
폴더가 서브모듈로 잘못 추가됨 | git rm --cached LearnReactNative |
서브모듈 메타데이터가 남아있음 | rm -rf .git/modules/LearnReactNative |
원격 리포지토리와 로컬 기록 불일치 | git pull origin master --rebase 후 git push |
🎯 최종 명령어 정리
# 1. 서브모듈 제거
git rm --cached LearnReactNative
# 2. 서브모듈 메타데이터 삭제
rm -rf .git/modules/LearnReactNative
# 3. 변경사항 커밋
git commit -m "Removed LearnReactNative submodule"
# 4. 원격 변경사항 가져오기
git pull origin master --rebase
rm -rf LearnReactNative/.git
# 5. 일반 폴더로 추가
git add LearnReactNative
git commit -m "Added LearnReactNative as a regular folder"
# 6. 변경사항 푸시
git push origin khs-branch
🔎 다른 방법2)
TodoApp 디렉토리를 서브모듈로 잘못 추가한 후 일반 폴더로 변환하려고 했는데, 여전히 Git에서 서브모듈로 표시되는 경우, 다음 단계를 따라 문제를 해결할 수 있습니다.
1. 서브모듈 캐시 제거
서브모듈 관련 캐시와 메타데이터가 남아있을 가능성이 있습니다. 아래 명령어로 제거하세요:
git rm --cached TodoApp # Git 인덱스에서 제거
rm -rf .git/modules/TodoApp # 서브모듈 메타데이터 삭제
2. 서브모듈 디렉토리 정리
서브모듈 디렉토리 내부에 .git 폴더가 남아있을 수 있습니다. 이를 삭제하여 일반 폴더로 변환하세요:
rm -rf TodoApp/.git
3. 변경 사항 커밋
위 작업이 완료되었으면 변경 사항을 커밋하세요:
git add TodoApp
git commit -m "Converted TodoApp to a regular folder"
4. 원격 리포지토리와 동기화
원격에 서브모듈로 설정된 상태가 남아있을 수 있습니다. 이를 제거하고 변경 사항을 푸시하세요:
git push origin khs-branch
✅ 최종 결과
- GitHub에서 화살표(→) 표시가 사라지고, LearnReactNative 폴더가 일반 폴더로 표시됩니다.
- 모든 서브모듈 기록이 삭제되었고, 문제가 해결되었습니다.
- 느낌상 방법2가 더 잘된다.
번외) 추가 개념 설명
문제가 발생한 원인
- 서브모듈로 추가된 상태
TodoApp 디렉토리가 이미 독립적인 Git 리포지토리로 관리되고 있었습니다.- git add TodoApp 명령을 실행하면 Git은 이 디렉토리를 일반 폴더로 추가하는 대신 서브모듈로 인식합니다.
- Git은 .git/modules/TodoApp에 서브모듈 메타데이터를 생성하고, .git/config 파일에 서브모듈 관련 설정을 추가합니다.
- 서브모듈의 특성
서브모듈은 별도의 Git 리포지토리로 관리되므로:- 서브모듈의 변경사항은 상위 리포지토리에 직접 포함되지 않습니다.
- 복제(clone) 시 서브모듈은 원본 URL을 참조하며, 해당 내용을 자동으로 가져오지 않습니다.
- 원하는 동작과 불일치
TodoApp을 일반 디렉토리로 관리하려고 했지만, 서브모듈로 추가되면서 상위 리포지토리가 이를 독립적인 Git 리포지토리로 계속 인식한 것입니다.
해결 과정의 원리
- 서브모듈 캐시와 메타데이터 제거
서브모듈로 추가된 디렉토리를 일반 디렉토리로 변경하려면:- Git 인덱스와 메타데이터에서 서브모듈 정보를 삭제해야 합니다.
- git rm --cached TodoApp: Git의 인덱스에서 TodoApp 제거
- rm -rf .git/modules/TodoApp: 서브모듈 메타데이터 삭제
- 내부 .git 폴더 제거
서브모듈 디렉토리(TodoApp) 내부에 .git 폴더가 존재하면 Git은 여전히 이를 독립적인 리포지토리로 인식합니다.- 따라서, rm -rf TodoApp/.git 명령으로 내부 .git 폴더를 삭제하여 일반 폴더로 변환했습니다.
- 변경 사항 재추가 및 커밋
- git add TodoApp: 이제 TodoApp은 일반 디렉토리로 추가됩니다.
- git commit: 서브모듈 제거 및 일반 디렉토리로 추가된 변경사항을 기록합니다.
- 원격 리포지토리와 동기화
- 이전에 서브모듈로 설정된 정보가 원격 리포지토리에 남아 있다면 이를 덮어쓰기 위해 변경 사항을 푸시합니다.
- 이로 인해 원격 리포지토리에서도 TodoApp을 일반 디렉토리로 관리할 수 있게 됩니다.
요약
- 문제 원인: TodoApp 디렉토리가 서브모듈로 추가되어 Git이 이를 독립적인 리포지토리로 인식했기 때문입니다.
- 해결 원리: 서브모듈 정보를 삭제하고 내부 .git 폴더를 제거하여 Git이 이를 일반 폴더로 인식하도록 만들었습니다.
'Git' 카테고리의 다른 글
[git] 서브모듈 해쉬 커밋 충돌 날 때 충돌 해결 편법 (0) | 2024.12.10 |
---|---|
여러 브랜치를 관리 해야 하고, git pull 함부로 써서 충돌 처리를 하기 힘들 때 좋은 방법 (0) | 2024.06.28 |
깃 체리픽 하는 방법 (0) | 2024.05.16 |
git 작업을 이전으로 되돌리는 방법들 (0) | 2023.11.20 |
Git : 여러 프로젝트들 모음에서 새로운 프로젝트 추가 시 문제 해결 방법 (3) | 2023.10.25 |