위와 같이 설정하니까 되더라. 대상에 바로 ckw를 적어주지 않고 cmd를 먼저 실행하는 것은... ckw를 바로 실행하게 했더니 자그마한 cmd창이 같이 뜨고 타이핑하는게 양쪽 창에 다 찍히는 희한한 상황이 되어서였음.
ckw를 실행할 때 명령행 인자로 -bg, -fg 등으로 색상을 바꿔주거나 할 수 있다1. 일반적인 명령 프롬프트 창 대용으로 띄울 때와 구분되게 하니까 좋았음.
문제는 탐색기에서 마우스 우클릭했을 때 뜨는 컨텍스트 메뉴인데, 이건 git-cheetah 라는 게 git설치할 때 같이 깔려서 그 부분을 담당하는데, 메일로 문의하니 재컴파일하지 않는 이상 고칠 수 없다고 함. 대신 msysgit설치할 때 git-cheetah 대신 registry 기반 컨텍스트 메뉴를 사용하게 설치할 경우, (HKLM 또는 HKCU)\SOFTWARE\Classes\Directory\shell\git_shell\command에서 수정할 수 있다고 함
위의 내용은 윈도XP에서 주인장이 설정한 것이고, 윈도7은 좀 다른 듯 하다. 아래 Comments 참고.
commit할 때 사용하는 에디터를 gvim으로 바꾸고 싶으면 GIT_EDITOR 환경 변수를 정해주면 됨. 다만 bash를 거치기 때문에 경로를 다음과 같이.
export GIT_EDITOR=/d/Local/Vim/vim72/gvim.exe
VimEditor 7.2부터는 git 설정파일 등의 신택스 하일라이팅이 지원되는데, 그 이전 버전은 다음과 같이 하면 된다8
Syntax highlighting for git commit messages, config files, etc. is
included with the vim distribution as of vim 7.2, and should work
automatically.
If you have an older version of vim, you can get the latest syntax
files from the vim project:
http://ftp.vim.org/pub/vim/runtime/syntax/git.vim
http://ftp.vim.org/pub/vim/runtime/syntax/gitcommit.vim
http://ftp.vim.org/pub/vim/runtime/syntax/gitconfig.vim
http://ftp.vim.org/pub/vim/runtime/syntax/gitrebase.vim
http://ftp.vim.org/pub/vim/runtime/syntax/gitsendemail.vim
These files are also available via FTP at the same location.
To install:
1. Copy these files to vim's syntax directory $HOME/.vim/syntax
2. To auto-detect the editing of various git-related filetypes:
$ cat >>$HOME/.vim/filetype.vim <<'EOF'
autocmd BufNewFile,BufRead *.git/COMMIT_EDITMSG setf gitcommit
autocmd BufNewFile,BufRead *.git/config,.gitconfig setf gitconfig
autocmd BufNewFile,BufRead git-rebase-todo setf gitrebase
autocmd BufNewFile,BufRead .msg.[0-9]*
\ if getline(1) =~ '^From.*# This line is ignored.$' |
\ setf gitsendemail |
\ endif
autocmd BufNewFile,BufRead *.git/**
\ if getline(1) =~ '^\x\{40\}\>\|^ref: ' |
\ setf git |
\ endif
EOF
Warning: commit message does not conform to UTF-8.
You may want to amend it after fixing the message, or set the config
variable i18n.commitencoding to the encoding your project uses.
(**) 이 경우는, 메시지 인코딩이 cp949라고 해 놓고는 실제로 UTF-8인코딩된 메시지를 넘겨주었으니, 잘 되는 게 이상한 듯?
결론적으로
github를 생각하면 무조건 UTF-8인코딩을 써야 하고
명령 프롬프트 창에서 git log 등을 할 때 깨지지 않으려면 i18n.logoutputencoding=cp949 만 적용
여담으로,
프로젝트 내용물 중에 README 파일이 있으면 github에서 그 내용을 첫 화면에 같이 보여주는데, 이 파일은 UTF-8로 인코딩하거나 cp949로 인코딩하거나 상관없이 화면에 잘 나왔다. 이거 참 신기하다. cp949는 euc-jp 등과 겹칠 우려가 있지 않은가?
README 파일의 인코딩을 바꾸어가며 커밋하고 github에서 각 커밋을 클릭해서 diff를 보면, 인코딩이 바뀔 때의 diff는 깨져서 나오지만, 같은 인코딩끼리라면 한글 문자열의 diff도 잘 보여 주었음
위에 있는 "Pro git" 번역판 7장에 "다른 Merge, Diff 도구 사용하기" 섹션이 있는데, 윈도우에서 하려니 잘 안 되는 부분이 있어서, 이래저래 구글링도 하고 직접 테스트 하면서 알아낸 것 정리.
일단 책에 소개된 P4Merge[9]와, VimEditor를 쓰는 걸 생각해 보자.
P4Merge 설치는 다운로드 페이지[10]에서, by component - Clients - Visual Merge Tool 로 선택한 후 윈도우용을 받고, 설치할 때 Merge Tool만 설치하면 됨
vimdiff 는 Git에서 기본으로 지원하는 값이고, msysgit에는 vim도 같이 들어있다. 따라서 merge.tool = vimdiff 이것만으로도 충분하다. 그러나 vim이 뜨면 명령 프롬프트 창에서 작업을 해야 하는데 좀 불편하니, 원래 PC에 설치되어 있던 gvim을 띄우기 위해서 path로 gvim.exe를 지정해준다.
"Pro Git" 책에는 mergetool.p4merge.cmd 옵션을 설정해서 호출할 때 인자를 넘겨주는 방법을 지정해야 한다고 나왔으나, stack overflow 등에서 답변들을 보니 최신 버전의 git은 p4merge를 자체적으로 지원하므로 필요없어짐
그러나 p4merge.exe가 PATH에 잡혀 있더라도 그냥은 실행이 안 되고, path를 지정해주어야 하더라. 지정해 줄 때도 저렇게 윈도우용 경로명을 직접 적어주면 자꾸 슬래쉬가 이스케이프되어 버려서 잘 안 된다. msysgit의 Git bash에서 다음과 같이 지정해주는 게 낫다
소스 코드 파일들이 UTF-8로 인코딩되어 있다면... 이러면 좀 더 복잡해진다. p4merge는 실행 후 메뉴에서 인코딩을 바꿀 수 있다. 따라서 위처럼 설정하고 p4merge를 실행할 때마다 직접 바꿔줘도 되겠지만 귀찮다.
또 p4merge는 명령행 옵션을 써서 인코딩을 옵션으로 줄 수도 있다! 그런데, 문제는 Git가 p4merge를 불러오는 과정에서 그 옵션을 삽입하게 할 방법이 없다10
별 수 없이, wrapper 스크립트를 만든다.
diff는 merge하고 상황이 다른데, merge야 충돌 나면 그때가서 충돌난 파일을 에디터로 열어서 손으로 찾아가며 해도 되지만, diff는 git diff를 할 때마다 터미널 창에 뜨는데 UTF-8은 다 깨져나와서, 별 수 없이 리다이렉션으로 일단 저장하고 열어보는 수고를 해야 한다. 아니면 파이프로 iconv에게 넘겨줘도 되는데 이러면 색상 구분이 다 없어져 버린다.
일단 vimdiff로 diff를 보는 것부터 얘기하자.
diff도 두가지가 있다.
git difftool[13] - 이건 merge와 유사하게 diff.tool 옵션으로 제어하고, 만일 이 옵션의 값이 없으면 merge.tool 값을 사용한다. tool옵션의 값이 Git가 지원하는 프리셋 중 하나라면 거기에 맞춰 인자가 넘어가고, 그 외의 경우는 difftool.툴이름.cmd에서 지정해 주어야 한다.
git difftool에서만 vim을 쓰고 싶다면 툴만 지정해주면 된다. gvim을 원한다면 merge할 때와 같이 path도 지정.
[diff]tool = vimdiff
git diff에서도 vim을 쓰고 싶다면 좀 복잡하다. 여기에는 vimdiff 프리셋 같은 게 없어서 일일이 명령어와 인자를 명시해줘야 한다.
여기서도 wrapper 스크립트를 만들어주자. Git bash 상에서 /bin/extDiff 스크립트를 만든 후, 다음과 같이 적는다:
이게 아주 해괴망칙한 부분인데...
두 커밋 또는 커밋과 작업 디렉토리 등을 비교할 때, 파일이 양쪽에 다 존재하면 괜찮은데, 중간에 파일을 새로 생성했다거나 삭제를 했다면 어느 한쪽에는 파일이 없다. 문제는 그 없는 파일이 diff를 할 때 /dev/null이라는 경로명으로 diff 프로그램에 넘어간다는 거다. Git의 기본 diff는 이걸 잘 처리해주고 (빈 파일처럼 다루어 비교함), vimdiff도 마찬가지인데, p4merge 는 인자로 이 이름을 받으면 잘못된 파일이라고 에러를 낸다.
(이 문제에 대해서는 stackoverflow를 비롯해서 구글링을 여러 차례 해도 나오는 게 없더라. 윈도 msysgit에서 p4merge를 사용하는 법을 묻는 질문은 종종 있던데, 다들 이 문제는 포기하고 살았던 걸까, 아니면 나만 겪고 있나?)
어차피 인코딩 옵션 때문에 wrapper 스크립트를 쓰긴 해야 하는데, 이 문제 때문에 인자를 미리 검사해서 p4merge를 속이는 일도 해줘야 한다. diff와 difftool 양쪽에서 다 p4merge를 쓰는 경우를 가정하자.
wrapper 스크립트는 다음과 같이 작성한다.
#!/bin/sh# %TEMP% 디렉토리에 저장될 임시파일명. PC내에서 절대 겹치지 않을 것 같은 이름을 지어준다BLANKFILE="${TEMP}/_blank_"if[$#-eq7]then# 'git diff'LOCAL=$2REMOTE=$5elseecho"I got $# arguments. ERROR!"exit1fiif["$LOCAL"=='/dev/null']then
touch $BLANKFILELOCAL=$BLANKFILEfiif["$REMOTE"=='/dev/null']then
touch $BLANKFILEREMOTE=$BLANKFILEfi
/c/Program\ Files/Perforce/p4merge.exe -C utf8 "$LOCAL""$REMOTE"
rm -f$BLANKFILE
인자로 /dev/null을 받으면, %TEMP% 디렉토리에 빈 파일 하나를 만들고 그 파일 이름으로 인자를 바꿔치기하여 p4merge에 전달한다.
cmd의 값이 복잡한 건 빈 인자를 끼워넣어 인자를 7개 만드느라 그렇다. 여기가 지저분하면 그냥 $LOCAL과 $REMOTE 두 개만 넘겨주고, 스크립트 쪽에서 $1과 $2로 각각 받아도 되겠는데, 이건 git difftool에만 적용되고 git diff는 여전히 인자가 7개 넘어가니까, 스크립트 쪽에서 인자의 갯수를 비교해서 할당해줘야 해서 더 귀찮다.
[P4Merge를 사용한 diff 스크린샷] - 왼쪽 창은 비교 대상 중 한쪽에 파일이 없는 경우. 실제로는 저렇게 창들이 한꺼번에 뜨지 않고, 파일 하나마다 뜨고 닫으면 다음 창이 뜬다.
그러나 p4merge에서처럼, 만일 두 스냅샷을 비교하는데 파일이 어느 한쪽에서만 존재하면, 존재하지 않는 쪽이 "nul"이라는 파일명으로 넘어가는 바람에 에러창이 뜨고, 에러창을 닫으면 또 DiffMerge창도 무의미하게 한 번 더 닫아줘야 한다.
그래서 할 수 없이 wrapper를 만든다. 내 경우는 다른 건 다 p4merge에서와 똑같이 하고, extDiff 스크립트 내에서 프로그램 호출하는 부분만 바꿔 적었다.
git diff의 경우는 diff.external 옵션값을 extDiff로 바꿔주면 되겠으나, 그동안 좀 더 사용하다보니까 git diff는 터미널에서 그냥 하는 게 나을 때도 많고 해서 이건 건드리지 않았다. (위에 dogfeet님 블로그 글과 같은 이유)
끝으로, DiffMerge는 기본 텍스트 인코딩을 ISO-8859인가로 잡아놨기 때문에 한글이 포함된 문서를 볼 때 제대로 안 보인다.
Tool - Option - File Windows (여기서 글꼴 변경) - Rulesets 메뉴에 들어가서, Default Ruleset 또는 커스텀 룰셋 각각의 Edit 들어가보면 인코딩을 지정할 수 있다.
리눅스 서버에 git 저장소를 하나 만들고, 그걸 윈도우 머신에서 복사하려고 (github를 거치지 않고) 시도했는데 아래와 같이 에러가 났다.
$ git clone gypark@gypark.pe.kr:/home/gypark/temp/cvstest/testwiki.git
Cloning into 'testwiki'...
gypark@gypark.pe.kr's password:
bash: git-upload-pack: command not found
fatal: The remote end hung up unexpectedly
서버의 내 아이디 gypark에서 git-upload-pack을 실행시킬 수 없었던 건데, 이 시점에서는 .bashrc만 적용되고 .bash_profile에 있는 $PATH 설정은 적용이 안 되더라. .bashrc쪽에서 PATH를 지정해주어 해결
CVS로 관리하던 UseModWiki소스수정을 github로 옮겼는데, 그간 중앙 집중형 버전관리시스템의 대세가 확실히 Subversion으로 넘어갔던 건지, svn에서 이전하는 건 Git 자체에서도 지원하는 듯 한데, CVS에서 옮기는 얘기는 은근히 잘 찾을 수가 없더라. cvs-svn-git로 두 번 넘어가야 하나, 그간 수백번의 리비전이 있었는데 제대로 옮겨지려나 걱정을 많이 했다. 그런데 막상 해보니, Git를 만져본 후 이게 가장 쉬웠다고 할 정도로 무난히 성공했음.
기본적으로 브랜치나 태그를 다 복원하는데, 이렇게 했더니 내가 CVS에서 관리할 때 만들었던 태그나 브랜치들이 꽤 복잡하게 얽히더라. 어차피 크게 중요한 게 아니었던 터라, 그런 걸 다 제외하고 메인 트렁크만 복원하도록 하였다:
# ctx.trunk_only = False
ctx.trunk_only = True
CVS 커밋의 저자명, 로그메시지, 파일네임 들을 유니코드로 변환할 때 사용할 인코딩 목록. 내 경우 위키 소스를 ext1.* 버전에서는 euc-kr로 작성했고 CVS 커밋 메시지도 마찬가지였다. (간혹 에디터 설정 실수로 UTF-8로 작성한 메시지들이 섞여 있음) 그래서 utf-8, cp949, ascii 순으로 시도하도록 적어주었다:
ctx.cvs_author_decoder = CVSTextDecoder(
[
#'latin1',#'utf8',# gypark
'utf8',
'cp949',
'ascii',
],
#fallback_encoding='ascii'
)
ctx.cvs_log_decoder = CVSTextDecoder(
[
#'latin1',#'utf8',# gypark
'utf8',
'cp949',
'ascii',
],
#fallback_encoding='ascii'
)
# You might want to be especially strict when converting filenames to# Unicode (e.g., maybe not specify a fallback_encoding).
ctx.cvs_filename_decoder = CVSTextDecoder(
[
#'latin1',#'utf8',# gypark
'utf8',
'cp949',
'ascii',
],
#fallback_encoding='ascii'
)
CVS에서 커밋에 author정보가 없는 부분(브랜치를 생성하는 시점 등)에 사용할 아이디. 다른 커밋에서 사용하던 그 아이디를 적어주었음:
ctx.output_option = GitOutputOption(
# The file in which to write the git-fast-import stream that# contains the changesets and branch/tag information:# 'cvs2svn-tmp/git-dump.dat',
'/home/gypark/temp/cvstest/testwiki-dump.dat',
...
)
가장 핵심이 되는, 변환할 CVS 저장소의 경로명
run_options.set_project(
# The filesystem path to the part of the CVS repository (*not* a# CVS working copy) that should be converted. This may be a# subdirectory (i.e., a module) within a larger CVS repository.# r'test-data/main-cvsrepos',
r'/home/gypark/CVS/testwiki',
...
)
이제 실행해서 덤프 파일을 생성한다.
$ cvs2git --options=옵션파일이름
저장소에 있는 *,v 파일들을 주욱 읽은 후에, 이러쿵 저러쿵 하는 메시지들을 쏟아내고 끝난다.
종료된 후에 확인해보면 위에 설정 파일에서 언급했던 두 개의 .dat 파일이 생성된 것을 알 수 있다.
좌측은 cvs log wiki.pl로 wiki.pl 파일의 커밋 로그를 출력했고, 우측은 git log로 전체 로그를 출력해보았음. git의 log는 전체 스냅샷을 대상으로 하기 때문에, 다른 파일에 해당되는 로그들이 같이 섞여 있다. 물론 git log wiki.pl하여 비교할 수도 있고, 정확히 일치함
막상 ls해 보면 파일이 하나도 없다! 당황하지 말고 git checkout master해서 체크아웃 한 번 해 준다.
여기까지가 정말 일사천리로 끝났다. 위에서 변환한 건 euc-kr을 사용하던 ext1.* 버전의 저장소인데, 총 커밋 횟수가 480회 정도 되고, 중간에 커밋 메시지가 에디터 설정 실수로 UTF-8로 끼어든 것들도 여럿 있고 그랬다. 그런데 전혀 에러나 오류 없이 깔끔히 변환되었다. 도저히 한번에 성공할 거라 생각하지 못해서, 일단 연습용 CVS저장소를 새로 만들고 커밋을 몇 번 한 후 변환을 시도하며 연습했었는데, 연습할 필요조차 없었지 싶다. 감탄했음.
그 다음은 UTF-8 기반으로 시작한 ext2.* 버전 저장소를 변환했다. 설정 파일에서 저장소 위치와 덤프 파일 이름만 바꿔주고는 한번에 성공.
이러고 나니까, 이왕 옮긴 김에, 두 Git 저장소를 하나로 통합하고 싶어졌다. ext1.* 버전에서 ext2.* 버전으로 죽 변경내역이 이어지도록 이어 붙이고 싶어진 것이다.
이건 어렵지 않게 구글링으로 성공했다. 위에 두 저장소를 잇기절에 있는 내용을 참고.
ext1.*버전의 저장소의 커밋이 a-b-c-d순으로 커밋되었고, ext2.*버전 저장소에 커밋이 h-i-j순으로 커밋되었다면, 첫번째 커밋인 h는 parent가 없는데, h의 parent가 d인 것처럼 속여 주는 것이다.
일단 통합 저장소를 하나 생성한다.
그 저장소에서 ext2.* 버전의 덤프 파일을 다시 fast-import 하여 복원한다.
복원한 후, 현재 저장되어 있는 가장 첫번째 커밋의 SHA값을 기록해 둔다.
[gypark@www UseModKr]$ git rev-list --reverse master | head -1
92de4e3fdcd017fa0692069d3dcb57e93ab5bcec
그 다음은 이보다 더 이전 커밋들, 즉 ext1.* 버전의 커밋과 커밋들이 가리키는 객체들을 이 저장소에 담아와야 하는데... 이걸 어떻게 해야 될지 몰라서, 그냥 ext1.* 버전의 덤프 파일을 가지고 다시 한 번 fast-import했다. (이 과정에서 뭔가 필요한 정보를 덮어써버렸거나, 반대로 불필요한 정보가 추가되어 버렸을 가능성이 있다는 얘기인데, 딱히 이래저래 나중에 비교해봤는데 그러진 않은 듯)
[gypark@www UseModKr]$ cat ../testwiki-blob.dat ../testwiki-dump.dat | git fast-import
warning: Not updating refs/heads/master (new tip 65919c894b1e19183c380d27093b5a08089186c1
does not contain 1fe3f81b4760efa38911f49905b0241eaaea3848)
위와 같이, 새로 임포트하는 커밋들이 현재 저장소에 있는 첫번째 커밋과 이어지지 않아서 경고가 나온다.
ext1.* 버전 저장소의 가장 마지막 커밋의 SHA값을 찾아 기록한다.
그쪽 저장소에 가서 찾아도 되지만, 위 경고 메시지에 나온 65919c894b1e19183c380d27093b5a08089186c1가 바로 그 값이다.
이제 두 커밋을 부모 자식 관계로 속인다. .git/info/grafts 파일에 자식 부모 순으로 적어준다.
[gypark@www UseModKr]$ git log --pretty=oneline
...
0be974ced4a7ab8212142666c321cbd66b170584 SlashLinks 옵션을 1로 켜고 관련 변수들을 절대 경로
92de4e3fdcd017fa0692069d3dcb57e93ab5bcec utf-8로 저장 <-- ext2.* 버전의 첫 커밋
65919c894b1e19183c380d27093b5a08089186c1 *** empty log message *** <-- ext1.* 버전의 마지막 커밋
8a90c0f4c323d44481184d97e42b3de5422ac4ed index 매크로 수정 - 인쇄할 때 인덱스 넘버를 출력하
...
성공!
grafts파일에 적어둔 현재 상태는 로컬저장소에서만 적용된다. 이걸 github 등에 Push를 하려면 실제로 커밋을 변경해주어야 한다11
앞 섹션의 파일명 문제도 그렇고, UTF-8로 인코딩된 문서를 윈도우 명령 프롬프트 창에서 diff 를 보거나 (또는 반대로 euc-kr 문서를 리눅스에서 보거나) 등등 할 때마다 글자가 깨지니까, 그냥 필터를 하나 만들어서 보기로 함(이 코드 자체는 뭐 git에서만 쓰는 게 아니라 범용이지만)
#!/usr/bin/env perl# git diff 의 출력을 받아서 인코딩을 변환하여 출력# 예: git diff --color | cat_encode.pluse strict;
use warnings;
use Encode;
use Encode::Guess;
my$pat_color = qr/(?:\e\[[;\d]*?m)/;
my@ansi = ();
my$output_encoding = 'cp949';
while ( my$line = <> ) {
chomp$line;
# ANSI 색상지정 코드를 일단 제거$line =~ s/($pat_color)/save_ansi($1)/eg;
my$enc = guess_encoding( $line, qw/cp949/ );
if ( notref($enc) ) {
print"!!! ", $line, "\n";
next;
}
my$str = encode($output_encoding, $enc->decode($line));
# ANSI 코드 복원$str =~ s/___ansicode\((\d+)\)___/$ansi[$1]/eg;
print$str, "\n";
}
subsave_ansi{
return''unless ( -t STDOUT);
my$ansi = shift;
push@ansi, $ansi;
return"___ansicode($#ansi)___";
}
그러면 git status | cat_encode.pl 등과 같이 쓸 수 있는데, 이번엔 뭐가 문제냐 하면 git 에서 출력을 할 때, 터미널로 출력을 안 하는 경우는 ANSI 컬러 코드를 출력하지 않아서 출력이 한 가지 색상으로만 나온다는 점이다(컬러 설정 값이 auto일 때). 이걸 또 손봐야 한다.
diff 의 경우는 옵션으로 --color=always를 주거나, 설정 파일에 color.diff = always로 지정 가능
status 는 실행할 때 옵션을 안 받아서, 설정 파일에 color.status = always
뭐 이런 식으로, 한글도 깨지지 않았으면 좋겠고 컬러도 적용되었으면 좋겠다 싶으면 설정을 바꿔주면 되는데... 또 문제가 있어서ㅋ 출력을 파일로 리다이렉션할 때도 컬러코드가 끼어 버린다 -ㅅ-; 어째서 --color 옵션을 받는 명령이 있고 안 받는 명령이 있는 거냐... (cat_encode.pl을 거치면 터미널로 나올때만 컬러코드가 나오도록 해놓긴 했음)
그리고 매번 파이프를 쓰기 귀찮으니 alias 설정을 할 수도 있겠다.
status 같은 경우는 항상 다른 인자 없이 git status 로만 쓰니까 alias.st = !git status | cat_encode.pl 이렇게 해 버리면 됨
diff 는 좀 다른게, git diff 뒤에 특정 파일 이름이나 커밋 이름 등 인자를 주는 경우가 있어서 위처럼은 곤란하고, 그냥 alias.df = diff --color로 해서 컬러를 강제로 켜는 정도로 타협
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: %$@%$@%@.txt <-- 깨진 글자
Untracked files:
(use "git add <file>..." to include in what will be committed)
한글이름.txt
no changes added to commit (use "git add" and/or "git commit -a")
이렇게 한글이름 파일들은 전부 stage와 untracked에 동시에 나온다. stage에서는 글자가 와장창 깨진 이름으로 나오면서 지워진 걸로 나온다. git이 기존에 저장한 파일명과 현재 파일명을 서로 다른 이름으로 해석하고 있는 눈치이다.
이 깨진 파일명을 어떻게 수작업으로 하려고 해도, 그 이름의 파일을 찾지 못하여서 not match 어쩌고 하면서 아무것도 안 된다. 그래서 그냥 지금까지의 이력을 날려버리고 저장소를 새로 시작해야 하는가 했는데, 찾아보니 이와 관련한 문서가 있음
git clean은 untracked 상태의 파일들을 지워버린다. 혹시 그게 지우면 안 될 파일일지 모르니 일단 저장소를 백업해놓고 하자.
구버전의 git.exe 만 있다고 동작하지는 않는다. 내 경우는 기존 PC에 설치된 git 디렉토리를 통채로 가져와서 사용했다.
이전 버전의 git이 없다면, 현재 버전의 git을 쓸 수도 있긴 하다. (비추)
git clean -f && git reset --hard
그런데 이렇게 하면 저장소의 상태가 어떻게 되냐 하면, 한글이름 파일들 각각마다 파일명이 깨진 글자로 된 파일들이 하나씩 짝을 이뤄 생겨난다. 이제 그런 것들을 일일이 찾아서 지워야 한다. 힘들더라.
내가 해보니 어쨌거나 저장소를 clean 상태로 두기만 하면 되는 거라서, untracked 파일이 현재 없다면 이 1번 과정을 거치지 않아도 되는 것 같다. 나는 그냥 .gitignore 파일에 넣어버렸는데 별 문제 없었다.
2. 기존에 저장된 인덱스를 삭제하고, 파일들을 전부 새로 추가한다.
git rm -rf --cached \* && git add --all
결국은 파일을 지우고 새로 add하고 있기 때문에... 특정한 파일에 대해 커밋 로그를 보려고 git log -- 파일명하면 한글 이름 파일의 경우는 과거 로그나 나오지 않게 된다. 이건 꽤 아쉽다. (어떤 파일은 나오고 어떤 파일은 안 나오는데 이런 차이가 나는 이유를 모르겠다)
3. git status를 해 보면 "깨진파일명 => 한글파일명" 상태로 이름이 바뀌어서 커밋 대기중인 상태로 나오는 거 확인한 후 커밋.
위 과정까지 거치고 나면, 그 다음은
중간중간에 다시 한글이 깨져서 어라 싶었던 경우가 있는데, git을 새로 설치하고 기존에 했던 각종 한글관련 설정을 하지 않은 상태에서 다시 재현하려고 하니 잘 되지 않는다. 아마 뭔가 기존 설정값이 문제였던 듯.
어쨌거나 1.7.9나 그 이전 버전을 쓸 때에 비하면 훨씬 터미널 환경에서 쓰기 편해진 느낌이다. 그런데 웬만하면 source tree 같은 걸 쓰는 게 나아보이기도. 나는 계속 리눅스나 맥의 커맨드 라인에서 쓰다보니 GUI가 낯설어서 그렇지만...
각주: 1. 매뉴얼[1] 참고 2. [2] 3. [3] 4. [4] 5. 6. [5] 7. [6] 8. git소스 디렉토리의 contrib/vim/README 9. [7] 10. C:\Program Files\Git\libexec\git-core\mergetools\p4merge 스크립트 참조 [github에서 보기]. path값에 옵션을 추가하더라도, 저 스크립트에서 따옴표로 둘러싸여 있으므로 통채로 실행하려고 해서 에러가 난다. 11. "Pro Git"을 읽어봐도 그렇고 github 등을 읽어봐도 그렇고, 일단 외부에 push해서 남이 가져간 커밋을 나중에 고치는 건 절대로 피해야 할 일이라고 하니 주의
msysgit 에잇하고 포기하고 있었는데 다시 도전해봐야 겠네요.
잘보겠습니다. 감사합니다.
이유는 모르겠지만 위에 설명하신대로는 실행이 안됩니다.
다음 처럼 실행하니 되는 군요.
"D:\local\ckw.exe" -e "C:\Program Files (x86)\Git\bin\sh.exe" -login -i
종종 참조하곤 합니다. 감사합니다^^