programing

내 Git 저장소에서 참조되지 않은 블랍을 제거하는 방법

jooyons 2023. 9. 12. 20:00
반응형

내 Git 저장소에서 참조되지 않은 블랍을 제거하는 방법

저는 마스터와 릴리즈의 두 가지 지점을 가진 GitHub 저장소를 가지고 있습니다.

릴리스 브랜치에는 매우 큰 저장소 크기(250MB 이상)에 기여하는 바이너리 배포 파일이 포함되어 있어 정리를 결정했습니다.

를 통해 원격 릴리즈 브랜치를 삭제했습니다.git push origin :release.

그런 다음 로컬 릴리즈 브랜치를 삭제했습니다.처음엔 해봤어요git branch -d release, 하지만 깃은 "오류: '해제'라는 가지는 당신의 현재 머리의 조상이 아닙니다."라고 말한 것이 사실입니다.git branch -D release삭제할 수 있습니다.

하지만 로컬과 GitHub 모두에서 제 저장소 크기는 여전히 컸습니다.명령 , 를 들면 Git령을요면를인서,면를,o요령을,ehftn인e서isgit gc --prune=today --aggressive

SO 1029969에서 Charles Bailey의 지시를 따라서 가장 큰 블롭에 대한 SHA-1 해시 목록을 얻을 수 있었습니다.SO 460331의 대본을 이용해 블롭을 찾아냈습니다...가장 큰 다섯 개는 존재하지 않지만 작은 방울들이 발견되기 때문에 대본이 작동하는 것으로 알고 있습니다.

이 블로그들은 릴리즈 브랜치에서 나온 바이너리들인 것 같은데, 브랜치 삭제 이후 어떻게 된 일인지는 알 수 없습니다.그들을 제거하는 올바른 방법은 무엇입니까?

이 유용한 명령어 "git-gc-all"을 제시합니다. 추가 구성 변수가 나올 때까지 모든 Git 가비지를 제거할 수 있습니다.

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 \
    -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc

다음과 같은 작업을 먼저 실행해야 할 수도 있습니다.

git remote rm origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ |
    xargs -n1 --no-run-if-empty git update-ref -d

일부 태그를 제거해야 할 수도 있습니다.

git tag | xargs git tag -d

답변의 자세한 내용과 같이 replog에서만 참조되는 모든 내용을 영구적으로 제거할 수 있습니다.

경고: 보관하려는 개체가 많이 제거됩니다.

  • 당신의 모든 은닉물들.
  • 현재 분기에 이전 기록이 없습니다.

설명서를 읽고 원하는 내용인지 확인합니다.

을(를) 만료하려면 과 같이 하십시오.reflog , 를 을 을 를

git reflog expire --expire-unreachable=now --all
git gc --prune=now

git reflog expire --expire-unreachable=now --all할수는의를두다두다neselesf할수는의>reflog.

git gc --prune=now커밋 자체를 제거합니다.

주의:사용만 가능git gc --prune=now해당 커밋은 리로그에서 계속 참조되므로 작동하지 않습니다.따라서 reflog를 삭제해야 합니다.또한 다음을 사용하는 경우rerere이 명령에 의해 삭제되지 않은 추가 참조가 있습니다. 참조하십시오.git help rerere 또한 원격 은 깃에 의해.또한 로컬 또는 원격 지점 또는 태그에서 참조하는 모든 커밋은 git에 의해 귀중한 데이터로 간주되므로 제거되지 않습니다.

SO답안에 언급된 바와 같이,git gc실제로 레포의 크기를 늘릴 수 있습니다!

이 스레드도 참조

이제 git에는 참조되지 않은 개체를 실행할 때 바로 삭제하지 않는 안전 메커니즘이 있습니다.git gc'.
기본적으로 참조되지 않은 개체는 2주 동안 주변에 보관됩니다.는 실수로 , 가 '지켜야 한다'는의미로 될 수 있는 입니다.git gc으로 실행됩니다 입니다.

따라서 포장되었지만 참조되지 않은 물체에 유예 기간을 주기 위해 재포장 프로세스는 참조되지 않은 물체를 포장 밖으로 밀어내어 노화되고 결국에는 가지치기 할 수 있습니다.
하지만 참조되지 않는 물체는 보통 그렇게 많지 않습니다.되지 않은 를 갖는 이며, 해당 대역폭을 낭비하는 입니다.404855개의 개체를 복제하는 것은 어리석은 일이며, 네트워크 대역폭을 낭비하는 것입니다.

