[FIFAPulse] 개발기록 - git config core.ignorecase false 반나절 동안 삽질하기 , chat GPT 에 대해

조민호·2023년 5월 8일
3

git config core.ignorecase false에 대한 간략한 설명은 >>
[TOJ] 개발기록 - git config core.ignorecase false 옵션으로 git 대소문자 구분 적용하기



프로젝트를 진행하던 도중 , 어느 지인분이 최소한 배포를 먼저 진행 해 놓고 개발을 하는 것이 좋다고 하는 말을 듣고 Vercel로 배포를 진행하려 했다

이 과정에서 사실 엄청 단순한 에러였지만 거의 반나절동안 고생하면서 해결한 문제가 있었다

이번에는 그 상황에 대해 한번 작성해보려 한다


  • 현재 프로젝트의 폴더 구조 중 일부를 설명하자면 아래와 같다

    • Pages 폴더 : 라우터에 사용되는 페이지들
    • Component 폴더 : 각 페이지 안에 사용되는 컴포넌트들
    • Service 폴더 : api를 호출하는 메소드들
  • 그렇지만 프로젝트 개발 초기에 소문자로 시작하는 component , service 형태의 폴더명 으로 사용하고 있었기에 대문자 형태인 Component , Service 로 변경했다

  • 이 당시에 로컬에서 폴더 명은 제대로 변경이 됐지만 ,계속 import 관련 부분에서 에러를 뱉기 시작했다
    아래와 같이 import를 하면 변경된 대문자로 인식을 하지 못하고
    기존 폴더명인 소문자로 해야 인식이 되는 것이었다

    import FIFAData from '../../Services/FifaData'; // 해당 모듈을 찾을 수 없다는 에러
    
    import FIFAData from '../../services/FifaData'; // 정상 작동

    사실 이때 쎄한 느낌을 알아차리고 바로 해결을 했어야 하는데 로컬에서는 동작이 잘 되니까
    에러를 어찌저찌 대충 해결하고 넘겼었다

  • 문제는 한참 뒤에 , vercel로 배포를 진행하려고 했는데 계속 이러한 문제가 발생했다

    Cannot find module '../../Services/FifaData' or its corresponding type declarations.
    src/Pages/ChooseModeAndLogin/ChooseModeAndLogin.tsx(6,30): error TS2307: Cannot find module '../../Components/AskNickNameModal' or its corresponding type declarations.

    사실 에러메세지가 더 길고 다양했지만 캡처를 모르고 해놓지 않아서 일부만 가져온 것이다

  • 처음에 경로 문제인줄 알고 엄청 고민을 했지만 아무리 봐도 로컬에서는 제대로 돌아갔고 경로는 문제가 없었다
    설마 절대경로를 사용하지 않아서 그런건가 싶기도 했지만 vercel에서 절대 경로를 강제하진 않기에 그것도 문제가 아니었다
  • 다행히 공식문서를 뒤져보니 이와 관련된 에러를 표기하고 있었다

알고보니 경로나 타입은 문제가 없었고

현재 깃허브는 대소문자가 구분되지 않는 상황에서 내가 로컬에서 대문자로 변경한 Component 와 Service 관련한 부분에서 계속 에러가 발생한 것이다

공식문서에 나온대로 How To Resolve 에 git config core.ignorecase false 를 사용하라는 말이 있었으므로

git config core.ignorecase false 는 깃허브에서 대소문자를 구별해주는 옵션이다

이 옵션을 적용만 하면 되는 줄 알고 옵션을 적용했다

그랬더니 해당 폴더들( Page , Component )이 변경사항으로 스테이징 영역에 들어간 것을 확인 할 수 있었고

"아 제대로 변경됐구나" 싶어서 별 다른 걱정 없이 바로 커밋하고 push했다


여기서부터 대참사가 시작됐다




