본문 바로가기

Git

[Git] 깃 저장소에서 여러 디렉토리 관리하려고 하고 하는데 어떤 디렉토리에 -> 표시가 생기고 해당 디렉토리가 들어가지 않는 문제

728x90

🚨 문제 요약

  1. GitHub 리포지토리에서 폴더 옆에 화살표(→) 아이콘이 표시됨
    → 이건 **해당 폴더가 서브모듈(submodule)**로 잘못 추가되어 있기 때문에 발생한 문제입니다.
  2. git rm --cached 명령어로 서브모듈을 삭제하고 나서 푸시(push)하려 했을 때 에러 발생
    → error: failed to push some refs 에러가 발생한 이유는 원격 리포지토리와 로컬 리포지토리의 기록이 일치하지 않기 때문입니다.

🔎 왜 화살표(→) 표시가 발생했나요?

화살표(→) 아이콘은 **Git 서브모듈(submodule)**을 나타냅니다.

💡 서브모듈이란?

  • 서브모듈은 Git 리포지토리 안에 또 다른 Git 리포지토리를 포함할 때 사용됩니다.
  • 서브모듈은 **바로가기(링크)**처럼 동작합니다. 실제 폴더가 리포지토리에 포함되지 않고, 참조 경로만 저장됩니다.
  • 서브모듈이 있는 상태에서 리포지토리를 복제(clone)하면, 내부 폴더의 내용은 비어있고 해당 경로가 다른 리포지토리를 가리키는 링크로 남아있습니다.

💡 왜 서브모듈이 추가되었나요?

이 문제는 보통 다음과 같은 실수로 발생합니다:

  1. 다른 리포지토리를 복사해왔을 때
    예를 들어, LearnReactNative라는 폴더가 이미 다른 Git 리포지토리였는데, 이를 현재 리포지토리에 복사했을 경우.
  2. 👉 이 경우, LearnReactNative 폴더 안에 .git 폴더가 그대로 남아있어 Git이 이를 별도의 리포지토리로 인식하고, 자동으로 서브모듈로 추가됩니다.
  3. 실수로 git submodule add 명령어를 사용했을 때이런 명령어를 사용하면 해당 폴더가 서브모듈로 추가됩니다.
git submodule add <url> LearnReactNative

💡 화살표(→) 표시의 의미

GitHub에서 폴더 옆에 화살표(→) 표시가 있는 이유는:

  • 해당 폴더가 서브모듈로 추가되었기 때문입니다.
  • 서브모듈은 참조만 포함하고, 실제 파일은 포함되지 않기 때문에 화살표로 표시됩니다.

🛠 어떻게 문제를 해결했나요?

📝 문제 해결 과정 요약

  1. 서브모듈로 잘못 추가된 LearnReactNative 폴더를 Git에서 제거했습니다.
  2. 서브모듈의 잔여 메타데이터와 캐시를 삭제했습니다.
  3. 일반 폴더로 다시 추가하고 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가 더 잘된다.

 

번외) 추가 개념 설명

 

문제가 발생한 원인

  1. 서브모듈로 추가된 상태
    TodoApp 디렉토리가 이미 독립적인 Git 리포지토리로 관리되고 있었습니다.
    • git add TodoApp 명령을 실행하면 Git은 이 디렉토리를 일반 폴더로 추가하는 대신 서브모듈로 인식합니다.
    • Git은 .git/modules/TodoApp에 서브모듈 메타데이터를 생성하고, .git/config 파일에 서브모듈 관련 설정을 추가합니다.
  2. 서브모듈의 특성
    서브모듈은 별도의 Git 리포지토리로 관리되므로:
    • 서브모듈의 변경사항은 상위 리포지토리에 직접 포함되지 않습니다.
    • 복제(clone) 시 서브모듈은 원본 URL을 참조하며, 해당 내용을 자동으로 가져오지 않습니다.
  3. 원하는 동작과 불일치
    TodoApp을 일반 디렉토리로 관리하려고 했지만, 서브모듈로 추가되면서 상위 리포지토리가 이를 독립적인 Git 리포지토리로 계속 인식한 것입니다.

해결 과정의 원리

  1. 서브모듈 캐시와 메타데이터 제거
    서브모듈로 추가된 디렉토리를 일반 디렉토리로 변경하려면:
    • Git 인덱스메타데이터에서 서브모듈 정보를 삭제해야 합니다.
    • git rm --cached TodoApp: Git의 인덱스에서 TodoApp 제거
    • rm -rf .git/modules/TodoApp: 서브모듈 메타데이터 삭제
  2. 내부 .git 폴더 제거
    서브모듈 디렉토리(TodoApp) 내부에 .git 폴더가 존재하면 Git은 여전히 이를 독립적인 리포지토리로 인식합니다.
    • 따라서, rm -rf TodoApp/.git 명령으로 내부 .git 폴더를 삭제하여 일반 폴더로 변환했습니다.
  3. 변경 사항 재추가 및 커밋
    • git add TodoApp: 이제 TodoApp은 일반 디렉토리로 추가됩니다.
    • git commit: 서브모듈 제거 및 일반 디렉토리로 추가된 변경사항을 기록합니다.
  4. 원격 리포지토리와 동기화
    • 이전에 서브모듈로 설정된 정보가 원격 리포지토리에 남아 있다면 이를 덮어쓰기 위해 변경 사항을 푸시합니다.
    • 이로 인해 원격 리포지토리에서도 TodoApp을 일반 디렉토리로 관리할 수 있게 됩니다.

요약

  • 문제 원인: TodoApp 디렉토리가 서브모듈로 추가되어 Git이 이를 독립적인 리포지토리로 인식했기 때문입니다.
  • 해결 원리: 서브모듈 정보를 삭제하고 내부 .git 폴더를 제거하여 Git이 이를 일반 폴더로 인식하도록 만들었습니다.
728x90