git 의 역대 커밋 내역에서 특정 디렉토리를 삭제하기

프론트 깎는 개발자·2022년 12월 15일
2

git

목록 보기
1/1

주의! 이 작업은 force push 를 요하는 작업입니다. 작업 전 반드시 백업 레포지토리를 만들어 두세요! ⚠️

TL;DR

우선, 원하는 브랜치를 이동...
local repo 에서 지우기

git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch ${지울_디렉토리_이름}' HEAD

remote 로 push

git push origin main --force

설명

작업을 하다 보면 어떤 이유로 git push 가 거부되는 일이 있다. 필자의 경우 하나의 파일이 너무 커서 (github 기준 100MB 이상) github 로 push 가 되지 않았다.

그런데 이미 push 전에 여러 건의 커밋 이전에 이미 대용량 파일을 넣은 상태라 git commit --amend 를 사용할 수도 없었다.

remote: Resolving deltas: 100% (8/8), completed with 5 local objects.
remote: error: Trace: ${redacted_git_hash_value}
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File summaryModel/pytorch_model.bin is 472.69 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com/.
To ${https://github.com/url/tp/my/repo.git}
 ! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to '${https://github.com/url/tp/my/repo.git}'

(하나의 파일이 100 MB 제한을 넘긴 무려 472.69 MB 에 달해서 push 가 되지 않고 있다)

그래서 모든 커밋을 다 되돌아 보며 이 폴더를 삭제할 필요가 있었다.

그 때 사용한 명령어가 바로 아래와 같다.
(먼저, 삭제를 원하는 branch 로 checkout 하자)

git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch ${지울_디렉토리_이름}' HEAD

예를 들어 git repo 이름이 foo 이고 디렉토리 구성이 아래와 같다고 할 때

foo
ㄴ Bar1
	ㄴ MyDir1
    ㄴ MyDir2
ㄴ Bar2
ㄴ Bar3
ㄴ index.html

예를 들어 내가 만약 내 레포지토리에서 Bar1 폴더 전부 (하위 디렉토리인 Bar1/MyDir1Bar2/MyDir2 포함) 를 내 커밋 내역에서 삭제하고 싶다면,

git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch Bar1' HEAD

이러면 이제 나의 local 에서는 모든 커밋에서 Bar1 과 관련된 내용이 삭제된다. (변경 및 생성 내용)
하지만 아직 remote 에는 반영되지 않았다.
그런데 이렇게 될 경우 remote 와 완전히 다른 history 를 가지기 때문에 일반적인 git push 는 할 수가 없다.

따라서 force push 를 해 주어야 한다. (main 브랜치인 경우)

git push origin main --force

Force Push 는 항상 조심! 또 조심! 하자...

profile
Comfort Zone 에서 벗어나자!

2개의 댓글

comment-user-thumbnail
2022년 12월 15일

너무 도움이 되는 정보였습니다. 이렇게 좋은 글 남겨주셔서 감사합니다. 킹아

1개의 답글