Git

[Git] 커밋 히스토리에서 .env 파일 완전 삭제하기

jundyu 2024. 10. 8. 09:25

Git

Github의 레포지토리를 처음 만들 때 private으로 설정해둬서 .env 파일까지 깃헙에 푸시했었는데 private 설정이 되어있어도 .env 파일을 푸시하는 건 위험다는 것을 알게 되어 뒤늦게 .gitignore 파일에 .env를 추가해줬습니다. 그리고 github에서도 .env파일을 삭제해줬습니다. 그러고 한참 작업하다가 push 하는데 웬걸 이런 에러가 떴습니다.

Error: You are trying to push a commit that contains the .env file which contains sensitive information.
Please remove the .env file from your commit history.

 

"Github에서도 삭제했고 .gitignore에도 추가했는데 왜 또 삭제하라는거지?"하는 생각에 알아보니 커밋했던 내역에 남아있던 .env 파일 때문이었습니다. 커밋의 해시 코드를 추적해서 github에서 .env 파일의 코드 기록을 볼 수 있기 때문에 이전 커밋에 대해서도 전부 삭제해줘야한다는 사실..! 이때가 커밋이 200개가 넘어가는 시점이라 하나하나 다 지워주는 건 어려웠습니다.

 

그래서 git의 filter-branch 명령어로 전체 커밋 내역을 전부 삭제해줬습니다!

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch .env" --prune-empty --tag-name-filter cat -- --all

1. git filter-branch

git filter-branch는 Git 커밋 히스토리를 수정하는 데 사용되는 강력한 명령어입니다. 주로 과거 커밋에서 특정 파일이나 데이터를 제거하거나 변경할 때 사용됩니다.

2. --force

--force 플래그는 명령어를 강제로 실행하도록 합니다. Git은 히스토리 재작성 작업이 위험하다고 경고할 수 있는데, 이 플래그는 그러한 경고를 무시하고 작업을 계속 진행하도록 보장해줍니다. 예를 들어, 이미 한 번 필터링된 브랜치를 다시 필터링할 때 발생할 수 있는 문제를 방지합니다.

3. --index-filter "git rm --cached --ignore-unmatch .env"

--index-filter는 Git이 각 커밋에서 파일을 삭제하거나 수정하도록 하는 매우 빠른 필터입니다. 이 필터는 각 커밋의 인덱스(즉, 스테이징 영역)에 대해 작업을 수행합니다.

  • git rm --cached .env: .env 파일을 스테이징 영역에서 제거합니다. --cached 옵션을 사용하므로 실제 파일은 워킹 디렉토리에는 남아 있지만, Git의 추적에서는 제거됩니다.
    .env는 루트 디렉토리에 있기 때문에 .env라고 작성했지만 특정 디렉토리의 파일을 제거하고 싶다면 경로까지 작성해야합니다.
  • --ignore-unmatch: 만약 특정 커밋에 .env 파일이 존재하지 않는 경우, 에러 없이 무시하고 계속 진행하게 하는 옵션입니다. 즉, 이 플래그가 없으면 .env 파일이 없는 커밋에서 Git이 에러를 발생시킬 수 있습니다.

4. --prune-empty

이 옵션은 .env 파일만 존재하는 커밋이 삭제되고 나서 빈 커밋이 남을 경우, 그 빈 커밋을 제거합니다. 예를 들어, 어떤 커밋이 오직 .env 파일만을 포함하고 있다면, 그 파일이 제거된 후에는 커밋이 비어 있을 수 있습니다. 이 경우 해당 커밋을 히스토리에서 완전히 삭제하여 불필요한 빈 커밋이 남지 않도록 합니다.

5. --tag-name-filter cat

Git에서는 브랜치뿐만 아니라 태그도 커밋에 붙습니다. 이 옵션은 모든 태그를 재작업하여 히스토리에서 수정된 커밋에 대응하도록 합니다.

  • cat은 태그 이름을 그대로 유지하면서 태그가 붙은 커밋들이 새롭게 필터링된 브랜치로 재작업되도록 합니다. 이 옵션이 없으면 태그가 있는 커밋은 수정되지 않은 채 남아 있을 수 있습니다.

6. -- --all

이 옵션은 모든 브랜치와 태그를 대상으로 필터링 작업을 수행하게 합니다. 기본적으로 git filter-branch는 현재 체크아웃된 브랜치에만 적용됩니다. 하지만 -- --all을 추가하면, 저장소 내의 모든 브랜치태그에 대해 이 작업이 적용되도록 합니다. 이로 인해 저장소에 있는 모든 브랜치에서 .env 파일이 제거됩니다.

 

이 명령어를 실행한 뒤에 강제로 push 해주면 됩니다!

git push --force --all

 

.

.

.

 

마치며

Git은 정말 파고 파도 끝이 없는 것 같습니다. 기본 명령어들만 알아도 플젝할 때 무리 없을 줄 알았는데 성실하게 공부하겠습니다..

'Git' 카테고리의 다른 글

[Git] 로컬에서 삭제한 파일 스테이징하기  (0) 2024.10.20