ปัจจุบันไม่มีความแตกต่าง: git gc --aggressive
ดำเนินการตามข้อเสนอแนะของ Linus ที่ทำในปี 2550; ดูด้านล่าง สำหรับเวอร์ชัน 2.11 (ไตรมาสที่ 4 ปี 2016) ค่าเริ่มต้นของคอมไพล์คือความลึก 50 หน้าต่างขนาด 250 เป็นสิ่งที่ดีเพราะจะสแกนส่วนที่ใหญ่กว่าของแต่ละวัตถุ แต่ความลึกที่ 250 นั้นไม่ดีเนื่องจากทำให้ห่วงโซ่ทุกชิ้นอ้างถึงความเก่าที่ลึกมาก วัตถุซึ่งทำให้การทำงานของคอมไพล์ในอนาคตทั้งหมดช้าลงสำหรับการใช้งานดิสก์ที่ลดลงเล็กน้อย
ประวัติความเป็นมา
Linus แนะนำ (ดูด้านล่างสำหรับโพสต์รายชื่ออีเมลฉบับเต็ม) โดยใช้git gc --aggressive
เฉพาะเมื่อคุณมีในคำพูดของเขา " แพ็คที่ไม่ดีจริงๆ " หรือ "เดลต้าที่แย่มากจริงๆ" อย่างไรก็ตาม "เกือบตลอดเวลาในกรณีอื่น ๆ มันแย่จริงๆ สิ่งที่ต้องทำ." ผลลัพธ์อาจทำให้ที่เก็บของคุณอยู่ในสภาพที่แย่กว่าตอนที่คุณเริ่ม!
คำสั่งที่เขาแนะนำให้ทำอย่างถูกต้องหลังจากที่นำเข้า "ประวัติศาสตร์อันยาวนานและเกี่ยวข้อง" คือ
git repack -a -d -f --depth=250 --window=250
แต่ตอนนี้ถือว่าคุณมีอยู่แล้วเอาออก gunk ที่ไม่พึงประสงค์จากประวัติศาสตร์พื้นที่เก็บข้อมูลของคุณและที่คุณได้ทำตามรายการตรวจสอบสำหรับการหดตัวที่พบพื้นที่เก็บข้อมูลในเอกสารgit filter-branch
git-filter-branch สามารถใช้เพื่อกำจัดไฟล์ชุดย่อยโดยปกติจะมีการรวมกันของ--index-filter
และ--subdirectory-filter
. ผู้คนคาดหวังว่าพื้นที่เก็บข้อมูลที่ได้จะมีขนาดเล็กกว่าเดิม แต่คุณต้องมีขั้นตอนอีกสองสามขั้นเพื่อทำให้มันเล็กลงเพราะ Git พยายามอย่างยิ่งที่จะไม่ให้วัตถุของคุณหายไปจนกว่าคุณจะบอกไป ก่อนอื่นตรวจสอบให้แน่ใจว่า:
คุณได้ลบชื่อไฟล์รูปแบบต่างๆออกไปแล้วจริงๆถ้าหยดถูกย้ายไปตลอดอายุการใช้งาน git log --name-only --follow --all -- filename
สามารถช่วยคุณค้นหาการเปลี่ยนชื่อ
จริงๆคุณกรอง refs ทั้งหมด: ใช้เมื่อเรียก--tag-name-filter cat -- --all
git filter-branch
จากนั้นมีสองวิธีในการรับพื้นที่เก็บข้อมูลขนาดเล็ก วิธีที่ปลอดภัยกว่าคือการโคลนซึ่งทำให้ต้นฉบับของคุณไม่เสียหาย
- โคลนด้วย
git clone file:///path/to/repo
. โคลนจะไม่มีวัตถุที่ถูกลบออก ดู git-clone (โปรดทราบว่าการโคลนนิ่งด้วยเส้นทางธรรมดาเพียงแค่เชื่อมโยงทุกอย่าง!)
หากคุณไม่ต้องการโคลนจริงๆไม่ว่าด้วยเหตุผลใดก็ตามให้ตรวจสอบจุดต่อไปนี้แทน (ตามลำดับนี้) นี่เป็นวิธีการทำลายล้างอย่างมากดังนั้นให้ทำการสำรองข้อมูลหรือย้อนกลับไปที่การโคลน คุณได้รับการเตือนแล้ว
ลบการอ้างอิงเดิมที่สำรองไว้โดย git-filter-branch: say
git for-each-ref --format="%(refname)" refs/original/ |
xargs -n 1 git update-ref -d
หมดอายุ reflogs ทั้งหมดด้วยgit reflog expire --expire=now --all
.
Garbage รวบรวมอ็อบเจ็กต์ที่ไม่ได้อ้างอิงทั้งหมดด้วย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>
ในวันพฤหัสบดีที่ 6 ธันวาคม 2550 Daniel Berlin เขียนว่า:
อันที่จริงปรากฎว่าgit-gc --aggressive
บางครั้งสิ่งที่โง่เขลาในการแพ็คไฟล์ไม่ว่าคุณจะแปลงจาก SVN repo หรือไม่ก็ตาม
อย่างแน่นอน git --aggressive
ส่วนใหญ่เป็นใบ้ มันมีประโยชน์จริงๆสำหรับกรณี "ฉันรู้ว่าฉันมีแพ็คที่ไม่ดีจริงๆและฉันอยากจะทิ้งการตัดสินใจบรรจุหีบห่อที่ไม่ดีทั้งหมดที่ฉันเคยทำไป"
เพื่ออธิบายสิ่งนี้มันคุ้มค่าที่จะอธิบาย (คุณอาจจะรู้อยู่แล้ว แต่ขอให้ฉันอ่านพื้นฐานต่อไป) การทำงานของ git delta-chains และมันแตกต่างจากระบบอื่น ๆ อย่างไร
ใน SCM อื่น ๆ โดยทั่วไปแล้วเดลต้าเชนจะได้รับการแก้ไข อาจเป็น "ไปข้างหน้า" หรือ "ถอยหลัง" และอาจมีการพัฒนาขึ้นเล็กน้อยเมื่อคุณทำงานกับที่เก็บ แต่โดยทั่วไปแล้วจะเป็นห่วงโซ่การเปลี่ยนแปลงของไฟล์เดียวที่แสดงเป็นเอนทิตี SCM เดี่ยวบางประเภท ใน CVS เห็นได้ชัดว่าเป็น*,v
ไฟล์และระบบอื่น ๆ อีกมากมายทำสิ่งที่คล้ายกัน
Git ยังทำเดลต้าเชน แต่มันทำแบบ "หลวม ๆ " มากกว่า ไม่มีนิติบุคคลตายตัว Deltas ถูกสร้างขึ้นจากเวอร์ชันสุ่มอื่น ๆ ที่ git ถือว่าเป็นตัวเลือกเดลต้าที่ดี (ด้วยการวิเคราะห์พฤติกรรมที่ประสบความสำเร็จอย่างมาก) และไม่มีกฎการจัดกลุ่มที่ยากอย่างแน่นอน
นี่เป็นสิ่งที่ดีมาก เป็นสิ่งที่ดีสำหรับเหตุผลเชิงแนวคิดต่างๆ ( กล่าวคือคอมไพล์ภายในไม่จำเป็นต้องสนใจห่วงโซ่การแก้ไขทั้งหมด - มันไม่ได้คิดในแง่ของเดลต้าเลย) แต่ก็ยอดเยี่ยมเช่นกันเพราะการกำจัดกฎเดลต้าที่ไม่ยืดหยุ่นหมายความว่า คอมไพล์นั้นไม่มีปัญหาใด ๆ เลยในการรวมไฟล์สองไฟล์เข้าด้วยกันตัวอย่างเช่นไม่มี*,v
"ไฟล์แก้ไข" ตามอำเภอใจที่มีความหมายซ่อนอยู่
นอกจากนี้ยังหมายความว่าการเลือกเดลต้าเป็นคำถามปลายเปิดมากกว่า หากคุณ จำกัด ห่วงโซ่เดลต้าไว้เพียงไฟล์เดียวจริงๆแล้วคุณไม่มีทางเลือกมากมายว่าจะทำอย่างไรกับเดลต้า แต่ในคอมไพล์มันอาจเป็นปัญหาที่แตกต่างไปจากเดิมโดยสิ้นเชิง
และนี่คือที่--aggressive
มาของชื่อที่ไม่ดีจริงๆในขณะที่ git โดยทั่วไปจะพยายามใช้ข้อมูลเดลต้าซ้ำ (เพราะเป็นความคิดที่ดีและไม่ต้องเสียเวลา CPU ในการค้นหาเดลต้าที่ดีทั้งหมดที่เราพบก่อนหน้านี้อีกครั้ง) บางครั้งคุณ ต้องการบอกว่า“ มาเริ่มกันใหม่โดยใช้กระดานชนวนว่างเปล่าและเพิกเฉยต่อข้อมูลเดลต้าก่อนหน้าทั้งหมดและพยายามสร้างเดลต้าชุดใหม่”
ดังนั้นจึง--aggressive
ไม่ได้เกี่ยวกับการก้าวร้าว แต่เป็นการเสียเวลาของ CPU ในการตัดสินใจใหม่ที่เราได้ทำไปแล้วก่อนหน้านี้!
บางครั้งนั่นก็เป็นเรื่องดี โดยเฉพาะอย่างยิ่งเครื่องมือนำเข้าบางอย่างสามารถสร้างเดลต้าที่เลวร้ายได้อย่างน่าสยดสยอง git fast-import
ตัวอย่างเช่นสิ่งที่ใช้มักจะไม่มีเค้าโครงเดลต้าที่ยอดเยี่ยมมากนักดังนั้นจึงควรพูดว่า "ฉันต้องการเริ่มจากกระดานชนวนที่สะอาด"
แต่เกือบตลอดเวลาในกรณีอื่น ๆ มันเป็นสิ่งที่เลวร้ายจริงๆ มันจะเสียเวลา CPU และโดยเฉพาะอย่างยิ่งถ้าคุณทำงานได้ดีในการเดลต้าก่อนหน้านี้ผลลัพธ์สุดท้ายจะไม่นำเดลต้าที่ดีทั้งหมดที่คุณพบมาใช้ซ้ำดังนั้นคุณจะจบลงด้วย ผลสุดท้ายแย่ลงด้วย!
ฉันจะส่งแพตช์ไปให้ Junio เพื่อเอาgit gc --aggressive
เอกสารออก อาจมีประโยชน์ แต่โดยทั่วไปแล้วจะมีประโยชน์ก็ต่อเมื่อคุณเข้าใจในระดับลึกจริงๆว่ากำลังทำอะไรอยู่และเอกสารนั้นไม่ได้ช่วยให้คุณทำเช่นนั้นได้
โดยทั่วไปการทำที่เพิ่มขึ้นเป็นวิธีการที่เหมาะสมและดีกว่าทำgit gc
git gc --aggressive
มันจะนำเดลตาเก่ามาใช้ใหม่และเมื่อไม่พบเดลตาเก่าเหล่านั้น (เหตุผลในการทำ GC แบบเพิ่มหน่วยตั้งแต่แรก!) มันจะสร้างอันใหม่
ในทางกลับกันมันเป็นความจริงอย่างแน่นอนที่“ การนำเข้าครั้งแรกของประวัติศาสตร์อันยาวนานและเกี่ยวข้อง” เป็นจุดที่คุ้มค่ากับการเสียเวลาไปกับการค้นหาเดลต้าที่ดีจริงๆ จากนั้นผู้ใช้ทุกคนหลังจากนั้น (ตราบใดที่พวกเขาไม่ได้ใช้git gc --aggressive
เพื่อเลิกทำ!) จะได้รับประโยชน์จากเหตุการณ์ที่เกิดขึ้นเพียงครั้งเดียว ดังนั้นโดยเฉพาะอย่างยิ่งสำหรับโครงการขนาดใหญ่ที่มีประวัติอันยาวนานมันอาจคุ้มค่าที่จะทำงานพิเศษบางอย่างโดยบอกให้รหัสการค้นหาเดลต้าดำเนินไปอย่างรวดเร็ว
ดังนั้นสิ่งที่เทียบเท่าgit gc --aggressive
- แต่ทำอย่างถูกต้อง - คือการทำ (ค้างคืน) อย่าง
git repack -a -d --depth=250 --window=250
โดยที่ความลึกนั้นเกี่ยวกับว่าโซ่เดลต้าสามารถอยู่ได้ลึกแค่ไหน (ทำให้มันยาวขึ้นสำหรับประวัติศาสตร์เก่า - มันคุ้มค่ากับพื้นที่เหนือศีรษะ) และหน้าต่างก็คือหน้าต่างออบเจ็กต์ที่เราต้องการให้ผู้สมัครเดลต้าแต่ละคนสแกน
และที่นี่คุณอาจต้องการเพิ่ม-f
แฟล็ก (ซึ่งก็คือ "ทิ้งเดลต้าเก่าทั้งหมด" เนื่องจากตอนนี้คุณกำลังพยายามทำให้แน่ใจว่าอันนี้พบผู้สมัครที่ดีจริงๆ
จากนั้นมันจะใช้เวลาตลอดไปและหนึ่งวัน ( กล่าวคือสิ่งที่ "ทำค้างคืน") แต่ผลลัพธ์ที่ได้คือทุกคนที่ล่องจากที่เก็บนั้นจะได้รับแพ็คที่ดีขึ้นมากโดยไม่ต้องใช้ความพยายามใด ๆ กับมัน
Linus