SSD를 쓰기 시작하면서 디스크 공간이 굉장히 소중해졌다. 그래서 잘 안 쓰는 파일들은 zip으로 압축해서 저장하곤 하지만 뭔가 파일 하나가 보고 싶을 때는 꺼내기가 좀 불편하다.
대안은 Git bare 저장소로 보관하는 것이다. 이 방법은 공간도 적게 사용하면서 필요할 때 gut 명령으로 간단히 파일을 꺼내 볼 수도 있다.
뿐만 아니라 Git 저장소는 굉장히 공간효율적이다. 때때로 gzip으로 압축했을 때 보다도 디스크 공간을 적게 사용하는 경우도 있어 나를 놀라게 한다.
Git 저장소로 파일을 보관하고 읽고 쓰는 법에 대해 간단히 알아보자.
Git 저장소에 넣기
평소에 문서파일을 저장하던 text라는 디렉토리를 Git 저장소로 바꾸고 싶어졌다면 다음과 같이 하면 된다.
cd text
git init
git add *
git commit -m 'put them all'
mv .git ../text.git
cd ..
rm -rf text
cd text.git
git config core.bare true
Git 저장소의 파일 다루기
위에서 git 명령으로 간단히 파일을 꺼내 볼 수 있다고 말하긴 했지만, 사실 bare 저장소에 들어있는 파일을 직접 다루는 것은 흔치 않은 일이다. 그래서 익숙해지기 어렵다. 그러므로 Git bare 저장소에서 동작하는 cp나 cat과 같은 coreutils를 간단히 만들어서 쓰는 것이 편하다.
git-cat
우선 git-cat
을 만들어보자. 아주 간단하다.
#!/bin/sh git show HEAD:$1
이 파일을 실행 가능하게 설정하고, path가 잡혀있는 디렉토리에 넣어두면 그 다음부터는 git cat <filename>
으로 git 저장소에 들어있는 파일 내용을 볼 수 있게 된다. 예를 들면 다음과 같다.
$ cd text.git
~/text.git$ git cat hello.txt
Hello, World
git-ls
git-cat
은 GNU coreutils의 cat과는 달리 디렉토리의 내용도 볼 수 있다. 하지만 좀 더 ls에 가깝게 출력하는 기능이 필요하다면 다음과 같은 스크립트를 만들면 된다.
#!/bin/sh git ls-tree --name-only HEAD
알려진 이슈: 한글 파일명을 제대로 보여주지 못한다는 문제가 있다. “\355\225\234\352\270\200” 와 같이 코드로 보여준다.
git-cp
마지막으로 저장소 밖의 파일을 저장소 안으로 넣을 수 있는 git-cp
다. 이건 파이썬으로 작성했다. 전체 소스코드는 여기에 있는데, 상당히 긴 관계로 가장 중요한 세 군데만 설명하겠다.
우선 git hash-object
로 blob을 만든다. (do()는 쉘명령 실행하는 함수) blob은 파일 하나에 해당한다.
blob_id = do(git_cmd + ['hash-object', '-t', 'blob', '-w', '--', src], None, options).strip()
그리고 git mktreee
로 위에서 만든 blob이 담긴 tree를 만든다. tree는 디렉토리에 해당한다.
tree_id = do(git_cmd + ['mktree', '-z'], None, options, ''.join(files)).strip()
마지막으로 git commit-tree
로 커밋을 하면 된다.
commit_id = do(git_cmd + ['commit-tree', tree_id] + parent_param + ['-m', message], None, options).strip()
사용법은 다음과 같다.
$ git cp hello.txt text.git
알려진 이슈: 커밋을 한번도 안한 빈 코드저장소에 파일을 복사하려 시도하면 오동작한다.
전체 소스코드
git-coreutils에 전체 코드를 올려 놓았다.