문제 상황


  • 다시 vercel로 배포를 진행했더니 또 다른 에러가 발생했다

    vercel의 에러 메세지를 자세히 보니

    • ../../Services/FifaData 와 ../../services/FifaData

    • ../../Components/AskNickNameModal 과 ../../components/AskNickNameModal

      라는 문구들이 수십개씩 찍혀있었다

      다시 깃허브를 들어가보니

      git config core.ignorecase false 옵션을 적용한 대문자로 변경된 새로운 폴더들이

      새로 생성되어 원격 저장소에 push가 되어 있었다

      아래 사진처럼 Component 와 component , Service 와 service 가 존재하는 것을 볼 수 있다

      즉 , 기존에 존재하는 소문자 폴더들이 대문자 폴더로 변경이 된 게 아니라

      소문자 폴더들은 그대로 있고 대문자 폴더들이 새로 생성된 것이다

      심지어 소문자로 생성된 폴더들은 git으로 추척도 되지 않았다

      그러므로 소문자로 된 폴더들을 어떻게든 지워보기 위해

      fetch나 , pull 을 아무리 해도 새로 업데이트도 되지 않았다

      원격 저장소에서 직접 지워도 로컬에서 계속 이상한 충돌이 발생했다

      그냥 원격 저장소에만 따로 존재해서 둥둥 떠다니며 로컬에서는 건드리지도 못하는 꼴이 된 것이다



이 때 , chat GPT한테 자문을 요구했고 알려주는 대로 진행했다

원래 기존 main브랜치를 직접적으로 손대는 일은 절대 발생해서는 안 되고

내 프로젝트의 컨벤션 또한 그렇게 하도록 내가 지정했지만

그 당시에는 너무 당황해서 어쩔 수 없이 main에서 직접 에러를 해결하려 했다

그렇지만 엎친데 덮친 격으로 전체적인 상황파악을 할 생각을 안하고

원격 저장소에는 추적되지 않는 파일이 존재하며 서로 꼬여있는 상태에서

gpt가 시키는대로 명령어만 계속 남발하다 보니

상상 이상으로 main의 브랜치 상황이 완전히 뒤죽박죽이 되어 버렸고

심지어 해당 브랜치에서 pull , 브랜치 이동 등 모든 동작을 할 때마다 에러가 발생했다
즉 , 그 어떠한 동작도 더이상 진행할 수 없었다

( 나도 이걸 해결하고 싶은데 애초에 소문자로 된 폴더들이 내 로컬에 존재하지도 않고 원격에 있는 것도 받아와지지 않는데 뭘 어쩌라는… )


어쩔 수 없이 reset --hard 를 사용할 수 밖에 없었다

git config core.ignorecase false 를 진행하기 전으로

reset --hard 를 한 다음 --force push를 해서 우선 처음부터 다시

차근차근 진행을 해보려고 했다



reset --hard 까지는 제대로 진행이 됐는데 그 이후에 또 에러가 발생했다

이때 멘탈이 너무 나가버려서 캡처를 못했지만
하나 기억나는 것은 git remote -v 를 했을 때
origin https://github.com/minh0518/FIFAPulse.git 가 나와야 하는데
origin https://github.com/minh0518/tmp.git 로 바뀌어 있었고
다시 변경도 안 됐다

이 에러는 뭐 도저히 손을 댈 수 없는 에러 같았지만 정말 우연히 프론트엔드 관련 오픈채팅방에서 다들 깃허브가 안된다는 말을 하기 시작하는 걸 봤고

구글에서 github status를 검색해보니

다행이었던 것인지 불운이었던 것인지 모르겠지만

직전의 에러는 현재 github 자체가 다운되어 있어서 에러가 발생했던 것이었다




해결


결국 깃헙이 안정화 되기까지 기다렸다가 reset -- hard + --force push 조합으로

완전히 로컬과 원격 저장소를 되돌린 다음, 다시 처음부터 진행했다


알고보니 매우매우 간단했다

원격 저장소의 캐시만 지워주면 해결이 됐던 문제였다

git config core.ignorecase false를 적용할때 아래와 같이 진행하면 된다

  1. git config core.ignorecase false 옵션 적용

  2. 자동으로 기존에 존재했던 파일의 대소문자 변경사항이 적용 or

    이후에 내가 직접 해당 파일의 대소문자로 변경

  3. 그리고 push하면 원격 저장소에는 대문자 , 소문자로 된

    2개의 파일 존재 (component Component)

  4. 여기서 git rm -r --cached . 명령어로

    내 로컬에 있는 파일은 유지한채 remote의 파일을 삭제

  5. 그러고 나서 다시 원격 저장소에 push해서 해결