아무튼...당신의 문제를 해결하기 위해서 당신은 단지 실행하기만 하면 됩니다.git gc'와 --prune=now해당 유예 기간을 비활성화하고 참조되지 않은 개체를 즉시 제거하기 위한 인수(워크스테이션에서 쉽게 확인할 수 있는 다른 git 활동이 동시에 발생하지 않는 경우에만 안전)

그리고 그건 그렇고, '을 사용하는 것.git gc --aggressive 버전' ' 에 git 으로 ( '))과 함께.git repack -a -f -d --window=250 --depth=250')

동일한 스레드에서 다음을 언급합니다.

 git config pack.deltaCacheSize 1

이는 델타 캐시 크기를 무제한을 의미하는 기본값 0이 아닌 1바이트로 제한합니다.를해의여를시릴수다을e수릴hstkgpotiem를'e해시의를여을egit repack의 스레드를 사용하는 GB의 RAM을 사용하고 4개의 스레드를 사용하는 x86-64 시스템에서 명령을 수행합니다(이것은 쿼드 코어입니다).은 거의 3가 3.3으로 합니다하지만 GB.

컴퓨터가 SMP이고 RAM이 충분하지 않으면 스레드 수를 1개로 줄일 수 있습니다.

git config pack.threads 1

으로, 은 을 할 할 으로 은 을 --window-memory argumentgit repack'.
를 들어,어를 사용하면,--window-memory=128M파일이 일치가 덜될 수 검색 .repo량이이어는우의타가될수다타색만리에해야인을에d다야을인해에리phpd색yehssopaneftosh타량l .


필터-브랜치 전선에서는 이 스크립트를 신중하게 고려할 수 있습니다.

#!/bin/bash
set -o errexit

# Author: David Underhill
# Script to permanently delete files/folders from your git repository.  To use 
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2

if [ $# -eq 0 ]; then
    exit 0
fi

# make sure we're at the root of git repo
if [ ! -d .git ]; then
    echo "Error: must run this script from the root of a git repository"
    exit 1
fi

# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD

# remove the temporary history git-filter-branch otherwise leaves behind for a long time
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune

git gc --prune=now, 아니면 낮은 수준git prune --expire now.

헤드가 움직일 때마다 깃이 추적해요reflog커밋을에에 "commits. "dangling commits"는 "dangling commits"입니다.reflog④ 실수로 커밋할 때의 실수로 커밋을 삭제할 때의 안전망입니다.

사용할 수 있습니다.git reflog특정 커밋, 리팩 등을 제거하는 명령 또는 상위 레벨 명령만 수행합니다.

git gc --prune=now

git filter-branch그리고.git gc, 저장소에 있는 태그를 검토해야 합니다.지속적인 통합 및 배포같은 것들에 대한 자동 태그를 가진 실제 시스템은 원하지 않는 객체가 여전히 이러한 태그에 의해 참조되도록 만들 것입니다. 따라서gc제거할 수 없고 저장소의 크기가 여전히 큰 이유가 무엇인지 계속 궁금할 것입니다.

모든 원치 않는 것들을 없애는 가장 좋은 방법은 달리는 것입니다.git-filter&git gc그런 다음 마스터를 새 베어 저장소로 밀어 넣습니다.새 베어 저장소에 정리된 트리가 표시됩니다.

을 사용할 수 .git forget-blob.

사용법은 매우 간단합니다.

git forget-blob file-to-forget

Git 저장소에서 'git forget-blob'으로 파일을 완전히 제거하기에서 더 많은 정보를 얻을 수 있습니다.

기록의 모든 커밋, 리로그, 태그 등에서 사라집니다.

저는 가끔 같은 문제에 부딪치고, 매번 이 게시물과 다른 사람들에게 돌아와야 합니다.그래서 프로세스를 자동화했습니다.

공로는 샘 왓킨스와 같은 기고자들에게 돌아갑니다.

때때로 "gc"가 큰 도움이 되지 않는 이유는 오래된 커밋에 기반한 미완성 리베이스 또는 은닉이 있기 때문입니다.

git-filter-branch를 사용해 보십시오. 큰 blob을 제거하지는 않지만 전체 저장소에서 지정한 큰 파일을 제거할 수 있습니다.저는 저장소 크기를 수백 MB에서 12 MB로 줄였습니다.

다른 팁을 추가하려면 git gc를 사용하기 전에 git 원격 가지치기를 사용하여 원격지의 오래된 가지를 삭제하는 것을 잊지 마십시오.

git branch로 보실 수 있습니다 -a

GitHub에서 가져온 저장소를 포크할 때 유용한 경우가 많습니다.

다음과 같은 요지에서 접근을 시도해 보십시오.

git gc --prune="0 days"

언급URL : https://stackoverflow.com/questions/1904860/how-to-remove-unreferenced-blobs-from-my-git-repository

반응형