developer tip

Git 저장소 (기록)에서 파일 제거

copycodes 2020. 10. 17. 10:40
반응형

Git 저장소 (기록)에서 파일 제거


(해결됨, 질문 본문 하단 참조)
오랫동안 이것을 찾고 지금까지 내가 가진 것은 다음과 같습니다.

거의 같은 방법이지만 둘 다 팩 파일에 개체를 남깁니다.
내가 시도한 것 :

git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name'
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc

팩에 여전히 파일이 있으며 이것이 내가 아는 방법입니다.

git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3

이:

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune

똑같다...

git clone트릭을 시도 했지만 일부 파일 (최대 3000 개)을 제거했지만 여전히 가장 큰 파일이 있습니다.

리포지토리에 200M 정도의 큰 레거시 파일이 있지만 실제로는 원하지 않습니다 ... 그리고 리포지토리를 0으로 재설정하고 싶지 않습니다.

솔루션 : 다음은 파일을 제거하는 가장 짧은 방법입니다.

  1. .git / packed-refs 확인-내 문제는 refs/remotes/origin/master원격 저장소에 대한 줄 이 있다는 것입니다. 삭제하지 않으면 git이 해당 파일을 제거하지 않습니다.
  2. (선택 사항) git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5 -가장 큰 파일을 확인합니다.
  3. (선택 사항) git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98 -해당 파일이 무엇인지 확인
  4. git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names' -모든 개정판에서 파일 제거
  5. rm -rf .git/refs/original/ -자식의 백업을 제거하려면
  6. git reflog expire --all --expire='0 days' -모든 느슨한 개체를 만료
  7. git fsck --full --unreachable -느슨한 물체가 있는지 확인하기 위해
  8. git repack -A -d -재 포장
  9. git prune -마지막으로 해당 개체를 제거하려면

리포지토리 데이터에 액세스하지 않고는 확실히 말할 수는 없지만 실행하기 전에 이전 커밋을 참조하는 패킹 된 참조가 하나 이상있을 것입니다 git filter-branch. 이것은 git fsck --full --unreachablereflog를 만료하고 원래 (압축되지 않은) 참조를 제거 했음에도 불구하고 큰 blob을 도달 할 수없는 객체라고 부르지 않는 이유를 설명 합니다.

내가 할 일은 다음과 같습니다 (이후 git filter-branchgit gc완료) :

1) 원본 참조가 없어 졌는지 확인하십시오.

rm -rf .git/refs/original

2) 모든 리플 로그 항목 만료 :

git reflog expire --all --expire='0 days'

3) 오래된 포장 된 심판 확인

얼마나 많은 포장 된 참조가 있는지에 따라 이것은 잠재적으로 까다로울 수 있습니다. 이 작업을 자동화하는 Git 명령을 모르기 때문에 수동으로 수행해야한다고 생각합니다. 의 백업을 만듭니다 .git/packed-refs. 이제 편집하십시오 .git/packed-refs. 이전 참조를 확인합니다 (특히에서 참조를 포장했는지 확인 .git/refs/original). 거기에있을 필요가없는 오래된 것을 찾으면 삭제하십시오 (해당 참조에 대한 줄 제거).

packed-refs파일 정리를 마친 후 git fsck연결할 수없는 개체가 있는지 확인 합니다.

git fsck --full --unreachable

작동하고 git fsck이제 큰 Blob에 연결할 수없는 것으로보고하면 다음 단계로 이동할 수 있습니다.

4) 압축 된 아카이브 재 포장

git repack -A -d

이렇게하면 도달 할 수없는 개체가 압축 해제되고 압축 해제 상태로 유지 됩니다.

5) 느슨한 (접근 할 수없는) 개체 정리

git prune

그리고 그렇게해야합니다. Git에는 패킹 된 참조를 관리하는 더 나은 방법이 있어야합니다. 내가 모르는 더 좋은 방법이있을 수 있습니다. 더 나은 방법이 없으면 packed-refs파일을 수동으로 편집하는 것이 유일한 방법 일 수 있습니다.


Git 히스토리에서 파일을 다시 쓰기 위해 특별히 설계된 것보다 더 간단하고 빠른 대안 인 BFG Repo-Cleaner를 사용하는 것이 좋습니다 git-filter-branch. 여기서 삶을 더 쉽게 만드는 한 가지 방법은 기본적으로 모든 참조 (모든 태그, 브랜치, refs / remotes / origin / master 등)를 실제로 처리 하지만 10-50 배 더 빠르다 것입니다.

You should carefully follow these steps here: http://rtyley.github.com/bfg-repo-cleaner/#usage - but the core bit is just this: download the BFG's jar (requires Java 6 or above) and run this command:

$ java -jar bfg.jar  --delete-files file_name  my-repo.git

Any file named file_name (that isn't in your latest commit) will be will be totally removed from your repository's history. You can then use git gc to clean away the dead data:

$ git gc --prune=now --aggressive

The BFG is generally much simpler to use than git-filter-branch - the options are tailored around these two common use-cases:

  • Removing Crazy Big Files
  • Removing Passwords, Credentials & other Private data

Full disclosure: I'm the author of the BFG Repo-Cleaner.


I found this to be quite helpful with regards to removing a whole folder as the above didn't really help me: https://help.github.com/articles/remove-sensitive-data.

I used:

git filter-branch -f --force \
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \
--prune-empty --tag-name-filter cat -- --all

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now

I was trying to get rid of a big file in the history, and the above answers worked, up to a point. The point is: they don't work if you have tags. If the commit containing the big file is reachable from a tag, then you would need to adjust the filter-branches command thusly:

git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags

See: How do I remove sensitive files from git’s history

The above will fail if the file does not exist in a rev. In that case, the '--ignore-unmatch' switch will fix it:

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD

Then, to get all loose objects out of the repostiry:

git gc --prune='0 days ago'

You have various reasons for a still large git repo size after git gc, since it does not remove all loose objects.

I detail those reasons in "reduce the git repository size"

But one trick to test in your case would be to clone your "cleaned" Git repo and see if the clone has the appropriate size.

(' "cleaned" repo ' being the one where you did apply the filter-branch, and then gc and prune)


This should be covered by the git obliterate command in Git Extras (https://github.com/visionmedia/git-extras).

git obliterate <filename>

I had the same problem and I found a great tutorial on github that explain step by step how to get rid of files you accidentally committed.

Here is a little summary of the procedure as Cupcake suggested.

If you have a file named file_to_remove to remove from the history :

cd path_to_parent_dir

git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch file_to_remove' \
  --prune-empty --tag-name-filter cat -- --all

참고URL : https://stackoverflow.com/questions/2164581/remove-file-from-git-repository-history

반응형