git로 만든 큰 .pack 파일을 제거합니다.
저는 많은 파일을 분기에 체크인하고 병합한 다음 제거해야 했고 이제 제거하는 방법을 모르는 큰 .pack 파일이 남아 있습니다.
다음을 사용하여 모든 파일을 삭제했습니다.git rm -rf xxxxxx
그리고 나는 또한 실행했습니다.--cached
옵션도 마찬가지입니다.
현재 다음 디렉터리에 있는 큰 .pack 파일을 제거하는 방법을 누가 알려줄 수 있습니까?
.git/objects/pack/pack-xxxxxxxxxxxxxxxxx.pack
제가 아직 가지고 있지만 더 이상 사용하지 않는 브랜치만 제거하면 됩니까?아니면 제가 뛰어야 할 다른 것이 있나요?
얼마나 차이가 나는지는 모르겠지만 파일에 대한 자물쇠가 표시됩니다.
감사해요.
편집
다음은 mybash_history에서 발췌한 내용으로, 어떻게 이 상태가 되었는지 알 수 있습니다(이 시점에서 'my-branch'라는 git 브랜치에서 작업하고 있으며 더 많은 폴더/파일이 들어 있는 폴더가 있다고 가정합니다).
git add .
git commit -m "Adding my branch changes to master"
git checkout master
git merge my-branch
git rm -rf unwanted_folder/
rm -rf unwanted_folder/ (not sure why I ran this as well but I did)
나도 다음을 실행했다고 생각했는데 다른 것들과 함께 bash_history에 나타나지 않습니다.
git rm -rf --cached unwanted_folder/
는 또한 명령을 했습니다.git gc
팩 않습니다 를 참조하십시오.
문제는 파일을 제거했음에도 불구하고 이전 버전에 파일이 여전히 존재한다는 것입니다.그것이 바로 git의 요점입니다. 당신이 무언가를 삭제하더라도, 당신은 여전히 기록에 접근함으로써 그것을 되찾을 수 있다는 것입니다.
있는 역사를 것이라고 , 은 역사를 다시 쓰는 것과 이 있습니다.git filter-branch
지휘권
GitHub은 그들의 사이트에 그 문제에 대한 좋은 설명을 가지고 있습니다.https://help.github.com/articles/remove-sensitive-data
더 직접적으로 , 이 기본적으로 해야 할 다가 있는 이 입니다.unwanted_filename_or_folder
그에 따라 교체:
git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch unwanted_filename_or_folder' --prune-empty
이렇게 하면 레포의 활성 기록에서 파일에 대한 모든 참조가 제거됩니다.
다음 단계에서는 GC 주기를 수행하여 파일에 대한 모든 참조가 만료되고 팩 파일에서 제거되도록 합니다.이 명령에서는 아무것도 바꿀 필요가 없습니다.
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
# or, for older git versions (e.g. 1.8.3.1) which don't support --stdin
# git update-ref $(git for-each-ref --format='delete %(refname)' refs/original)
git reflog expire --expire=now --all
git gc --aggressive --prune=now
시나리오 A: 대용량 파일이 분기에만 추가된 경우 실행할 필요가 없습니다.git filter-branch
분기를 삭제하고 가비지 수집을 실행하기만 하면 됩니다.
git branch -D mybranch
git reflog expire --expire-unreachable=all --all
git gc --prune=all
시나리오 B: 그러나 bash 기록에 따르면 변경 사항을 마스터에 병합한 것 같습니다.변경사항을 다른 사용자와 공유하지 않은 경우(아니오)git push
가장 쉬운 방법은 큰 파일이 있는 분기와 병합하기 전으로 마스터를 재설정하는 것입니다.이렇게 하면 분기에서 모든 커밋이 제거되고 병합 후 마스터에 대해 수행되는 모든 커밋이 제거됩니다.따라서 대용량 파일 외에도 실제로 필요한 변경 사항이 손실될 수 있습니다.
git checkout master
git log # Find the commit hash just before the merge
git reset --hard <commit hash>
그런 다음 시나리오 A의 단계를 실행합니다.
시나리오 C: 병합 후에 분기에서 다른 변경 사항이 있거나 마스터에서 유지하려는 변경 사항이 있는 경우 마스터를 기본 재배치하고 원하는 커밋을 선택적으로 포함하는 것이 가장 좋습니다.
git checkout master
git log # Find the commit hash just before the merge
git rebase -i <commit hash>
편집기에서 큰 파일을 추가한 커밋에 해당하는 행은 제거하고 나머지는 그대로 둡니다.저장하고 종료합니다.마스터 분기에는 원하는 항목만 포함되어야 하며 큰 파일은 포함되지 않아야 합니다.:git rebase
없이-p
커밋이 합병커밋선대남다기습니록형이한 뒤에 남게 .<commit hash>
이것은 아마도 당신에게 괜찮겠지만, 만약 그렇지 않다면, 당신은 시도할 수 있습니다.-p
,그렇지만git help rebase
말한다combining -p with the -i option explicitly is generally not a good idea unless you know what you are doing
.
그런 다음 시나리오 A의 명령을 실행합니다.
명령을 하여 " " " 를 대체합니다. 대체PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
파일 이름뿐만 아니라 제거할 파일의 경로를 사용합니다.이러한 인수는 다음과 같습니다.
- Git가 모든 분기 및 태그의 전체 기록을 처리하지만 체크아웃하지 않도록 합니다.
- 지정한 파일과 결과적으로 생성된 빈 커밋을 제거합니다.
- 기존 태그 덮어쓰기
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
그러면 레포의 활성 기록에서 파일에 대한 모든 참조가 강제로 제거됩니다.
다음 단계에서는 GC 주기를 수행하여 파일에 대한 모든 참조가 만료되고 팩 파일에서 제거되도록 합니다.이 명령에서는 아무것도 바꿀 필요가 없습니다.
git update-ref -d refs/original/refs/remotes/origin/master
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --aggressive --prune=now
loganfsmyth가 답변에서 이미 언급했듯이, repo에서 파일을 삭제한 후에도 git history는 계속 존재하기 때문에 삭제해야 합니다.공식 GitHub 문서는 BFG를 추천하는데, BFG는 사용하기가 더 쉽다고 생각합니다.filter-branch
:
기록에서 파일 삭제
웹 사이트에서 BFG를 다운로드합니다.Java가 설치되어 있는지 확인한 다음 미러 복제 및 삭제 기록을 만듭니다.교체해야 합니다.YOUR_FILE_NAME
삭제할 파일의 이름을 지정합니다.
git clone --mirror git://example.com/some-big-repo.git
java -jar bfg.jar --delete-files YOUR_FILE_NAME some-big-repo.git
cd some-big-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push
폴더 삭제
위와동만사용을 합니다.--delete-folders
java -jar bfg.jar --delete-folders YOUR_FOLDER_NAME some-big-repo.git
기타 옵션
BFG는 또한 다음과 같은 고급 옵션(문서 참조)을 허용합니다.
기록에서 100M보다 큰 모든 파일 제거:
java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git
중요한!
BFG를 실행할 때는 두 가지 모두를 주의해야 합니다.YOUR_FILE_NAME
그리고.YOUR_FOLDER_NAME
파일/폴더 이름일 뿐입니다.그들은 길이 아니기 때문에, 뭐 그런 것처럼.foo/bar.jpg
작동하지 않습니다!대신 지정된 이름의 모든 파일/폴더가 존재하는 경로나 분기에 관계없이 복원 기록에서 제거됩니다.
한 가지 옵션:
려달을 git gc
수동으로 여러 개의 팩 파일을 하나 또는 몇 개의 팩 파일로 압축합니다.이 큰 팩 동작을 함) 를 압축하는 할 수 .git gc --aggressive
하고 이 코드를 하여 새 (".git .git" .git" .git " .git" .git " .git")를 입니다.git init
).
쇼에 조금 늦었지만 위의 답변이 질문을 해결하지 못했을 경우 다른 방법을 찾았습니다..pack에서 특정 대용량 파일을 제거하기만 하면 됩니다.실수로 2GB 용량의 대용량 파일을 체크인하는 문제가 발생했습니다.다음 링크에 설명된 단계를 수행했습니다. http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/
이는 GitHub에서 권장하는 BFG를 사용하는 것으로, @Timo의 답변과 동일하지만 CLI 옵션을 살펴보는데 시간을 할애했기 때문에 약간의 차이가 있습니다.
예를 들어, 제가 이미지들을 아래로 밀었다고 칩시다.60MB
오래 전에 약속을 취소할 수 없습니다. 다음과 같은 할 것입니다.
java -jar /jarfiles/bfg-1.14.0.jar --delete-files '*.{png,jpg,JPG,PNG}'
그런 다음 다음 다음 명령을 실행해야 한다는 제안을 받습니다.
git reflog expire --expire=now --all && git gc --prune=now --aggressive
마지막으로 원격에 대한 변경 사항을 다음과 동기화합니다.
git push --force
다음과 같이 팩 파일 크기가 감소했는지 확인할 수 있습니다.
du -sh ./
언급URL : https://stackoverflow.com/questions/11050265/remove-large-pack-file-created-by-git
'sourcecode' 카테고리의 다른 글
Angular 2 퀵스타트 404 GET /app/main.js (0) | 2023.07.03 |
---|---|
postgresql - 텍스트 필드 내 문자열의 모든 인스턴스를 바꿉니다. (0) | 2023.07.03 |
tight_()layout는 피규어 서브타이틀을 고려하지 않습니다. (0) | 2023.07.03 |
스프링 부트: java.awt.헤드리스예외. (0) | 2023.07.03 |
Git 버전 제어의 패치란 무엇입니까? (0) | 2023.07.03 |