Git의 용량제한과 LFS
기본적으로 git은 여러개의 작은 소스코드 파일들을 위한 버전 컨트롤 시스템(VCS)이다. 따라서 Github의 경우 50Mb부터 Warning이 표시되고, 100Mb부터는 push시 Error가 발생한다. 그럼에도 불구하고 경우에 따라서 반드시 대용량 파일을 git repo에 포함시켜야하는 상황이 존재할 수 있다(예를 들면 학습된 모델파라미터를 올려야할 때). 이러한 경우에 사용할 수 있는 해결책인 Git LFS(Large File Storage)을 소개한다.
git lfs가 정상적으로 적용된 경우, 아주 큰 파일에 대해서도 git push와 pull이 가능해진다.
기본적인 사용방법은 다음 블로그에서 가져왔다.
Git LFS 기능 설치하기
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt install git-lfs
특정 repo에 git lfs 적용하기
(해당 레포로 이동 후)
git lfs install
특정 repo에 git lfs 해제하기
(해당 레포로 이동 후)
git lfs uninstall
LFS로 File 관리하기
먼저 lfs를 사용하고자 하는 repo에서 다음을 입력하여 lfs를 적용해야한다.
git lfs install
그 다음 lfs로 관리할 파일을 track한다. 기본적으로는 해당 파일을 git add하기 전에, git lfs track을 해주어야한다. 만약 기존에 add해둔 파일을 lfs로 관리해야하는 상황이라면 git rm --cache로 먼저 unstaging을 시킨 다음, 다시 git lfs track을 해야한다.
git rm --cahced <file path>
git lfs track <file path>
그러면 해당 파일의 내용이 원래의 contents가 아니라, lfs pointer로 바뀌는 것을 알 수 있다.또한 lfs로 트래킹하는 파일에 대한 정보는 .gitattributes을 통해서 관리가 되어 이 변경사항을 꼭 add해주어야한다. 나머지는 일반적인 git push와 동일하다.
git add .gitattributes
git commit -m "update gitattributes for lfs"
git push
(단, 이 글에 따르면, .gitattributes를 먼저 push하고난 다음에야 정상적으로 나머지 파일들에 대해서도 잘 동작하는 경우가 있다고는 한다.)
LFS File 관리 해제하기
.gitattributes의 맨 마지막 라인을 보면 어떤 규칙으로 파일들이 lfs로 관리되고 있는지 볼 수 있다. 그리고 새로 track할때와 마찬가지로 git lfs untrack을 할 때마다 .gitattributes의 내용이 변경된다.
그런데 untrack을 하더라도 .gitattributes의 내용만 변경되고, 실제로 해당 file의 내용은 아직도 lfs pointer인 상태로 유지되고 있다. 따라서 이때도 마찬가지로 rm --cache를 이용해서 unstaging한 후 다시 add해주어야, git lfs 가 관리하던 파일에서, 다시 일반적인 git이 관리하는 파일로 변경된다.
git lfs untrack <file>
(또는 .gitattributes에서 수동으로 삭제 후)
git rm --cached <file>
git add <file>
LFS로 관리중인 File 다운로드 받기
단순히 git lfs로 관리중인 파일이 아래와 같이 lfs pointer만 가지고 있는 경우, lfs pull 명령어로 컨텐츠를 다운받아올 수 있다.
version https://git-lfs.github.com/spec/v1
oid sha256:265d20bff17c6e19af9c76ef9e00c89de14e34135e23ac2626f6db56e7fb3182
size 15927
git lfs pull --> 실제 파일 컨텐츠를 다운받음
LFS 파일 목록 확인
git lfs ls-files : lfs로 관리중인 파일 목록 확인
LFS를 subdir에 대해서 적용하기
git rm -r --cached "toy_data/**/*"
git lfs track toy_data/**/*
이런식으로 꼭 --cached에서는 큰따옴표로 감싸은뒤 **을 사용해야하고, 반면 lfs에서는 큰따옴표 없이 적용해야한다.
LFS가 적용된 repo clone하기
git clone을 하고나서 pull이나 fetch를 해도 제대로 lfs가 동작하지 않고, pointer정보만 가져오게 되므로, 이 때는 git lfs pull을 해주어야한다.
git clone [url]
git lfs pull
LFS migrate
lfs track로 파일을 추적하더라도, git의 history에 남아있는 파일들은 아직도 과거의 방식대로 기록이 되어있다. 이를 전부 git lfs로 바꾸는 방법은 오직 history rewrite밖에는 방법이 없다. 그래서 이러한 경우에 필요한 명령어가 바로 git lfs migrate 이다.
git lfs migrate import --include="toy_data/*"
git push
Trouble Shooting
git lfs pull로 이미 tracking하던 파일을 받았는데, modifed로 나오면서 push하면 lfs로 올리라는 에러가 뜰 때
* 문제의 원인
다른 사람이 lfs track된 파일을 push할 때 .gitattributes을 빠트리고 올린 것으로 보인다. 따라서 git pull을 한 상태에서, 최근의 merge commit을 취소하고 .gitattributes을 올바르게 수정하고 다시 commit해야한다.
git reset --mixed HEAD~1 으로 일단 마지막 merged commit을 취소한다.
그다음 unstage된 상태의 파일에 대해서 git lfs track으로 다시 track을 한다.
그리고나서 add/commit/push를 한다.
LFS File 관리를 해제해도 계속 문제가 발생
this exceeds GitHub Enterprise's file size limit of 100.00 MB
이는 git history에 아직 github로 push불가능한 large file들이 남아있어서 생기는 문제이다. 따라서 완전히 history에서까지 파일들을 지워주어야한다.
git filter-branch --tree-filter 'rm -rf path/to/your/file' HEAD
git push
Git Enterprise에서 LFS이 가능하게 설정하기
https://help.github.com/en/enterprise/2.19/admin/installation/configuring-git-large-file-storage
Locking support detected on remote "origin". Consider enabling it with:
lfs가 포함된 파일을 push했을 때 위와 같은 메시지가 뜨는 경우, 그 에러 메시지 바로 아레에 git config를 이용한 해결법이 나온다. 이를 그대로 복사해서 입력해준다.
(혹시 이거 때문에 자꾸 .git/index.lock 파일이 생성되었다가 삭제가 안되고 계속 남아있는 것인가? 아님... 이거랑 상관없이 계속 그러네)
git config 'lfs.https://github.com/<my_repo>.git/info/lfs.locksverify' true
dial tcp: lookup lfs.github.com: no such host
이러한 에러 발생시 DNS 서버에 해당 도메인이 제대로 처리되지 않아서 발생하는 것이었다. 따라소 매우 손쉽게 hosts에 직접 해당 domain의 ip를 등록하여 해결하였다.
https://github.com/git-lfs/git-lfs/issues/2887
https://newsight.tistory.com/266
remote: error: File vanilla-app.zip is 129.25 MB; this exceeds GitHub's file size limit of 100.00 MB
lfs로 관리할 파일들은 반드시 git add로 staging을 하기 전에 git lfs track으로 해당 파일을 입력해야한다. 만약 실수로 순서를 틀렸을 경우 위와 같은 에러메시지가 발생한다. 해결 방법은 git rm --cache <파일> 으로 해당 파일을 unstaging한다음 다시 올리면 된다.
https://github.com/git-lfs/git-lfs/issues/1933
댓글