코딩하는 개굴이

LFS 를 적용해보자! (feat. Trouble Shooting) 본문

GIT

LFS 를 적용해보자! (feat. Trouble Shooting)

개굴이모자 2023. 7. 14. 01:09
반응형
LFS 를 한번도 써본 적이 없는 상태에서 대략적으로 무엇인지만 알았다가 큰 코다친 경험으로 인해,
정확히 알아보고자 해당 포스팅을 작성하게 되었다. 다음에는 이런일이 없도록...!!

 

LFS 란 무엇일까?

LFS 란 무엇일까? 아래처럼 한방에 이해되도록 하는 취향 저격인 이미지가 있길래 끌어와보았다.

image is from link (https://medium.com/junior-dev/how-to-use-git-lfs-large-file-storage-to-push-large-files-to-github-41c8db1e2d65)

간략하게 말해서는 좌측의 뚱이처럼 우리가 입이 작은 스펀지밥인 github 에 100MB 크기가 넘는 파일들을 업로드 할 수 있도록 하는 기능이다.

Git 은 본래 여러개의 작은 소스코드 파일들을 위한 버전 컨트롤 시스템(VCS) 이다. 따라서, 인식하지 못했을지 모르지만 Github 은 50Mb 부터 push 시 Warning 이 표시되고, 100Mb 부터는 push 시 Error 가 발생한다. 그러나, 상황에 따라 불가피하게 반드시 대용량 파일을 git repo 에 포함시켜야 할 때가 있다. 이러한 경우를 위해 Git LFS 가 존재한다.

 

또한 추가로, audio, video 혹은 image 파일을 LFS 없이 일반적으로 올리고자한다면 이들은 binary file 들이기 때문에 만일 어떠한 변경이 발생할 경우 일반 파일들과 같은 non-binary file 들이 Git 으로 인해 트래킹 되는 것과 똑같이 트래킹되지는 않는다. 이들은 트래킹 되지 않고 파일을 복사한 형태로 트래킹된다. 따라서, 만일 100Mb 에 가까운 바이너리 파일을 4번 수정하게 된다면, 본래 100Mb 에 변경된 4번의 100Mb 가 붙어 총 500Mb 를 차지하게 된다.

그 뿐만이 아니라 이러한 변경은 remote 에도 푸시되기 때문에 remote 또한 사이즈가 늘어나게 되고 이것이 여러 파일에 대해 반복되면 clone, push, pull 등의 속도가 느려지게 될 수 있다. 

그러나, LFS 를 사용할 경우 커밋 할 때 원본 바이너리 파일을 LFS Repo 에 푸시한 후엔 바이너리 파일을 가리키는 대신에 포인터를 가리키게 되므로, 필요한 파일의 버전만 Git LFS 서버에서 가져되어 공간과 시간을 절약할 수 있다.

 

 

 

 

Git LFS 는 어떻게 동작할까?

 

Git LFS 는 대용량 파일을 별도의 서버에 올리고, 원래 파일이 있어야 할 위치에는 포인터만 남긴다.

 

따라서, 사용자 입장에서는 Git Push, Pull 등을 그대로 사용할 수 있다.

 

다만, Github 에서 제공하는 LFS 는 무제한은 아니다. Pro, Github Free 의 경우 2GB 만 제공되기 때문에, 100MB 가 넘어가지 않는다면 개인의 경우 LFS 에 올리면 제한 용량이 소비될 수 있으므로 주의해야한다.

 

 

Git LFS 적용하기

Git LFS 를 적용하고자 하는 Repo 에서 사용하겠다는 선언을 해야한다.
해당 Repo 의 위치로 이동하여 아래 명령으로 install을 수행한다.

git lfs install

 

LFS 에 올릴 파일을 Git의 Tracking 에서는 제외해야하기 때문에, 아래 명령어로 Unstaging 을 진행한다.
(별도의 GUI 툴을 사용한다면 툴을 이용하여 해도 무방하다.)

git rm --cached (file path)

 

만일 특정 파일 하나만 포함시키고자 한다면 LFS 에서 사용할 수 있도록 수동으로 Tracking 을 설정한다.

git lfs track (file path)

 

그러나, 주로 100Mb 이상의 파일들은 mp3, mp4, wav, png, webp, jpeg, mov 등의 확장자이기 때문에 아래처럼 와일드카드의 형태로 확장자만 지정해서 repo 내의 모든 wav 파일은 lfs 에 올리겠다고 설정할 수 있다.

git lfs track "*.wav"

 

이렇게 설정하고 나면 레포에 .gitattributes 라는 파일이 생긴 것을 확인할 수 있다. 이 파일에 Git LFS 로 관리되는 파일 정보가 저장되기 때문에 Git 에 해당 변경사항을 추가해주어야한다.

git add .gitattributes
git commit -m "넣고자 하는 커밋 메시지"

 

이렇게 Commit 까지 완료했다면 Remote 에 push 하면 완료이다!

git push (remote 이름) (branch 이름)

 

LFS 관리하기

LFS 파일 목록 확인하기

현재 lfs 에 어떤 파일들이 올라가 있는지 아래와 같은 명령어로 확인할 수 있다. 아까 올린 파일이 잘 올라가있는지 확인해보자.

git lfs ls-files

 

LFS 로 관리 중인 File 다운 받기

git lfs 로 관리 중인 파일이 lfs 포인터만 가지고 있는 경우, lfs pull 명령어로 컨텐츠를 받아올 수 있다.

git lfs pull

 

LFS File 관리 해제하기

.gitattributes 는 어떤 규칙들로 파일들이 관리되고 있는지 볼 수 있고, git lfs untrack 을 할 때마다 해당 내용이 바뀌게 된다.

그러나 실제로 untrack 을 하면 (혹은 수동으로 gitattributes 에서 해당 파일 필터링을 지우거나) gitattributes 의 내용만 바뀌고 포인터였던 파일은 그대로 포인터인 상태로 유지되고 있는 것을 볼 수 있을 텐데, 이때는 rm --cache 를 이용해서 unstaging 을 한 다음에
다시 add 를 해주어야 git lfs 로 관리되던 파일에서 다시 git 이 관리하는 파일로 트래킹이 가능해진다.

git lfs untrack (file path)
git rm --cached (file path)
git add (file path)

 

LFS migrate

lfs track 으로 특정 파일을 이제부터 추적하도록 변경했다고 하자. 그렇다면 기존에 git history 에 남아있는 이전 버전의 파일들은 아직 과거 방식 그대로 기록이 되어있을 것이다. 이를 전부 git lfs 로 바꾸는 방법은 오직 history rewrite 이며, 이는 git lfs migrate 로 수행할 수 있다.

git lfs migrate import --include=(file path)
git push
 
 
 
 

Trouble Shooting

git lfs pull 로 이미 tracking 하던 파일을 받았는데, modified 로 나오면서 push 하면 lfs 로 올리라는 에러가 뜰 때

다른 사람이 lfs track 파일을 push 할 때 .gitattributes 를 빠트리고 올린 것일 수 있다. 따라서 git pull 을 한 상태에서 최근의 merge commit 을 취소하고, gitattributes 를 수정 후 다시 commit 해야한다.

 

Git LFS upload failed: Your push was rejected due to missing or corrupt local objects.

본인이 고생했던 이슈이다.

하단에 hint 로 "You can disable this check with `git config lfs.allowincompletepush true`" 를 설정할 수 있다. 라고 하는데, 해당 설정은 푸시할 때 Git 푸시를 중단하지 않고 개체가 로컬 캐시에서 누락되도록하는 세팅이기에 임시적인 해결책이 될 수는 있지만 위험한 옵션일 수 있다.

문제 자체는 lfs 에 업로드가 되지 않았기에 포인터로 가리키는 것을 찾을 수 없어 발생하는 것이고 이후에 파일을 엎어썼다고 하더라도 새로 올린 것에 대해서는 새로운 oid 를 갖고 갔기 때문에 기존 것을 찾을 수 없다는 이슈가 발생한 것이다. 따라서 missing 인 파일을 찾아 lfs 에 임의로 업로드해준다면 해결될 수 있다.

 

 

참고 링크

반응형

'GIT' 카테고리의 다른 글

[Git 이해하기] Git 이 관리하는 방법  (0) 2023.07.16
[Git] Pull Request 를 Git 에 끌어오자!  (0) 2023.04.17
Comments