The future of large files in Git is Git

Tyler Cipriani

Git에서 대용량 파일의 미래는 Git이다

Git에 숙적이 있다면, 그건 바로 대용량 파일이에요.

대용량 파일은 Git 저장소를 비대하게 만들고, git clone을 느리게 하며, Git 포지를 골치 아프게 만들어요.

2015년 GitHub는 대용량 파일 문제를 임시로 우회하는 Git 확장 기능인 Git LFS를 출시했어요. 하지만 Git LFS는 새로운 복잡성과 저장 비용을 덤으로 가져왔죠.

그동안 Git 프로젝트는 조용히 대용량 파일 문제를 개선해 왔어요. LFS가 아직 완전히 사라진 건 아니지만, 최신 Git 릴리스는 LFS가 마침내 쓸모없어지는 미래로 가는 길을 보여줘요.

오늘 당장 할 수 있는 일: Git LFS를 Git partial clone으로 대체하기

Git LFS는 대용량 파일을 저장소 바깥에 저장하는 방식으로 동작해요.

LFS로 프로젝트를 clone하면 저장소의 히스토리와 작은 파일들은 가져오지만 대용량 파일은 건너뛰어요. 대신 Git LFS는 작업 사본에 실제로 필요한 대용량 파일만 다운로드하죠.

2017년 Git 프로젝트는 Git LFS와 동일한 이점을 제공하는 partial clone을 선보였어요:

partial clone을 사용하면 clone과 fetch 과정에서 [대용량 바이너리 에셋]을 미리 다운로드하지 않아도 되므로 다운로드 시간과 디스크 사용량을 줄일 수 있어요.

– Partial Clone 설계 노트, git-scm.com

Git partial clone과 LFS는 모두 다음과 같은 장점을 제공해요:

  1. 가벼운 체크아웃 – clone할 때 대용량 파일의 모든 버전을 받는 대신 최신 사본만 받아요.
  2. 빠른 clone – 대용량 파일을 다운로드하지 않으니 clone 자체가 빨라요.
  3. 빠른 시작 – shallow clone과 달리 프로젝트의 전체 히스토리를 그대로 받으니 바로 작업을 시작할 수 있어요.

partial clone이란?

Git partial clone은 --filter를 붙인 clone이에요.

예를 들어 100KB보다 큰 파일의 다운로드를 피하려면 이렇게 실행하면 돼요:

git clone --filter='blobs:size=100k' <repo>

이후 체크아웃에 필요한 100KB 이상의 파일은 Git이 필요할 때 지연(lazy) 다운로드해요.

기본 설정대로 성가신 25MB짜리 PNG 파일이 여러 버전 들어 있는 저장소를 git clone하면 clone은 느리고 체크아웃 용량도 터무니없이 커져요:

$ time git clone https://github.com/thcipriani/noise-over-git
Cloning into '/tmp/noise-over-git'...
...
Receiving objects: 100% (153/153), 1.19 GiB

real    3m49.052s

25MB짜리 파일 하나 체크아웃하는 데 거의 4분이 걸려요!

$ du --max-depth=0 --human-readable noise-over-git/.
1.3G    noise-over-git/.
$ ^ 🤬

그리고 그 25MB짜리 파일 하나에 50개 버전이 쌓이니 1.3GB를 차지해요.

하지만 partial clone을 쓰면 이런 문제를 피할 수 있어요:

$ git config --global alias.pclone 'clone --filter=blob:limit=100k'
$ time git pclone https://github.com/thcipriani/noise-over-git
Cloning into '/tmp/noise-over-git'...
...
Receiving objects: 100% (1/1), 24.03 MiB

real    0m6.132s
$ du --max-depth=0 --human-readable noise-over-git/.
49M     noise-over-git/
$ ^ 😻 (the same size as a git lfs checkout)

필터를 적용하니 clone 속도가 97% 빨라졌고(3분 49초 → 6초), 체크아웃 용량도 96% 줄었어요(1.3GB → 49M)!

물론 아직 몇 가지 주의할 점이 있어요.

필터로 제외한 데이터가 필요한 명령을 실행하면 Git이 서버에 다녀와야 해요. 그래서 git diff, git blame, git checkout 같은 명령은 Git 호스트에 접속해야 실행할 수 있어요.

하지만 대용량 파일의 경우 이는 Git LFS와 동일한 동작이에요.

게다가 PNG 파일에 git blame을 실행해 본 게 언제였는지 기억도 안 나요 🙃.

굳이 번거롭게 바꿀 필요가 있을까요? Git LFS의 문제는 뭘까요?

Git LFS는 Git이 가진 대용량 파일 문제를 사용자에게 떠넘겨요.

