GitHub 큰 파일 올리기, Git LFS와 Releases는 언제 쓰나
협업자가 GitHub에서 ZIP을 내려받았더니 PSD 원본 자리에 작은 텍스트 파일만 들어 있다. 큰 작업 원본과 배포할 설치 파일은 각각 어디에 올려야 할까?

- 일반 Git의 100MiB 제한을 넘는 작업 원본은 LFS로 관리하고, 배포 파일은 Releases에 첨부한다.
- LFS는 새 버전 전체를 저장하며 다운로드 대역폭도 저장소 소유자의 사용량에 포함된다.
- 파일 삭제나 로컬 prune은 GitHub의 원격 LFS 객체를 자동 제거하지 않는다.
수정할 원본은 LFS, 배포할 완성 파일은 Releases
큰 디자인 원본이나 영상 자료를 코드와 함께 수정한다면 Git LFS가 맞다. 반면 이용자에게 내려받게 할 설치 파일이나 완성된 압축 파일은 GitHub Releases에 첨부하는 편이 목적에 맞는다. 파일 크기가 같아도 개발자가 과거 버전으로 돌아가야 하는 자료인지, 사용자가 특정 출시본을 받으면 되는 자료인지에 따라 저장할 곳이 달라진다.
GitHub의 일반 Git 파일 제한은 100MiB 초과 차단이며, 50MiB를 넘으면 경고가 나온다. 웹브라우저로 파일을 올리는 경로는 25MiB까지다. 이 세 숫자는 서로 다른 조건이다. 브라우저에서 막힌 파일을 터미널로 올릴 수 있는 경우는 있지만, 일반 Git의 단일 파일 제한까지 없어지는 것은 아니다.
| 자료의 용도 | 저장 방식 | 다음에 사용하는 방법 |
|---|---|---|
| 코드·설정·작은 문서다. | 일반 Git으로 추적한다. | 커밋별 파일과 변경 내용을 가져온다. |
| 작업 중 계속 수정하는 큰 원본이다. | LFS로 추적한다. | 커밋의 포인터가 가리키는 원본을 받는다. |
| 설치 프로그램·완성된 배포 묶음이다. | Releases에 첨부한다. | 사용자가 해당 릴리스의 첨부 파일을 받는다. |
| 다시 생성할 수 있는 캐시·빌드 중간 파일이다. | 추적할 필요가 없다면 ignore 규칙에 넣는다. | 필요한 환경에서 다시 생성한다. |
LFS는 Git에 실제 파일의 식별자와 크기를 담은 작은 포인터를 남기고 원본은 별도로 저장한다. 커밋에는 어떤 원본 버전을 사용할지가 기록된다. 디자인 파일을 열려면 그 커밋뿐 아니라 포인터가 가리키는 LFS 원본도 받아야 한다.
LFS에도 단일 파일 한도는 있다. GitHub Free·Pro는 2GB, Team은 4GB, Enterprise Cloud는 5GB다. 이 값은 한 파일의 상한이며 계정 전체의 무료 저장 공간과는 다르다. 파일 하나가 허용 크기 안에 들어가도 여러 버전이 쌓이면 계정 사용량은 늘어난다.
아직 커밋하지 않은 원본을 LFS로 등록하기
Git LFS 클라이언트는 Git과 별도로 설치한다. 운영체제에 맞는 설치 파일이나 패키지 관리자로 설치한 뒤 git lfs install을 실행한다. 이 명령은 LFS를 쓰도록 Git 설정을 준비하는 단계다. 파일 확장자를 정하는 일은 그다음 저장소 안에서 한다.
다음은 아직 Git에 커밋하지 않은 PSD 원본을 추가하는 예다. 작업할 저장소 폴더에서 실행하며 design/cover.psd는 실제 파일 경로로 바꾼다. 먼저 추적 규칙을 만들고, 규칙 파일과 원본을 함께 스테이징한다.
git lfs install
git lfs track "*.psd"
git add .gitattributes design/cover.psd
git lfs ls-files --size
git diff --cached --stat track 명령은 .gitattributes에 규칙을 쓴다. 따옴표는 셸이 현재 폴더의 파일 이름으로 별표를 먼저 펼치지 않도록 한다. 이 규칙을 저장소에 커밋해야 다른 개발자가 새로 받아도 같은 파일 유형을 LFS로 다룰 수 있다.
ls-files --size는 LFS 파일 경로와 크기를 확인하는 데 쓴다. 이어 스테이징된 변경 목록을 보고 이번에 올릴 원본과 규칙이 맞으면 커밋한다. 기존에 다른 작업을 스테이징했다면 그것도 같은 커밋에 들어갈 수 있으므로 목록을 읽는 단계가 필요하다.
git commit -m "Track design source with Git LFS"
git push 이 예의 git push는 원격 저장소와 현재 브랜치의 업스트림을 이미 설정한 프로젝트를 전제로 한다. 업로드 중 LFS 오류가 나오면 커밋 메시지만 보고 원본 전송이 끝났다고 판단하지 않는다. LFS 파일을 받는 협업자의 환경에도 클라이언트가 필요하다.
이미 커밋한 큰 파일에는 이력 처리가 필요하다
.gitignore는 이미 추적 중인 파일에 영향을 주지 않는다. 큰 파일을 커밋한 뒤 ignore에 추가하거나, 다음 커밋에서 삭제해도 앞선 커밋에는 그 파일이 남는다. GitHub가 미전송 이력 안의 큰 파일을 거절하는 상황이라면 현재 폴더에서 파일이 보이지 않는 것만으로 해결되지 않는다.
예를 들어 첫 커밋에 큰 원본을 넣고 두 번째 커밋에서 삭제했다면, 두 커밋을 함께 보내는 push에는 여전히 첫 원본이 포함된다. 계속 버전 관리할 원본이라면 해당 이력을 LFS 포인터로 바꾸는 방법을 선택한다. 보관할 필요가 없는 생성물이었다면 그 파일을 넣은 이력을 제거하는 쪽이 맞다.
git lfs migrate의 기본 대상은 현재 체크아웃한 브랜치 중 어느 원격에도 아직 없는 커밋이다. 아래 첫 명령은 파일 유형별 크기를 조사하고, 두 번째 명령은 그 범위의 PSD 파일을 LFS로 변환한다. 두 번째 줄은 이력을 바꾸므로 원본과 저장소 사본을 확보하고, 커밋하지 않은 작업을 커밋하거나 stash로 보관한 뒤 진행한다.
git lfs migrate info
git lfs migrate import --include="*.psd" 첫 결과를 검토하고 변환하기로 한 경우에만 두 번째 명령을 실행한다. 기본 동작에는 원격 참조를 최신으로 받는 과정이 있지만, 변환된 커밋을 원격에 자동으로 push하지는 않는다. 로컬 결과에서 원본 경로와 변경 이력을 확인한 다음 전송한다.
변환 뒤 PSD 파일을 열었는데 포인터 텍스트가 보인다면, 로컬에 보관된 원본을 작업 폴더에 꺼내는 git lfs checkout을 실행한다. 이 명령은 로컬에 해당 객체가 있을 때 빠진 파일이나 포인터를 원본으로 채우며, 수정한 파일을 덮어쓰지 않는다. 서버에서 원본을 내려받는 명령은 아니므로 로컬 객체까지 없는 상황은 별도로 다운로드해야 한다.
이미 여러 사람이 받은 이력을 바꾸는 작업은 이 예와 범위가 다르다. --everything은 다른 참조가 가리키는 커밋까지 넓히며, 다시 쓴 커밋은 식별자가 바뀐다. 원격 이력을 교체하려면 협업자의 기존 이력도 함께 처리해야 하므로, 업로드 오류마다 --everything과 강제 push를 붙이는 방식으로 진행하지 않는다. 기존 파일 이전 안내에서 이력 정리와 LFS 추적을 함께 설명하는 이유다.
파일 버전과 다운로드가 각각 사용량이 된다
2026년 10월 26일 확인한 GitHub LFS 요금 규칙에서 Free·Pro·무료 조직은 저장 공간과 다운로드 대역폭이 각각 10GiB 포함된다. Team·Enterprise Cloud는 각각 250GiB다. 과거 선불 데이터 팩 설명 대신 현재 계정의 종량제 사용량과 예산을 기준으로 본다.
LFS 파일을 수정해 push하면 바뀐 몇 바이트만이 아니라 새 파일 전체 크기가 저장 사용량에 추가된다. 예를 들어 각 1GiB인 서로 다른 원본 세 버전을 올렸다고 가정하면, 현재 작업 폴더에 한 버전만 있어도 서버에 보관한 세 버전은 3GiB다. 컴퓨터에서만 수정하고 push하지 않은 버전은 이 서버 사용량에 추가되지 않는다.
다운로드 대역폭은 받는 사람이 아니라 저장소 소유자에게 잡힌다. GitHub Actions가 LFS 원본을 받는 경우도 포함된다. 업로드에는 이 다운로드 대역폭을 계산하지 않는다. 예산을 0달러로 설정하면 초과 사용이 차단되지만, 예산 자체를 삭제하면 지출 한도가 없어지므로 두 상태를 같은 것으로 취급하지 않는다.
파일 삭제·로컬 정리·원격 제거의 차이
Git LFS 프로젝트의 한 질문자는 큰 파일을 지우고 이력 정리 도구까지 사용했는데 quota가 남았다고 보고했다. 이 질문은 2022년의 사례다. 현재 GitHub의 제거 안내도 Git 이력에서 없앤 LFS 파일의 원격 객체는 그대로 남아 저장 사용량에 포함된다고 설명한다.
| 하는 작업 | 바뀌는 것 | 자동으로 해결되지 않는 것 |
|---|---|---|
| 파일을 삭제하고 커밋한다. | 새 커밋에서 파일이 빠진다. | 과거 버전과 원격 LFS 객체는 남을 수 있다. |
| LFS 추적 규칙을 제거한다. | 이후 파일을 다룰 규칙이 바뀐다. | 기존 원격 객체를 지우는 요청이 아니다. |
| git lfs prune을 실행한다. | 조건에 맞는 로컬 LFS 사본을 정리한다. | GitHub 서버의 객체를 제거하지 않는다. |
| GitHub에서 원격 객체를 제거한다. | 서버에 보관할 LFS 데이터가 줄어든다. | 이미 발생한 그달 누적 사용량을 소급해 없애지 않는다. |
로컬 prune의 대상을 보기만 하려면 다음 명령을 쓴다. --dry-run은 실제 삭제 없이 후보를 보여준다. 노트북 공간이 문제인지 GitHub의 사용량이 문제인지에 따라 필요한 작업이 달라지므로, 서버 quota를 줄이려고 로컬 명령을 반복할 필요는 없다.
git lfs prune --dry-run --verbose GitHub는 원격 LFS 객체를 없애는 방법으로 저장소 삭제 후 재생성을 안내하고, 저장소를 삭제할 수 없다면 Support에 제거를 문의하도록 한다. 저장소 삭제에는 이슈·별 같은 프로젝트 기록의 손실도 따르므로 용량 숫자만 보고 실행할 정리 명령이 아니다. 남길 LFS 원본과 프로젝트 기록을 정한 뒤 지원 경로를 선택한다.
현재 남은 객체와 이번 달 이미 쌓인 사용량도 다르다. 월 중간에 원격 객체를 제거해도 그달의 저장 사용량을 소급해 다시 계산하지 않는다는 것이 GitHub의 설명이다. 반대로 다음 달 사용량 집계가 새로 시작한다고 서버 파일이 자동 삭제되는 것도 아니다.
Releases에 첨부하고 실제 받을 파일 확인하기
Releases는 Git 태그에 연결된 배포 묶음이다. 수정할 PSD 원본은 LFS에 두고, 그 원본에서 만든 완성 패키지는 릴리스에 붙일 수 있다. 한 릴리스에는 최대 1,000개 첨부 파일을 연결할 수 있으며, 이용자는 그중 필요한 패키지를 내려받는다.
웹에서 만들 때는 저장소의 Releases→Draft a new release로 들어간다. 기존 태그를 선택하거나 새 태그와 대상 브랜치를 정하고, 제목·변경 설명을 적은 뒤 바이너리 첨부 영역에 배포 파일을 올린다. 검토 중에는 Save draft로 두고, 첨부가 끝난 뒤 Publish release를 선택한다. 불변 릴리스를 켠 저장소는 발행 뒤 첨부를 추가·교체·삭제할 수 없으므로 초안에서 파일 구성을 완성한다.
릴리스 화면의 자동 생성 Source code ZIP은 직접 첨부한 설치 파일과 다르다. 자동 ZIP·tarball에서 LFS 파일은 기본적으로 원본 대신 포인터로 들어간다. 관리자가 Settings의 Archives에서 Include Git LFS objects in archives를 켜면 원본을 포함할 수 있지만, 이때의 다운로드는 LFS 대역폭에 잡힌다. 저장소에 커밋한 .gitattributes 규칙이 있어야 해당 객체가 포함된다.
개발자에게는 저장소와 필요한 LFS 원본을 받는 경로를, 설치만 할 이용자에게는 완성된 첨부 파일을 전달한다. 배포 안내에 연결한 파일을 직접 내려받아 원본이 필요한 자리에 포인터 텍스트만 있지 않은지, 설치 패키지가 의도한 버전인지 확인하면 전달 단계까지 마칠 수 있다.