https://github.com/rtyley/bfg-repo-cleaner
https://rtyley.github.io/bfg-repo-cleaner/
실수로 github 나 gitlab 의 public 저장소에 큰 파일을 커밋했거나 암호나 SSH private key 같이 민감한 정보를 올린 경우 파일을 삭제하거나 commit history 를 정리해야 한다.
삭제하고 마스킹해서 새로운 커밋을 올려도 과거 커밋 (변경) 기록에는 남아있겠죠?
리포의 히스토리를 관리하는 툴에는 두 가지가 있다.
하나는 깃허브에서 공식적으로 제공하는 방법인 git filter-repo 이다.
다른 하나는 위의 툴을 대체하기 위한 bfg 이다.
⇒ 빠르고 사용하기 쉬운 장점, 그러나 강력하지는 않음 (번거롭지만 강력한 git-filter-branch 사용해도)
- Removing Crazy Big Files
- Removing Passwords, Credentials & other Private data
사용법
1. java jdk 설치
java -version
확인. 아무것도 안뜬다면 당신의 컴퓨터에는 자바가 없는 것입니다.
https://www.azul.com/downloads/?package=jdk#download-openjdk
위 사이트에서 jdk 다운로드. dmg 파일로 다운받으면 맥에서 쓰기 편리하더라고요
2. bfg.jar 다운로드
curl -o bfg.jar -L <https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar>
3. 레포를 --mirror 플래그로 클론해오기
git clone --mirror <my awesome repo.git>
- normal file들은 보이지 않는 bare repo, full copy of Git DB of your repo
- 로컬에 당연히 백업 만들어둬야 함
4. bfg 돌리기 (clean 하기)
java -jar bfg.jar --strip-blobs-bigger-than 100M haha.git
java -jar bfg.jar --delete-files id_{dsa, rsa} haha.git
java -jar bfg.jar --replace-text delete.txt haha.git
- 크기가 큰 파일들을 커밋 히스토리에서 삭제할수도 있고
- 특정 이름의 파일들을 히스토리에서 삭제할수도 있고
- delete.txt 파일에 담긴 text들을 전부 ***REMOVED*** 로 마스킹할수도 있다 // ‘regex:’, ‘glob:’ prefix
아래처럼 delete.txt 를 구성하면 유출되면 안되는 url들을 커밋 히스토리에서 마스킹해버릴 수 있겠죠
regex:(rtsp:\\/\\/admin:[^@]+@) # delete.txt
5. 남아있는 dirty data 삭제하기
cd haha.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
- 4단계 진행하면 commit, branch, tag 등은 업데이트되었지만 실제 파일의 삭제나 변경은 아직 수행 안 됨
- git-gc 이용해서 삭제
5. git push
git push
- this push will update all refs on your remote server
- repo의 old copy 가지고 있는 사람들은 fresh clone 수행하면 됨 (dirty history 남아있으므로)
트러블슈팅
1. repo의 branch rule 적용되어있을 때
당연하게 git push 가 막혀있습니다
잠깐 branch protection을 disable or delete 하고 진행하셔야 함
2. ! [remote rejected] (protected branch hook declined) 경고 메시지
push는 완료된거 같은데, 수많은 경고 메시지의 향연..
git for-each-ref --format="%(refname)" refs/pull/ | xargs -n 1 git update-ref -d
(편법) 위 커맨드를 사용해 refs/pull 참조들을 로컬 레포에서 전부 제거한 후 push하면 발생하지 않는다
쨌든 저 경고가 왜 발생하고 근본적인 원인은?
https://github.com/rtyley/bfg-repo-cleaner/issues/36
https://stackoverflow.com/questions/34265266/remote-rejected-errors-after-mirroring-a-git-repository
GitHub의 refs/pull/과 관련된 읽기 전용 참조들 때문이다.
이 참조들은 GitHub에서 자동으로 생성되며, Pull Request와 관련된 브랜치에 대한 참조를 포함한다
우리는 --mirror clone으로 전부 가져왔고 당연히 pull request 관련 참조들도 포함
⇒ refs/pull/ 참조들은 읽기 전용이기 때문에 사용자가 직접 수정하거나 삭제할 수 없음
= GitHub에서 관리되며, 사용자 푸시 작업에서 수정이 거부됨
⇒ Pull Request와 관련된 참조들(refs/pull/)은 해당 Pull Request에서 사용된 커밋들을 가리킴
즉 BFG가 히스토리를 정리하여 민감한 정보를 제거하더라도, 해당 참조들에 의해 과거의 커밋 히스토리가 남아 있을 수 있다. 따라서, Pull Request 내에서 과거의 민감한 정보가 여전히 확인될 수 있다는 거 (!!!!!)
그렇다면 pr history까지 없애려면 어케 하느냐
1. 레포를 새로 판다.. (거긴 pr 관련 read-only ref 가 없을테니)
2. contact github support and ask them to delete PRs
"해줘"
교훈: commit history는 흑역사 삭제 가능이지만 pr history는 쉽게 못지우니 .gitignore + 주요 정보 commit 전에 masking 꼭 하자..
'etc' 카테고리의 다른 글
github에는 못올리는 큰 파일 dvc로 관리하기 (0) | 2024.08.29 |
---|---|
rsync로 원격 서버에 파일 빨리 올리기 (0) | 2024.08.29 |
PyTorch와 PyTorch Lightning (0) | 2024.08.29 |
rootutils로 프로젝트 구조 관리하기 (0) | 2024.08.29 |
venv → poetry 로 포팅하기 (0) | 2024.08.29 |