Ethan Hur's blog

git 과 Asset

2018-02-01

서론

회사에서 운영하는 EC2 서버에 GitLab을 깔아서 쓰고 있었다.

그런데 오늘, GitLab에 갑자기 push 가 안되길래 살펴보다가 disk space 를 100% 차지하고 있던 것을 발견했다.

최근 git 으로 그냥 돌리던 레포들을 GitLab으로 이전했고, 새로운 프로젝트를 하기 위해 레포를 새로 파서 급격한 용량 증가가 있었다.

이 이슈를 해결하면서 여러가지 것들을 생각해 보았고, 생각해본 내용을 공유하고자 한다.

git internal

git 은 기본적으로 snapshot 을 압축하여 저장한다.

코드의 경우 plain text 이므로 많은 양이 쌓여도 그리 문제가 되지 않는다.

하지만, 이미지 등의 리소스를 생각해보자. 내가 이미지를 어떤 레포에서 A -> B -> C 로 바꾸었다면, git 내부에서는 A, B, C 모두 저장하고 있다. (압축된 상태이긴 하지만)

git 의 압축 알고리즘은 훌륭하지만, 그래도 이미지의 변경 사항을 전부 기록하는 것은 부담스러울 수 밖에 없다.

clone 을 받았을 때 10년치의 기록을 다 받을 필요는 없지 않은가?

오래된 프로젝트

만약 10년짜리 프로젝트라고 생각해보자. 10년동안 프로젝트의 UI는 트렌트에 따라 엄청 변화했을 것이다.

하나의 레포에서 관리를 한다고 하면, 그 레포는 10년 동안의 데이터를 (압축된 상태로) 전부 가지고 있는 것이다.

100기가 넘어가는 것도 그리 어려운 일이 아닐 것이다. AAA 게임 타이틀을 생각해보면 패키징해서 나온 결과물만 2~30기가이다.

그렇다고 버전 관리를 포기할 수는 없다. 그럼 우리는 어떻게 해야 할까?

사실 가장 좋은 해결책

https://www.perforce.com/

사실 가장 좋은 해결책은 위와 같은 솔루션을 도입하는 것이다.

더 따질 것이 없다. Ubisoft, Nvidia 등이 실제로 잘 사용하고 있고 내가 해야 하는 위와 같은 고민들을 해결하여 제품화한 것이다.

하지만 문제는 돈이다. 개발팀 20명짜리 프로젝트에 저런 솔루션을 도입할 수는 없다.

다른 해결책들

로컬에서는 shallow copy 를 통해 전체 히스토리가 아닌 일부만 가지고 올 수 있다.

1
git clone [url] --depth 10

이렇게 하면 거의 관심이 있는 최근 데이터만 depth 옵션을 줘서 가지고 올 수 있다.

하지만 서버의 경우는 좀 복잡하다. 서버에서는 모든 히스토리를 가지고 있어야 하는 게 당연하다. 따라서 위에서 설명한 모든 스냅샷을 가지고 있어야 하는 게 맞다.

아주 특별한 경우, commit 된 snapshot 들이 더 이상 필요없다고 판단한 경우에는 commit history 를 모두 날리고 현재 snapshot 만 저장할 수 있다.

1
2
3
4
5
6
7
8
rm -rf .git
git init
git add .
git commit -m "Initial commit"
git remote add origin <URL>
git push -u --force origin master

히스토리를 날리는 것은 절대 권장하지 않지만, 정말 필요할 때는 고려해볼 수 있겠다. 물론 모든 사람이 rebase 또는 다시 clone 을 해야 한다.

그래서 나는 어떻게 해결했나?

다시 돌아가서, GitLab 은 그냥 EBS 볼륨을 늘렸다. storage 200GB 늘리는 것이 부담이 된다면 흠….

여기 가이드가 자세하게 나와 있다.

뭔갈 하기 전에 스냅샷 찍는 건 잊지 말자.

결론

  1. git 이 버전 관리의 만능은 아니다. (특히 Binary Asset 관리할 때)

  2. 하지만 git이 소규모 프로젝트에서 가장 잘 쓸 수 있는 툴은 맞는 것 같다.

  3. 돈 많으면 다 해결된다. 필요하면 외부 솔루션 가져다가 쓰자.