Git 기록에서 파일을 제거하는 방법은 무엇입니까?


91

얼마 전에 비공개 여야하는 정보 (파일)를 추가했습니다. 프로젝트에서 제거하는 것은 문제가되지 않지만 git기록 에서도 제거해야합니다 .

Git과 Github (개인 계정)를 사용합니다.

참고 : 이 스레드에서 유사한 내용이 표시되지만 여기에는 기능 브랜치에 추가 된 이전 파일이 있습니다. 해당 브랜치는 개발 브랜치에 병합되고 마지막으로 마스터에 병합 되었기 때문에 많은 변경이 이루어졌습니다. 따라서 동일하지 않으며 필요한 것은 기록을 변경하고 개인 정보 보호를 위해 해당 파일을 숨기는 것입니다.


3
역사를 다시 써야 할 것입니다. 예를 들어 git rebase다음git push -f
코리 크레이머


filter-branch제안 중복 된 설명 방법은 당신이 원하는 것을 할 것입니다.
1615903

또한 사용하는 것보다 빠를 수있는 BFG 를 가리키는 stackoverflow.com/a/17890278git filter-branch
Hasturkun

하지만 더 빨리 가서 똑같이하고 자바를 사용해야합니다. @Hasturkun
Marcos R. Guevara

답변:


114

이 답변을 찾았으며 도움이되었습니다.

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch path_to_file" HEAD

여기에서 찾았습니다 https://myopswork.com/how-remove-files-completely-from-git-repository-history-47ed3e0c4c35


5
경고 : 이로 인해 많은 커밋이 생성되고 차이가 발생합니다. 강제로 밀어야하는데 너무 무서웠어요.
sudo

1
@sudo가 말한 것을 두 번째로했지만 실수로 맡은 신선한 지점에서 작동 .env했습니다. 빠르고 정확한 솔루션.
Joe Scotto

1
사실, 간단한 힘 푸시가 작동합니다! 나도 무서웠지만 모든 것을 백업했습니다.
wutBruh

1
마지막 인수로 커밋 범위를 지정할 수도 있습니다. 문제의 커밋이 최근 인 경우 수행 <previous_hash>..HEAD하고 시간을 절약하십시오.
Victor Sergienko

이 후 그것은 나에게만 작동합니다git push --force
Sebastian Schmal

48

최근에 해당 파일을 커밋했거나 해당 파일이 하나 또는 두 개의 커밋에서 변경된 경우 해당 커밋을 사용 rebase하고 cherrypick제거하는 것이 좋습니다 .

그렇지 않으면 전체 기록을 다시 작성해야합니다.

git filter-branch --tree-filter 'rm -f <path_to_file>' HEAD

변경 사항에 만족하고 모든 것이 정상적으로 보이도록 정당하게 확인한 경우 모든 원격 지점을 업데이트해야합니다.

git push origin --force --all

참고 :-복잡한 작업이며 수행중인 작업을 알고 있어야합니다. 먼저 데모 저장소에서 어떻게 작동하는지 확인하십시오. 또한 다른 개발자에게 그동안 변경 사항이 없도록 알려야합니다.


전체 기록을 다시 작성한 후 저장소 (github)에 변경 사항을 유지하려면 어떻게해야합니까?
Marcos R. Guevara

감사합니다. 기다릴 것입니다. 데모 저장소로 시도해 보겠습니다. 여기에서 모든 작업이 완료된 상태로 업데이트하겠습니다.
Marcos R. Guevara

실수로 --all. 이제 두 인수로 푸시를 다시 실행할 때마다 모든 최신 정보가 표시됩니다. 그리고 파일은 다른 분기에서 제거되지 않습니다. 이제 어떻게해야합니까?
Reeshabh 란잔

귀하의 제안이 @PetroFranko의 답변 에서처럼 --tree-filter대신 사용되는 이유는 무엇 --index-filter입니까?
einpoklum

14
  • 파일을 제거하고 제거 된 파일로 수행 한 커밋에서 기록을 다시 작성합니다 (커밋 한 파일에서 새 커밋 해시가 생성됨).

    git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' --prune-empty --tag-name-filter cat -- --all

  • 이제 repo를 강제로 푸시하십시오.

    git push origin --force --all

  • 이제 공동 작업자에게 rebase.



7
  • 우선, .gitignore파일에 추가하고 파일을 커밋하는 것을 잊지 마십시오 :-)
  • 이 사이트를 사용할 수 있습니다 : http://gtiignore.io 를 생성하고 .gitignore바이너리 파일 / 폴더에 필요한 경로를 추가합니다.

  • 파일을 추가하면 .gitignoreBFG를 사용하여 "이전"바이너리 파일을 제거 할 수 있습니다.


How to remove big files from the repository

git filter-branch또는 BFG 를 사용할 수 있습니다 . https://rtyley.github.io/bfg-repo-cleaner/

BFG Repo-Cleaner

git-filter-branch의 대안.

BFG는 Git 저장소 기록에서 잘못된 데이터 를 정리하기 위해 git-filter-branch에 대한 더 간단하고 빠른 대안입니다 .

* 미친 큰 파일
제거 * * 암호, 자격 증명 및 기타 개인 데이터 제거

예 (공식 사이트에서)

이 모든 예에서 bfg는 java -jar bfg.jar의 별명입니다.

# Delete all files named 'id_rsa' or 'id_dsa' :
bfg --delete-files id_{dsa,rsa}  my-repo.git

여기에 이미지 설명 입력


6

나는 이 GitHub 기사를 읽었 으며 다음 명령으로 이어졌습니다 (허용되는 답변과 비슷하지만 조금 더 강력합니다).

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" --prune-empty --tag-name-filter cat -- --all

4

git-repo-filter

gitgit-filter-repo 사용을 권장합니다 ( git filter-branch명령이 실행될 때 ). 다른 대안 ( https://github.com/newren/git-filter-repo#why-filter-repo-instead-of-other-alternatives ) 보다 나은 이유에 대한 긴 목록 이 있습니다. 매우 간단하고 빠릅니다.

이 명령은 모든 분기의 모든 커밋에서 파일을 제거합니다.

git filter-repo --path <path to the file or directory> --invert-paths

여러 --path매개 변수 를 사용하여 여러 경로를 지정할 수 있습니다 . 여기에서 자세한 문서를 찾을 수 있습니다 : https://www.mankier.com/1/git-filter-repo

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.