- [GitHub] API key 등 민감한 정보 히스토리 삭제2025년 01월 16일 22시 35분 12초에 업로드 된 글입니다.작성자: DandyNow728x90반응형
github를 사용하다 보면 실수로 API key와 같은 민감한 정보를 push해버리는 경우가 있다. github에서 해당 파일을 삭제하더라도 history에는 여전히 민감한 내용이 노출되고 있다. 해당 project를 private으로 전환할 수도 있겠지만 클라우드에 노출되어 있다는 점은 변함없다. 이 난감한 상황을 해결하기 위한 "민감한 history를 제거하는 방법 두 가지"를 정리해 보았다.
1. git filter-branch 명령어를 사용하여 히스토리 삭제
1) git filter-branch 명령어 실행
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch <파일 경로>" --prune-empty --tag-name-filter cat -- --all이 명령어는 Git 저장소의 히스토리를 재작성하여 특정 파일을 삭제하는 강력한 명령어이다.
명령어 해석:
--force: 강제로 히스토리를 변경한다.--index-filter: 각 커밋의 인덱스에 대해 지정된 명령을 실행한다."git rm --cached --ignore-unmatch <파일 경로>": 지정된 파일을 인덱스에서 삭제한다.--ignore-unmatch옵션은 해당 파일이 없어도 오류를 발생시키지 않도록 한다.--prune-empty: 빈 커밋을 제거한다.--tag-name-filter cat: 태그 이름을 그대로 유지한다.--all: 모든 브랜치에 적용한다.
작동 방식:
- 히스토리 재작성: 이 명령어는 Git 저장소의 모든 커밋을 순차적으로 검토한다.
- 파일 삭제: 각 커밋에서 지정된 파일을 인덱스에서 삭제한다.
- 빈 커밋 제거: 파일이 삭제된 후 빈 커밋이 되면 해당 커밋을 제거한다.
- 태그 유지:
--tag-name-filter cat옵션으로 인해 태그 이름은 변경되지 않고 그대로 유지된다. - 모든 브랜치 적용:
--all옵션으로 인해 모든 브랜치에 변경 사항이 적용된다.
결과: 이 명령어를 실행하면 지정한 파일이 모든 커밋에서 삭제되고, 빈 커밋이 제거되어 깔끔한 히스토리가 생성된다.
주의사항:
- 히스토리 변경: 이 명령어는 Git 히스토리를 영구적으로 변경한다. 따라서 실행하기 전에 반드시 백업한다.
- 협업: 다른 사람과 함께 작업하는 저장소라면, 이 명령어를 실행하기 전에 팀원들에게 알리고 충분히 논의한다.
- 원격 저장소: 변경된 히스토리를 원격 저장소에 반영하려면
git push --force명령어를 사용해야 한다.--force옵션은 매우 위험하므로 신중하게 사용해야 한다.
추가 설명:
<파일 경로>: 실제 삭제하려는 파일의 경로를 입력해야 한다.--tag-name-filter cat: 이 옵션을 생략하면 태그가 삭제될 수 있다. 필요에 따라 다른 태그 필터링 옵션을 사용할 수 있다.

[그림 1] 명령어를 실행한 후에도 git으로 관리하던 test.txt 파일 유효함. 
[그림 2] add, commit을 마저 진행해야 한다. log를 찍어보면 기존 history가 모두 삭제된 것을 확인할 수 있다. 2) 원격 저장소에 강제로 푸시 (Force Push)
git add,git commit까지 진행했다면 최종적으로git push를 진행해야하는데,git filter-branch는 로컬 저장소의 커밋 히스토리를 완전히 재작성하는 작업이기 때문에, 일반적인git push로는 원격 저장소에 반영할 수 없다. 원격 저장소의 히스토리와 로컬의 재작성된 히스토리 간에 불일치가 발생하기 때문이다. 따라서 강제로 푸시(--force또는--force-with-lease)해야 한다.git push --force: 이 명령어는 원격 저장소의 히스토리를 로컬의 히스토리로 덮어씌운다. 가장 간단하지만 가장 위험한 방법이다. 다른 사람들이 해당 브랜치에 푸시한 내용이 있다면, 그 내용이 손실될 수 있다.git push --force-with-lease: 이 명령어는--force보다 안전한 방법이다. 원격 브랜치가 마지막으로 로컬에서 가져온(fetch) 상태와 동일할 경우에만 푸시를 허용한다. 만약 그 사이에 다른 사람이 원격 브랜치에 푸시를 했다면, 푸시를 거부하여 다른 사람의 작업을 실수로 덮어쓰는 것을 방지한다. 가능하다면 이 옵션을 사용하는 것이 좋다.
명령어 예시:
git push origin <브랜치명> --force-with-lease # 또는 git push origin <브랜치명> --force여기서
<브랜치명>은 현재 작업 중인 브랜치(예:main,master,develop등)로 대체해야 한다. 모든 브랜치를 한 번에 푸시하려면--all옵션을 사용할 수도 있다.git push origin --all --force-with-lease2. 새로운 저장소 생성 및 이전
이 방법은 기존 저장소를 완전히 삭제하고 새로운 저장소를 만드는-무식하지만 확실한-방법이다.
- 새로운 저장소 생성: 기존 저장소와 동일한 프로젝트를 위한 새로운 저장소를 생성한다.
- 필요한 파일 복사: 삭제하고 싶은 파일을 제외한 파일만 복사한다.
- 새로운 저장소에 Push: 새로운 저장소에 복사한 파일을 Push한다.
- 협업자에게 알림: 협업자들에게 새로운 저장소로 이동하도록 안내한다.
- 기존 저장소 삭제: 기존 저장소는 Github에서 완전 삭제한다.
728x90반응형'언어·프레임워크 > GitHub' 카테고리의 다른 글
[GitHub] 원격 브랜치를 로컬로 가져오는 방법 (0) 2025.08.03 [GitHub] 효과적인 Git Convention 가이드라인 (한국어 예시) (0) 2025.06.19 [GitHub] git clone할때 인증 문제 >.< (1) 2023.10.04 [GitHub] The file is empty?? 커밋이 왜 안되지?? (0) 2023.05.28 [GitHub] GitLab에서 GitHub 데스크톱을 사용하는 방법 (0) 2023.03.20 다음글이 없습니다.이전글이 없습니다.댓글