그리고 그 문제는 결코 가볍지 않아요:

  • 🖕 심한 종속성 – GitHub가 Git LFS를 만들 당시 Git Fat, Git Annex, Git Media 같은 다른 대용량 파일 시스템들은 서버 구현에 구애받지 않았어요. 하지만 GitHub는 사용자를 자사 독점 서버 구현에 묶어 두고 사용료를 부과했죠.1
  • 💸 비용 부담 – GitHub는 저장소를 무료로 호스팅하게 해줘서 성공했어요. 하지만 Git LFS는 처음부터 유료 제품으로 시작했죠. 지금은 무료 혜택이 있지만 가격 결정은 전적으로 GitHub 마음에 달려 있어요. 현재 GitHub에서 50GB 저장소를 유지하려면 연간 40달러가 들어요. 반면 Amazon S3 스탠다드 스토리지에 50GB를 보관하는 데는 연간 13달러면 충분하죠.
  • 😰 되돌리기 어려움 – 일단 Git LFS로 옮기면 히스토리를 다시 쓰지 않고는 되돌릴 수 없어요.
  • 🌀 지속적인 설정 비용 – 모든 협업자가 Git LFS를 설치해야 해요. Git LFS가 설치되어 있지 않으면 협업자는 기대한 대용량 파일 대신 헷갈리는 메타데이터 투성이의 텍스트 파일을 받게 되죠.

미래: Git large object promisor

대용량 파일은 Git 포지에게도 골칫거리예요.

GitHub와 GitLab은 파일 크기에 제한을 두고 있어요2. 큰 파일을 호스팅하는 데 비용이 더 많이 들기 때문이죠. Git LFS는 대용량 파일을 CDN으로 넘겨 서버 측 비용을 낮게 유지해요.

하지만 Git 프로젝트에는 새로운 해법이 있어요.

올해 초 Git은 새로운 기능인 large object promisor를 병합했어요. large object promisor는 사용자의 번거로움은 빼고 LFS와 동일한 서버 측 이점을 제공하는 것을 목표로 해요.

이 작업은 특히 서버 측을 개선하고, 특히 이미 바이너리 형태로 압축된 대형 blob을 개선하는 것을 목표로 합니다.

이 작업은 Git LFS에 대한 대안을 제공하는 것을 목표로 합니다

– Large Object Promisors, git-scm.com

large object promisor란?

large object promisor는 대용량 파일만 보관하는 특수한 Git 리모트예요.

반짝이는 밝은 미래에는 large object promisor가 이렇게 동작할 거예요:

  1. 대용량 파일을 Git 호스트에 push해요.
  2. 백그라운드에서 Git 호스트가 그 대용량 파일을 large object promisor로 옮겨요.
  3. clone할 때 Git 호스트가 Git 클라이언트에게 promisor에 대해 알려줘요.
  4. 클라이언트는 Git 호스트에서 clone하면서 대용량 파일은 promisor 리모트에서 자동으로 가져와요.

하지만 그 반짝이는 밝은 미래까지는 아직 갈 길이 멀어요.

Git large object promisor는 아직 진행 중이에요. 일부 기능이 2025년 3월에 Git에 병합됐지만, 아직 할 일이 남아 있고 풀어야 할 열린 질문들도 있어요.

그래서 오늘 시점에서는 거대한 파일에 대해 여전히 Git LFS에 의존해야 해요. 하지만 large object promisor가 널리 보급되면 어쩌면 GitHub에서도 100MB보다 큰 파일을 push할 수 있게 될지도 몰라요.

Git에서 대용량 파일의 미래는 Git이다.

Git 프로젝트가 대용량 파일에 대해 깊이 고민하고 있으니 여러분은 고민하지 않아도 돼요.

오늘날 우리는 아직 Git LFS에 발이 묶여 있어요.

하지만 곧 Git에서 대용량 파일을 다루는 데 유일한 장애물은 MP3 라이브러리를 Git에 넣어 두는 건 좋지 않다는 어렴풋하고 불길한 직감뿐일 거예요.


편집: Refactoring English


  1. 나중에 다른 Git 포지들도 자체 LFS 서버를 만들었어요. 오늘날에는 여러 Git 포지에 push하거나 LFS 전송 에이전트를 사용할 수 있지만, 이 모든 것이 기여자의 설정을 더 어렵게 만들죠. 사실상 추가로 노력을 기울이지 않는 한 종속된 상태에 머물게 돼요.↩︎

  2. 파일 크기 제한: GitHub는 100MB, GitLab.com은 100MB↩︎

원문은 Tyler Cipriani님이 에 게재했습니다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.