오늘날에는 차이가 없습니다. git gc --aggressive
Linus가 2007 년에 제안한 제안에 따라 작동합니다. 아래를 참조하십시오. 버전 2.11 (2016 년 4 분기)부터 git은 기본적으로 깊이가 50입니다. 크기가 250 인 창은 각 객체의 더 큰 섹션을 스캔하기 때문에 좋지만 250의 깊이는 모든 체인이 매우 오래된 것을 참조하기 때문에 좋지 않습니다. 이는 디스크 사용량을 약간 낮추기 위해 향후 모든 git 작업을 느리게 만듭니다 .
역사적 배경
Linus는 git gc --aggressive
" 정말 나쁜 팩"또는 "정말 끔찍한 델타" 가있을 때만 사용하도록 제안했습니다 (전체 메일 링리스트 게시물은 아래 참조). 그러나 "거의 항상, 다른 경우에는 실제로는 정말 나쁜 것입니다. 해야 할 일." 결과는 시작했을 때보 다 더 나쁜 상태로 저장소를 남길 수도 있습니다!
그가 "길고 복잡한 역사"를 가져온 후이를 제대로 수행하기 위해 제안한 명령은 다음과 같습니다.
git repack -a -d -f --depth=250 --window=250
그러나 이것은 당신이 이미 당신의 저장소 히스토리에서 원치 않는 건크 를 제거 했고 당신이 git filter-branch
문서 에있는 저장소 축소 체크리스트를 따랐다 고 가정합니다 .
git-filter-branch를 사용하여 파일 하위 집합을 제거 할 수 있으며 일반적으로 --index-filter
및 --subdirectory-filter
. 사람들은 결과 리포지토리가 원본보다 작을 것으로 기대하지만 실제로 작게 만들려면 몇 가지 단계가 더 필요합니다. 먼저 다음 사항을 확인하십시오.
그런 다음 더 작은 저장소를 얻는 두 가지 방법이 있습니다. 더 안전한 방법은 원본을 그대로 유지하는 복제하는 것입니다.
- 그것을 복제
git clone file:///path/to/repo
. 복제본에는 제거 된 개체가 없습니다. git-clone을 참조하십시오. (일반 경로로 복제하면 모든 것이 하드 링크됩니다!)
어떤 이유로 든 복제하고 싶지 않다면 대신 다음 사항을 확인하십시오 (이 순서대로). 이것은 매우 파괴적인 접근 방식이므로 백업을 만들거나 복제로 돌아가십시오. 경고를 받았습니다.
git-filter-branch에 의해 백업 된 원본 참조를 제거합니다.
git for-each-ref --format="%(refname)" refs/original/ |
xargs -n 1 git update-ref -d
를 사용하여 모든 리플 로그를 만료합니다 git reflog expire --expire=now --all
.
가비지는 참조되지 않은 모든 객체를 수집합니다 git gc --prune=now
(또는 git gc
에 대한 인수를 지원할만큼 새롭지 않은 --prune
경우 git repack -ad; git prune
대신 사용).
Date: Wed, 5 Dec 2007 22:09:12 -0800 (PST)
From: Linus Torvalds <torvalds at linux-foundation dot org>
To: Daniel Berlin <dberlin at dberlin dot org>
cc: David Miller <davem at davemloft dot net>,
ismail at pardus dot org dot tr,
gcc at gcc dot gnu dot org,
git at vger dot kernel dot org
Subject: Re: Git and GCC
In-Reply-To: <4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
Message-ID: <alpine.LFD.0.9999.0712052132450.13796@woody.linux-foundation.org>
References: <4aca3dc20712051947t5fbbb383ua1727c652eb25d7e@mail.gmail.com>
<20071205.202047.58135920.davem@davemloft.net>
<4aca3dc20712052032n521c344cla07a5df1f2c26cb8@mail.gmail.com>
<20071205.204848.227521641.davem@davemloft.net>
<4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
2007 년 12 월 6 일 목요일에 Daniel Berlin은 다음과 같이 썼습니다.
실제로 git-gc --aggressive
SVN 리포지토리에서 변환했는지 여부에 관계없이 때때로 파일을 압축하는 것은 바보 같은 일을합니다.
물론. git --aggressive
대부분 바보입니다. 이것은 " 정말 나쁜 팩 이 있다는 것을 알고 있으며, 제가 한 모든 나쁜 포장 결정을 버리고 싶습니다. "의 경우에만 유용 합니다.
이를 설명하기 위해 git delta-chain이 어떻게 작동하는지, 그리고 대부분의 다른 시스템과 어떻게 다른지 설명 할 가치가 있습니다 (아마도 알고 있겠지만 기본 사항을 살펴 보겠습니다).
다른 SCM에서는 일반적으로 델타 체인이 고정되어 있습니다. "앞으로"또는 "뒤로"가 될 수 있으며 리포지토리 작업에 따라 약간 씩 발전 할 수 있지만 일반적으로 단일 SCM 엔터티로 표현되는 단일 파일에 대한 일련의 변경 사항입니다. CVS에서는 분명히 *,v
파일이고 다른 많은 시스템이 비슷한 일을합니다.
Git은 또한 델타 체인을 수행하지만 훨씬 더 "느슨하게"수행합니다. 고정 된 개체가 없습니다. 델타는 git이 좋은 델타 후보로 간주하는 임의의 다른 버전에 대해 생성되며 (다양한 상당히 성공적인 휴리스틱으로) 절대적으로 엄격한 그룹화 규칙이 없습니다.
이것은 일반적으로 매우 좋은 것입니다. 다양한 개념적 이유 ( 즉 , git 내부적으로는 전체 개정 체인에 대해 전혀 신경을 쓸 필요조차 없습니다. 델타 측면에서 전혀 생각하지 않습니다).하지만 융통성없는 델타 규칙을 제거하는 것은 의미가 있기 때문에 좋습니다. 예를 들어 git은 두 파일을 병합하는 데 전혀 문제가 없습니다 *,v
. 숨겨진 의미가있는 임의의 "개정 파일" 이 없습니다 .
또한 델타의 선택이 훨씬 더 개방적인 질문임을 의미합니다. 델타 체인을 하나의 파일로 제한하면 델타에 대해 할 일에 대한 선택권이 많지 않지만 git에서는 완전히 다른 문제가 될 수 있습니다.
그리고 이것은 정말로 나쁜 이름 --aggressive
이 들어오는 곳입니다. git은 일반적으로 델타 정보를 재사용하려고 시도하지만 (좋은 생각이고 이전에 찾은 모든 좋은 델타를 다시 찾는 CPU 시간을 낭비하지 않기 때문에) 때때로 당신은 "빈 슬레이트로 다시 시작하고 이전의 모든 델타 정보를 무시하고 새로운 델타 세트를 생성 해 보겠습니다."라고 말하고 싶습니다.
따라서 --aggressive
공격적인 것이 아니라 이전에 이미 결정한 결정을 다시 수행하는 데 CPU 시간을 낭비하는 것입니다!
때때로 그것은 좋은 일입니다. 특히 일부 가져 오기 도구는 정말 끔찍하게 나쁜 델타를 생성 할 수 있습니다. git fast-import
예를 들어 를 사용하는 모든 항목 에는 델타 레이아웃이 많지 않을 수 있으므로 "깨끗한 상태에서 시작하고 싶습니다."라고 말할 가치가있을 수 있습니다.
그러나 거의 항상, 다른 경우에는 실제로는 정말 나쁜 일입니다. CPU 시간을 낭비하게 될 것입니다. 특히 이전에 델타를 잘 수행했다면 최종 결과는 이미 찾은 모든 좋은 델타 를 재사용하지 않을 것입니다 . 따라서 실제로 많은 데이터를 얻게 될 것입니다. 더 나쁜 결과도!
git gc --aggressive
문서를 제거하기 위해 Junio에 패치를 보내겠습니다 . 유용 할 수 있지만 일반적으로 그것이하는 일을 매우 심층적으로 이해하고 그 문서가 그렇게하는 데 도움이되지 않는 경우에만 유용합니다.
일반적으로 증분을 수행하는 git gc
것이 올바른 접근 방식이며 git gc --aggressive
. 이전 델타를 재사용 할 것이고, 이전 델타를 찾을 수 없을 때 (처음에 증분 GC를 수행하는 이유!) 새로운 델타를 생성 할 것입니다.
다른 한편으로,“길고 관련된 역사의 초기 수입”은 정말 좋은 델타를 찾는 데 많은 시간을 할애 할 가치가있는 지점이라는 것은 확실히 사실입니다 . 그러면 이후 모든 사용자 ( git gc --aggressive
실행 취소에 사용하지 않는 한 )는 해당 일회성 이벤트의 이점을 얻게됩니다. 따라서 특히 오랜 역사를 가진 대규모 프로젝트의 경우에는 추가 작업을 수행하여 델타 검색 코드를 야생으로 전환하는 것이 좋습니다.
따라서 git gc --aggressive
-그러나 올바르게 수행됨 -에 해당하는 것은 다음과 같이 (하룻밤)하는 것입니다.
git repack -a -d --depth=250 --window=250
그 깊이는 델타 체인이 얼마나 깊을 수 있는지에 관한 것이고 (오래된 기록을 위해 더 길게 만드십시오-공간 오버 헤드의 가치가 있습니다) 윈도우는 각 델타 후보가 스캔하기를 원하는 객체 윈도우의 크기에 관한 것입니다.
그리고 여기에 -f
플래그 를 추가하는 것이 좋습니다 ( "모든 오래된 델타 삭제"). 이제 실제로 이것이 좋은 후보를 실제로 찾는 지 확인하려고하기 때문입니다.
그리고 그것은 영원히 그리고 하루가 걸릴 것입니다 ( 즉 , "하룻밤"일). 그러나 최종 결과는 해당 저장소의 모든 다운 스트림이 직접 노력할 필요없이 훨씬 더 나은 팩을 얻을 수 있다는 것입니다.
Linus