다른 블로그를 보니 2번까지 진행하고 나서 push지 않고
바로 git rm -r --cached . 사용하고 한번에 push해도 된다고 한다

( 사실 git rm -r --cached . 또한 reset 하기 전 , 꼬일대로 꼬인 상태에서 사용 했었다가 미친듯한 에러가 남발했지만 너무 정신이 없어서 뒤죽박죽이라 제대로 어떤 에러였고 어떻게 해결했는지 기억은 잘 나지 않는다. 어찌 됐든 , reset으로 되돌아와서 위의 방법으로 해결했다 )



정리


  • 깃은 대소문자를 구별하지 못한다 그러므로 파일의 대소문자를 변경하고 push 해도 변경사항이 반영되지 않는다
  • git config core.ignorecase false 를 적용하면 대소문자를 구별하게 된다
  • 여기서 , 과거에 대소문자 변경을 하고 origin에 push 를 했었던

    파일이 있다면 그 파일들이 변경사항으로 처리가 돼서 커밋이 가능해진다

    그리고 이 상태로 origin에 push하게 되면

    origin에는 소문자 파일 , 대문자 파일 2개가 생성된다

    심지어 새로 바꾼 파일 말고 기존 파일은 git에서 추적조차 되지 않는다

  • 이 때 git rm -r --cached . 명령어로

    내 로컬에 있는 파일은 유지한채 remote의 파일의 캐시를 삭제한다

  • 그러고 나서 원격 저장소에 다시 push해서 원격 저장소에도 반영을 해준다
    이렇게 하면 origin에도 완벽하게 소문자 파일이 제거가 되는 것이다!

다른 블로그를 보니 git config core.ignorecase false 까지 적용하고
변경사항으로 처리가 됐을 때 , 바로 push하지 않고
바로 git rm -r --cached . 까지 진행한 다음,
최종적으로 한번에 push해도 된다고 한다




느낀 점들


되돌아보면 그냥 캐시를 지우는 명령어 하나만 작성하면 되는데

거의 5~6시간을 쓰면서 엄청나게 되돌아왔다.

알고리즘에 빗대어 보면 , 내가 진행하는 모든 동작마다 계속 에러가 재귀적으로 쉴새없이 호출되고

해당 에러를 해결해서 재귀를 탈출하면 다음에 또 더 깊은 재귀가 끝도 없이 호출되는 기분이랄까…

다들 알다시피 깃 특성상 하나의 에러를 바로 해결하지 않으면 여기서부터 파생되는 에러들이 정말 많은데 그 당시 도저히 캡처를 하며 기록을 해 놓을 정신이 아니었다보니

이 글에 작성한 에러보다 더 많은 에러가 존재했지만 전부 기록을 하지 못 했다

뭐가 됐든 , 이번 상황은 당연하게 한번쯤을 겪을 수 있는 에러라기 보단

전적으로 나의 평소 잘못된 습관으로 인해 발생했다고 생각한다


만약 git config core.ignorecase false를 사용하기에 앞서 , 최소한 이 명령어에 대해 한번이라도 검색을 해 보았으면 어떻게 됐을까?

깃 관련 동작은 하나하나 매우 치명적인 결과를 내 놓을 수 있으므로 사용하기 전에 구글링을 해보면서

최소한의 공부를 하고 진행 했어야 했는데 귀찮은 나머지

“아 몰라 그냥 되겠지” 라는 마인드로 명령어 하나에 의존해버린 탓에 이런 상황이 발생한 것이다


chat gpt에 대해

나는 chat gpt 자체를 원래 잘 사용하지 않는 편이었다

h1이 인라인 태그라고 말하질 않나

JS의 map 메소드에서 return을 사용하면 for문의 break 역할을 할 수 있다하질 않나

말 같지도 않은 소리를 논리정연하게 하는 것을 보고 아직은 믿을 수 없다고 생각했다


