프로젝트 작업 중 실수로 큰 파일을 Git 저장소에 커밋하면 push, fetch 속도가 느려집니다. 다른 팀원들에게 불필요한 부담을 줄 수 있죠. 이 글에서는 Git 저장소에 이미 올라간 큰 파일을 제거하는 방법을 다룹니다.
방법 1: git filter-repo
사용하기
git filter-repo
는 기존에 사용되던 도구인 git filter-branch
보다 신뢰성과 성능을 개선한 도구입니다.
그런데 단점이 있습니다. Git과 별도로 설치해야 한다는 거죠. 혹시 모르니 아래 설치를 하기 전에 먼저 git filter-repo --help
라고 명령어를 쳐 보세요. 깃 명령이 아니라고 나오지 않으면 설치돼 있는 것입니다.
설치 방법
- macOS:
brew install git-filter-repo
- Linux:
sudo apt-get install git-filter-repo
- Windows:
pip install git-filter-repo
파일 제거 방법
아래 명령으로 제거합니다. 그런데 제거하기 전에 git remote -v
로 원격 저장소 정보를 확인하고 보관해 두세요. 작업 후 다시 넣어 줘야 하거든요.
git filter-repo --path path/to/large_file --invert-paths
옵션은 아래와 같습니다.
path/to/large_file
: 제거할 파일의 경로--invert-paths
: 지정된 파일을 제외한 나머지 모든 파일을 유지한다는 옵션
원격 저장소 정보 손실
git filter-repo
를 사용하고 나면 원격 저장소 정보가 사라집니다. 이를 복구해야 합니다.
- 원격 저장소 URL 재설정: 원격 저장소 URL을 다시 설정합니다. 다음 명령어를 사용해 다시 추가합니다.
git remote add <name> <repository-url>
name이 origin이라면 명령이 아래와 같겠죠.git remote add origin <origin-url>
- 원격 저장소 정보 확인: 원격 저장소 설정이 올바르게 되어 있는지 확인합니다.
git remote -v
Git Filter-Repo 사용 후 동료들이 해야 할 일
git filter-repo
를 하면 커밋 history가 변경되기 때문에 저장소에는 강제로 푸시를 해야 합니다. 덮어 써야 하는 것이죠.
혼자 작업하는 저장소라면 상관없지만 동료들과 함께 쓰는 저장소라면 강제 푸시 전에 동료들에게 알리고 동료들이 해야 하는 절차를 미리 알려 주는 게 좋겠죠.
우선 강제 푸시 명령은 git push -f
입니다.
동료들은 이제 바뀐 원격 저장소를 받아 와야 할텐데요. 이 때 단순히 git pull
을 사용하면 충돌이 발생할 겁니다. 따라서 아래 명령을 이용해 강제로 로컬 코드를 덮어써야 합니다.
git fetch origin
git reset --hard origin/브랜치명
이 명령을 내리면 변경된 원격 코드가 로컬 코드를 덮어쓰게 되므로 중요한 변경사항이 있다면 백업해 둬야 합니다.
방법 2: git filter-branch
사용하기
git filter-branch
는 오래된 도구로, 실전에서 사용하는 복잡한 저장소에서는 느리고 문제를 일으킬 수 있습니다. 아래는 git-filter-repo가 git-filter-branch와 자신을 대비한 설명입니다.
filter-branch
- 속도 문제:
filter-branch
는 복잡한 레포지토리에서 매우 느리게 작동합니다. 일반적으로 예상보다 수십 배 느리게 처리될 수 있습니다.- 예기치 않은 문제: 이 명령어는 사용 중에 문제가 발생할 수 있습니다. 변경 작업이 제대로 이루어지지 않거나, 오히려 더 복잡하고 지저분한 상태가 될 수 있습니다.
- 사용의 어려움: 약간만 복잡한 수정 작업을 하더라도
filter-branch
를 사용하는 것은 매우 번거롭습니다.- 대안 제안: Git 프로젝트 측에서는
filter-branch
의 문제를 해결할 수 없다고 하며, 더 이상 사용하지 말 것을 권장합니다.- 대체 도구:
filter-branch
의 열렬한 팬이라면filter-lamely
라는 대체 도구에 관심이 있을 수 있습니다. 이는filter-repo
를 기반으로 한 재구현으로 성능이 더 좋지만, 여전히filter-repo
만큼 빠르거나 안전하지는 않습니다.- 명령어 변환:
filter-branch
의 사용 예제를filter-repo
명령어로 변환하는 방법을 보여주는 요약 자료도 제공됩니다.
사용 방법
git filter-branch --tree-filter 'rm -f path/to/large_file' --prune-empty -- --all
path/to/large_file
: 제거할 파일의 경로--prune-empty
: 빈 커밋을 제거
filter-branch를 사용한 후에도 강제 푸시를 해야 하고, 역시 동료들은 그걸로 로컬 코드를 덮어쓰는 작업을 해야 합니다.
정리
Git 저장소에서 실수로 큰 파일을 커밋했을 때, 현재 Git 자신이 추천하는 방법이 git filter-repo
를 사용하는 것입니다.
다만 이 도구를 사용한 후에는 원격 저장소 정보를 다시 입력해야 하고, 필요하면 강제로 푸시해(git push -f
) 변경 사항을 적용해야 합니다. 동료들이 있다면 로컬 코드도 덮어써야 합니다.
댓글 남기기