Git 저장소 및 GitHub의 원격에서 파일을 완전히 제거


78

실수로 이미지 폴더를 추가하고 커밋했습니다. 그런 다음 한 번 더 커밋했습니다. 그런 다음 사용하여 해당 파일을 제거 git rm -f ./images하고 다시 커밋했습니다.

지금은 그 브랜치 (마스터)에서 더 많은 커밋을했습니다. 내 HEAD에는 해당 ./static/images폴더 가 없습니다 .

이로 인해 내 저장소 크기가 많이 증가했습니다. 이러한 Blob을 완전히 제거하려면 어떻게해야합니까? 그리고 내 원격 GitHub 리포지토리에서도 제거하고 싶습니다.


어떤 이유로 github 이하의 지침이 저에게 효과가 없었지만 'Pro Git'책 의이 답변 과이 SO 답변에서 참조 된이 완벽하게 작동했습니다. stackoverflow.com/a/16877548/436014- 궁금합니다. 이제 트리 필터와 인덱스 필터의 차이점에 대해 알아 보겠습니다.
waffl

답변:


125

이것은 당신이 찾고있는 것입니다. 무시해도 파일이 제거되지 않습니다 . 해당 페이지를 읽는 것이 좋지만 다음은 사용할 특정 명령입니다.

git filter-branch --index-filter \
'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

또한 git이 생성 한 캐시에서 삭제 된 모든 파일을 제거하려면 다음을 사용하십시오.

rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune

마지막 명령에 대한 자세한 정보와 한 번의 작업으로 원하는 모든 작업을 수행하는 스크립트는 여기에서 찾을 수 있습니다. git : forever remove files or folders from history .

많은 설명이있는 또 다른 링크 : 민감한 데이터 제거 .

[편집] 또한이 StackOverflow 질문 : Git 기록에서 민감한 파일 및 커밋 제거를 참조하세요 .

( natacado위 링크 된 질문의의 답변에서 복사 한 명령 .) 작업 복사본에서 파일을 이미 제거했다면 다음이 작동합니다. 원하지 않는 파일을 추가 한 커밋의 해시를 찾습니다. 다음을 수행하십시오.

git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force

1
'git rm --cached <file>'을하라고하셨습니다. 하지만 지금 당장은 "./statis/images"폴더가 없어서 프로젝트에서 훨씬 앞서 있습니다. 그 후에도 많은 커밋을했습니다.
Abhijeet Rastogi 2011

1
@shadyabhi 흠, rm 명령에 --ignore-unmatch를 추가해보십시오. 작동하는지 알려주세요.
Darhuuk 2011

@Darhuuk 나는 당신이 말한 것을했습니다. "rm ..."이라는 많은 출력이 있습니다. $ git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch ./static/images'HEAD 다음 $ rm -rf .git / refs / original / && git reflog expire- -all && git gc --aggressive --prune. 여전히 내 저장소 크기는 2.7MB입니다. 내 소스는 525KB에 불과합니다. 내 커밋은 118 개에 불과합니다. 변경 사항이 적기 때문에 꽤 큽니다.
Abhijeet Rastogi 2011

@shadyabhi 내가 링크 한 다른 StackOverflow 질문에서 해결책을 시도해 보셨습니까?
Darhuuk 2011

@Darhuuk 리베이스를 사용해야합니까? 나는이 모든 것에 대한 초보자 일 뿐이므로 정확히 따르지는 않습니다.
Abhijeet Rastogi 2011

9

전체 브랜치를 리베이스하고 이미지를 추가 한 커밋과 이미지를 제거한 커밋을 모두 제거 할 수 있습니다.

git rebase -i master

커밋 목록이 표시됩니다. 제거하려는 불량 커밋이있는 줄을 삭제합니다. ( "dd"는 기본 편집기 인 vim에서 한 줄을 삭제합니다. 그런 다음 ZZ로 저장)

매달린 커밋은 자연 git 가비지 수집 과정에서 정리되며 Darhuuk의 답변에 주어진 명령으로 강제 할 수 있습니다.

편집 : 원격 저장소에 푸시 한 경우에도 작동하지만 --force로 푸시해야합니다. (똑같이 git filter-branch 솔루션에 적용됩니다).

이것은 당신의 지점에서 뽑은 모든 사람들에게 매우 성 가실 것입니다. 그들은 "업스트림 리베이스에서 복구" 를 참조해야합니다 .


아마도 원래 실수로 이미지를 추가 한 것은 유지하려는 커밋의 일부일 것입니다. 이 경우 유지하려는 부분을 분할하기 위해 리베이스 중에 커밋을 편집해야합니다. 해당 커밋에 대한 "rebase -i"목록의 "pick"을 "e"(편집 용)로 바꾸면됩니다. 리베이스 프로세스는 여기서 중지되며 "git commit --amend"를 사용하여 커밋을 분할 할 수 있습니다.


4

나는 본질적 으로이 Windows 형식 경고 와 결합 된 대답을 반복 하고 있으므로 주석으로 손실되지 않습니다.

문자열을 구문 분석하는 방법을 사용하는 셸에 따라 다르기 때문에 작은 따옴표 대신 큰 따옴표를 사용합니다.

한 줄:

git filter-branch --index-filter "git rm -r --cached --ignore-unmatch <file/dir>" HEAD

여러 줄 :

git filter-branch --index-filter \
    "git rm -r --cached --ignore-unmatch <file/dir>" HEAD
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.