근데 이번처럼 갑자기 급박한 상황이 닥치니 나도 모르게

쉽게 답변을 찾을 수 있는 유혹에 이끌린 것 같다

당황할수록 침착하고 깊게 생각해야 하는데

어떻게든 빨리 이걸 해결해야 한다는 강박으로 인해 그랬던 걸까,

결론적으로 이게 돌이킬 수 없는 강을 건너게 한 것이다

chat gpt는 정말 대단한 도구임에는 틀림없다

그렇지만 도구일 뿐이다

오로지 질문자의 질문에 대답만 할 뿐이며

그 이상으로 나아가 전체적인 틀까지 파악해서 모든 것을 알려주진 않는다

질문 수준에 따라 당연히 다르겠지만 지금은 나의 경우에 빗대어 표현하는 것이다


예를 들어 아래처럼 1부터 순차적으로 숫자가 나와하므로

마지막에는 5가 찍여야 하는데

1 2 3 4 5

2가 마지막으로 가버려서 5번째 값이 2가 나온 상황이다

1 3 4 5 2

이때 내가

  • “현재 상황은 이렇고 , 원래는 1부터 순차적으로 나와야하고 , 전체 길이는 몇이어야 하며 , …” 이렇게 나 스스로도 전체적인 상황을 파악하고 물어보는 것이 아니라
  • 단순히 “마지막에 5가 나와야 하는데 왜 2가 나왔지” 라고 물어본다면 chat gpt는 뭐라고 대답할까?

오로지 질문자가 물어본 현 상황에 대한 해결책만 알려줄 뿐이므로

2가 마지막으로 왔으니 뒤에 3 4 5를 추가하라고 할 것이다

그러므로 오히려 아래와 같이 더 말도 안되는 결과가 나오기 마련이다

1 3 4 5 2 3 4 5

내가 정확히 이런 상황이었다



무엇이 문제였는지에 대해 생각하며 전체 상황을 파악해야 했지만

오로지 직전 상황의 결과만 바라보면서 여기서의 해결만 요구하니 chat gpt 입장에서는

  • 마지막에 있는 2가 기존의 2가 들어갈 자리에 없네요. 순서를 다시 정렬 해 보세요 가 아닌
  • 더더욱 꼬여있는 상황으로 가는 답변을 알려줄 수 밖에 없는 것이다

제로초 님의 유튜브 영상을 보면 아래와 같은 말씀을 하신다

“ chat gpt 를 사용할때 반드시 내가 어느 정도 알고 있는 것에 대한 연장선의 도구로써 사용해야지 , 아무것도 모르는 부분에 대해 정답만 갈구하면서 chat gpt에 이끌려가게 되면 큰일납니다”


자동화


참고 : Git 설정 파일 팀원들과 공유하기

다른 사람들과 협업을 할 때에는 git config core.ignorecase false 를 나만 해서는 안 되고

모든 팀원들이 이 옵션을 적용해야 한다

그렇지만 매번 모든 팀원들이 100% 이 옵션을 적용한다는 보장은 없다

그러므로 자동화를 진행하면 좋다


  1. repository root에 .gitconfig 파일을 생성하고 추가하고 싶은 설정들을 입력한다.

    # .gitconfig
    [core]
        ignorecase = false

    그리고 아래의 명령어를 적용해야 .gitconfig 파일이 적용되면서 해동 옵션이 적용된다

    git config --local include.path ../.gitconfig
  1. 그렇지만 저것 역시 .gitconfig 관련해서 긴 명령어를 작성해야 하므로

    아래와 같은 스크립트를 추가해주면 보다 간편하게 사용이 가능하다

    💡 npm이나 yarn 같은 패키지 매니저를 사용하고 있는 경우에만 가능
    // package.json
    "scripts": {
        "gitconfig": "git config --local include.path ../.gitconfig"
    }

    그리고 나서 팀원들에게 ,혹은 README.md에 
    npm gitconfig나 yarn gitconfig 한번만 실행해달라고 해주면 된다

profile
할 수 있다

2개의 댓글

같은 오류를 겪었는데 덕분에 해결하였습니다 감사합니다 ㅎㅎㅎ

1개의 답글