bfg-repo-cleaner 로 git repository 에 올린 민감한 정보 삭제하기
개요
실수로 github 나 gitlab 의 public 저장소에 큰 파일을 커밋했거나 암호나 SSH private key 같이 민감한 정보를 올린 경우 파일을 삭제하거나 commit history 를 정리해야 합니다.
branch 를 재작성하는 git-filter-branch 명령으로 이런 작업을 할 수 있지만 사용이 어렵고 속도가 느린 단점이 있습니다.
BFG 는 git-filter-branch 명령의 대체제로 빠르고 사용하기 쉬운 장점이 있습니다. (반대 급부로 filter-branch 명령만큼 강력하지는 않습니다.)
BFG 는 java 로 작성되어서 JRE 가 필요하며 binary jar 파일은 maven central 에서 다운로드 받으면 됩니다.
$ curl -o bfg.jar -L https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar
사용
1. BFG 로 파일을 삭제하거나 커밋 이력을 정리할 저장소를 --mirror 옵션을 붙여서 clone 합니다.
$ git clone --mirror git@github.com:lesstif/my-repos.git
이 저장소는 bare 저장소로 일반적인 파일들은 보이지 않지만 저장소의 전체 git database 를 포함하고 있습니다.
2. 이제 저장소로 이동하지 말고 상위 폴더에서 BFG 명령어로 커밋 내역을 정리합니다. 예로 다음은 대상 저장소 커밋 이력에서 크기가 100M 이상인 파일을 삭제합니다.
$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repos.git
3. 정리가 끝났으면 저장소로 이동합니다.
$ cd my-repos.git
4. BFG 는 커밋과 브랜치, 태그를 업데이트했지만 실제 파일이 삭제되거나 변경되지는 않았습니다. local 의 원치않는 dirty data 를 삭제하는 명령인 git-gc 를 실행해서 변경 사항을 반영합니다.
$ git reflog expire --expire=now --all $ git gc --prune=now --aggressive
5. 완료되었으면 push 해서 원격 저장소에 반영합니다.
$ git push
예제
정리후 위 절차의 3번부터 실행해서 저장소에 반영하고 push 까지 마쳐야 합니다.
큰 파일 삭제
크기가 50M 이상인 모든 파일을 삭제합니다.
$ java -jar bfg.jar --strip-blobs-bigger-than 50M my-repos.git
SSH 개인키 삭제
id_rsa 나 id_dsa 로 시작하는 SSH 개인키 파일들을 모두 삭제합니다.
$ java -jar bfg.jar --delete-files id_{rsa,dsa} my-repos.git
민감 정보 포함한 커밋 이력 변경
설정 파일등에 DB 접속 암호등 민감한 정보를 포함해서 커밋했을 경우 -rt, --replace-text <expressions-file> 명령을 사용해서 제거할 수 있습니다.
<expressions-file>에는 패턴과 대체할 문자열을 적어 주면 되며 regex: 접두어를 붙이면 정규식 형식도 가능합니다.
실수로 Access Token 과 실제 domain 을 추가해서 커밋했고 내역 삭제를 위해서 expressions-file 파일을 만들었습니다.
regex:jira.server.url=.*==>ijra.server.url=https://your-jira.host.here regex:jira.user.pat=.*==>ijra.user.url=your-personal-token-here
이제 다음 명령으로 민감 정보를 포함한 커밋을 정리합니다.
$ java -jar bfg.jar --replace-text passwords.txt my-repos.git Using repo : C:\Users\lesstif\github\java\jira-rest-client Found 44 objects to protect Found 10 commit-pointing refs : HEAD, refs/heads/develop, refs/heads/main, ... Found 3 tag-pointing refs : refs/tags/RELEASE-0.6.1, refs/tags/v0.0.2, refs/tags/v0.7.1 Protected commits ----------------- These are your protected commits, and so their contents will NOT be altered: * commit 903fa3a9 (protected by 'HEAD') - contains 2 dirty files : - README.md (5.5 KB) - jira-rest-client.properties.example (285 B ) ... Changed files ------------- Filename Before & After --------------------------------------------------------------------------------------------------- jira-rest-client.properties.example | a32ac01d ⇒ 405ef3b3, 2a9ce72c ⇒ d8f8bac1, 026ffea8 ⇒ 859e789d In total, 11 object ids were changed. Full details are logged here: