본문 바로가기
Dev/Git

git 한글 깨짐 현상을 해결하면서

by 생귄맨 2021. 7. 26.

git status를 했을 때 한글 깨짐 현상

최근에 블로그 포스팅에 쓴 "게임판 덮기" 알고리즘 문제 소스코드를 Github에 커밋하려고, git add 후 git status 명령어를 쳤는데,

"게임판 덮기.cpp"로 나와야하는 것이, backslash 와 숫자들의 조합으로 표현된 것(걍 깨진 것)을 볼 수 있었다. (심기 불편...)

 

간단히 구글링을 해보니, 터미널에

git log --global core.quotepath false

이 명령어를 치면 문제가 해결이 된다고 나와있었다.

 

git log --stat을 통해 잘 적용되었는지 확인했다. (이미 커밋한 상태였어서 staging area에 아무것도 없었다. 그래서 git status로는 파일명을 확인할 수 없었기에... 이 명령어를 사용했다.)

잘 적용되었다.

 

같은 한글 깨짐 현상을 해결하실 분들은 여기까지 읽으시면 됩니다!

다음부터는 제가 추가적으로 학습한 내용으로, TMI가 가득할 수 있으니 스킵하셔도 좋습니다. 혹시나 궁금하신 분들은 계속해서 읽으시면 됩니다..!


문제는 해결되었지만, git config 다큐멘테이션을 확인해보니 core.quotepath에 대해 자세히 나와 있어서 좀 더 공부하기로 했다.

(git config --global 은 예전에 git 최초 설정할 때, git log --global user.email 로 사용해봤던 기억이 있다.)

 

core.quotepath는 

Commands that output paths (e.g. ls-files, diff), will quote "unusual" characters in the pathname by enclosing the pathname in double-quotes and escaping those characters with backslashes in the same way C escapes control characters (e.g. \t for TAB, \n for LF, \\ for backslash) or bytes with values larger than 0x80 (e.g. octal \302\265 for "micro" in UTF-8). If this variable is set to false, bytes higher than 0x80 are not considered "unusual" any more. Double-quotes, backslash and control characters are always escaped regardless of the setting of this variable. A simple space character is not considered "unusual". Many commands can output pathnames completely verbatim using the -z option. The default value is true.

라고 나와있다.

 

간단하게 앞 부분을 해석하자면, 이 명령어는 경로를 출력하는데, 경로 이름에 있는 특이한 문자들을, 경로 이름을 큰따옴표("")로 감싸고, 그 특이한 문자들을 C 언어가 특수 문자들 또는 0x80보다 큰 값을 가진 바이트들을 처리하는 방식과 같이 역슬래시로 탈출시킴으로써 나타낸다고 한다.

아까 한글이 깨졌던 모습이 이 해석과 동일하게 맞아 떨어지는 것을 볼 수 있다.

다시 한번 한글이 깨진 부분을 살펴보자.

두 번째 "새 파일 :" 이 부분을 보면, 경로가 큰따옴표로 감싸져 있고, 그 파일 이름(즉, 게임판 덮기)은 백슬래시와 그 값들을 8진법으로 표현한 값들의 조합으로 표현되어 있는 것을 볼 수 있었다!(오.. 역시 공식 문서..)

 

사실 아까 공식 문서에서 나온 "0x80보다 큰 값을 가진 바이트들을" 이라는 말이 잘 이해가 되지 않았다. 

0x80은 뭐지?? 궁금했다.

 

좀 더 구글링을 해보기로 했다. 

 

"(e.g. octal \302\265 for "micro" in UTF-8)" 공식 문서에서 예를 들어주었는데, 마이크로 문자는 UTF-8 인코딩 방식에서 8진법으로 \302\265를 나타낸다 라고 한다. 지금와서 보니 꽤나 친절한 설명이나, 처음 봤을 땐 무슨 소린지 몰랐다.

 

일단 UTF-8에 대해 몰라서, 찾아 보았다.

UTF-8는 유니코드에 포함되는 문자들을 표현하기 위해 1부터 4바이트를 사용하는 가변 길이 인코딩 방식이다. 

 

여기서 아까 살짝 말한 "0x80보다 큰 값을 가진 바이트들" 이라는 표현이 감이 잡히기 시작했다. 

"아~ 세계 어떤 문자든 UTF-8 인코딩 방식으로 1부터 4까지의 바이트들을 사용해 표현될 수 있구나." 정도로 이해했다.

 

구글링을 해보다가 찾은 건데, 한글은 3바이트를 사용해 표현된다고 한다.

 

실제로 그런지 확인하기 위해서

https://www.utf8-chartable.de/

 

Unicode/UTF-8-character table

 

www.utf8-chartable.de

 

유니코드와 UTF-8 인코딩 테이블을 직접 확인해보았다. ㅋㅌㅋ(투머치인가... 이해 못 하고는 잠을 못 잘 것 같아서 더 찾아보았다..)

 

자음 ㄱ 에 대한 유니코드 포인트와 UTF-8 (hex.)

간단하게 자음 'ㄱ'을 보자.

실제로 UTF-8 인코딩 방식으로 3 바이트로 표현된 것을 볼 수 있었다! (e1 84 80이 각각 한 바이트를 16진법으로 표현하고 있는 것이다!!)

 

그렇다면 아까 파일명이었던 "게임판 덮기"는 각 문자인 "게", "임", "판", "덮", "기" 에 해당하는 3바이트가 8진수로 표현된 것이 아까 그 백슬래시와 숫자들로 표현된 것이라 이해할 수 있다!

각 문자가 3바이트를 사용해 표현되기 때문에 한 문자는 세 개의 백슬래시와 세 개의 수들로 이루어져있다. 

실제로 보면 게임판 덮기가 15개의 "\수" 로 되어 있다! (오,, 이제서야 이해했다)

 

그럼 다시 돌아가서, 0x80은 뭘까?

UTF-8에서 아스키코드에 있는 문자들은 모두 1바이트를 이용해 표현되는데, 0x80이 처음으로 2바이트를 사용해 표현되는 것으로 넘어가는 경계에 있는 문자이다. (10진법으로 표현하면 숫자 128이 이에 대응한다!)아래 그림을 확인해보자.

0x80

유니코드 포인트 U+0080부터 UTF-8은 2바이트를 사용해 표현하는 것을 볼 수 있다!(0x7f 까지가 아스키코드 문자들이다!)

 

추가적으로 0x80은 2진법으로 1000 0000 이다. 아스키 코드의 문자들은 모두 0으로 시작한다. 

아스키코드에 있는 문자가 아닌 것을 예외 처리할 때, 이러한 특징을 이용해 비트 연산을 사용하면 된다고 한다! 아직은 사용한 적이 없지만,나중에 꼭 필요한 순간이 있을 것 같다.

 

이렇게 내 모든 궁금증은 풀렸다.

git 한글 깨짐 현상을 해결한다는게,,, 유니코드와 UTF-8을 살짝 맛보는 것까지 이어졌다.

 

컴퓨터공학에 접하면서 개발 공부를 하게 되었는데,

개발 공부가 참 매력적인게 이렇게 하나를 이해하기 위해서 여러 가지 다른 개념을 구글링해서 찾다보면 

원래 이해하려 했던 그 하나가 더 뻥뚫리는 듯한 느낌을 받는다. 이 분야에 한정되는 것은 아니겠지만 말이다.

 

 

 

이 글을 작성하면서 참고한 블로그 리스트(정말 감사드려요!!):

https://umbum.dev/328

https://skmagic.tistory.com/86

https://jyami.tistory.com/89?category=858859