“ การบรรจุที่เก็บอัตโนมัติเพื่อประสิทธิภาพสูงสุด” หมายความว่าอย่างไร


225

ฉันมีปัญหากับ repo คอมไพล์ของฉัน สองสามวันที่ผ่านมาเมื่อใดก็ตามที่ฉันกดเซิร์ฟเวอร์ฉันจะได้รับข้อความนี้: "การบรรจุที่เก็บอัตโนมัติเพื่อประสิทธิภาพที่ดีที่สุด" และดูเหมือนจะไม่หายไปไหนและกลับเชลล์

ฉันยังลองเช็คเอาท์ที่สาขาใหม่จากนั้นทำการ rebase ที่สาขาก่อนหน้าของฉันแล้วgit gcทำการลบวัตถุประวัติที่ไม่ได้ใช้แล้วทำการพุช แต่ยังมีข้อความนี้ปรากฏขึ้น โปรดแจ้งให้เราทราบว่าเกิดอะไรขึ้นกับ repo ของฉัน

คำตอบ:


305

เวอร์ชั่นย่อ: มันหมายถึงสิ่งที่พูดและถ้าคุณปล่อยให้มันจบทุกอย่างจะดี

ในระหว่างการดำเนินการส่วนใหญ่ซึ่งอาจจะสามารถเพิ่มจำนวนหลวม (แตก) วัตถุในพื้นที่เก็บข้อมูล (รวมถึงการผลักดัน) git gc --autoจะเรียก หากมีวัตถุหลวมเพียงพอ (โดยค่าเริ่มต้นอย่างน้อย 6700) จากนั้นจะเรียกใช้git repack -d -lเพื่อบรรจุวัตถุเหล่านั้น หากมีแพ็คแยกกันมากเกินไปก็จะบรรจุพวกเขาเป็นหนึ่ง

แพ็คเป็นไฟล์เดียวที่ถูกบีบอัดด้วยเดลต้าซึ่งมีวัตถุจำนวนมาก มันมีประสิทธิภาพมากขึ้นเพื่อเก็บวัตถุในแพ็ค แต่มันต้องใช้เวลาที่จะแพ็ค (บีบอัด) วัตถุดังนั้น Git แรกสร้างวัตถุหลวมแล้วแพ็คพวกเขาใน batches git gc --autoขณะนี้แล้วผ่านทางอัตโนมัติของการภาวนา

หากคุณปล่อยให้ Git บรรจุเสร็จแล้วสิ่งนี้จะไม่เกิดขึ้นอีกซักพัก อาจต้องใช้เวลาสักครู่โดยเฉพาะอย่างยิ่งถ้าคุณมีวัตถุไบนารีขนาดใหญ่จำนวนมาก แต่ถ้ามันถูกกระตุ้นก็เป็นสัญญาณว่ามันอาจจะลดปริมาณพื้นที่ดิสก์ที่ repo ลงอย่างมาก หากคุณไม่ต้องการให้เกิดขึ้นจริงคุณสามารถเปลี่ยนพารามิเตอร์กำหนดค่าgc.autoได้ หากคุณเพิ่มมันเป็นสิ่งที่ใหญ่กว่า 6700 มันจะเกิดขึ้นน้อยลง แต่จะใช้เวลานานกว่าเมื่อทำ หากคุณลดขนาดมันจะยังคงต้องทำหีบห่อปัจจุบันของคุณ แต่ต่อมาจะเกิดขึ้นบ่อยขึ้นและเสร็จเร็วขึ้น หากคุณตั้งค่าเป็น 0 มันจะปิดใช้งานการบรรจุใหม่โดยอัตโนมัติ

ดูman git-gc(ใต้--auto) และman git-config(ใต้gc.auto) สำหรับข้อมูลเพิ่มเติม


14
อันนี้ใช้เวลาประมาณ 5 นาทีสำหรับฉัน แต่มันก็จบลง คำตอบที่ดี
Joshua Pinter

6
เราเห็นว่ามันเกิดขึ้นทุกครั้งที่กด (ทำสักครู่สองสามวินาที)

2
@dpk: นั่นไม่ควรเกิดขึ้นในสถานการณ์ปกติ - จำนวนวัตถุในการกดครั้งเดียวไม่ควรมีขนาดใหญ่พอที่จะทริกเกอร์มัน (เว้นแต่ที่เก็บของคุณมีขนาดใหญ่มากและ / หรือคุณกำลังผลักดันจำนวนมาก) ดังนั้นเมื่อสำเร็จ เสร็จสิ้น (คุณกำลังปล่อยให้มันสมบูรณ์ใช่ไหม) มันจะไม่เกิดขึ้นอีกจนกว่าคุณจะสร้างมันขึ้นมา หากคุณคิดไม่ออกให้ถามคำถามแยกต่างหาก
Cascabel

6
"ถ้าคุณปล่อยให้ Git เสร็จสิ้น" และมันสามารถ ... fatal: Out of memory, malloc failed (tried to allocate 79610689 bytes) error: failed to run repack- นี่คือสิ่งที่ฉันได้รับจากการรวม codebase ทั้งหมดของเราไว้ใน repo git เดียว คิดว่าฉันจะฆ่าแอพและบังคับให้บรรจุหีบห่อใหม่ "ด้วยตนเอง"
ruffin

11
ฉันเข้าใจทุกครั้งที่ฉันทำคอมไพล์ ฉันทำ git gc ด้วยตนเองแล้ว แต่มันยังคงเกิดขึ้นทุกครั้งที่ฉันดึง แปลก.
Barry Kelly

51

ในขณะที่ Jefroni นั้นถูกต้องที่บางครั้งการจัดเรียงอัตโนมัติต้องใช้เวลาในการดำเนินการหากข้อความการบรรจุอัตโนมัติยังคงมีอยู่เป็นเวลาหลายวันตามที่ OP อธิบายมีโอกาสที่การล้างข้อมูลของ git หายไปจากวัตถุที่ห้อยต่องแต่งดังที่อธิบายไว้ในคำถามนี้

git fsckเพื่อดูว่าวัตถุห้อยกำลังเรียกข้อความอย่างต่อเนื่องเกี่ยวกับอัตโนมัติบรรจุลองใช้ หากคุณได้รับรายการห้อยที่ยาวนานคุณสามารถทำความสะอาดได้

git gc --prune=now

ฉันมักจะต้องใช้สิ่งนี้ใน repo ของฉันทุก 2-3 เดือนเมื่อข้อความการบรรจุอัตโนมัติไม่หายไปหลังจากการดึงเพียงครั้งเดียว


5
แม้ว่าจะไม่ใช่คำตอบที่ได้รับการยอมรับนี่เป็นสิ่งที่ฉันต้องการ ฉันได้รับข้อความทุกครั้งที่ฉันทำgit pullหลายวันและfsckแสดงให้เห็นถึงความมุ่งมั่นที่น่ากลัวมากมาย
Jörn Zaefferer

36

วิธีปิดใช้งานสำหรับหนึ่งโครงการ:

cd your_project_dir
git config gc.auto 0

วิธีปิดการใช้งานทั่วโลก:

git config --global gc.auto 0

2
ฉันคิดว่าฉันค้นพบวิธี: ไปที่โฟลเดอร์. git เปิดไฟล์ config และลบข้อความ 'auto = 0' และบันทึก ดูเหมือนว่าจะเปิดใช้งานการบรรจุอัตโนมัติอีกครั้ง
Adrian Keister

18
git config --unset gc.auto
jtatum

10

Git กำลังเรียกใช้ git-repack ซึ่งบรรจุวัตถุจำนวนมาก (= ไฟล์กระทำและต้นไม้) ลงในไฟล์แพ็คเดียว Git ทำเช่นนี้บางครั้งเมื่อฮิวริสติกบอกว่าสามารถประหยัดพื้นที่ได้ (ไฟล์แพ็คมีวัตถุที่ถูกบีบอัดในขณะที่แต่ละไฟล์ในออบเจ็กต์ / ไดเรกทอรีมีเนื้อหาไฟล์ที่ถูกบีบอัด)


2

หวังว่าgit gc --autoขั้นตอนนั้นตอนนี้ (git 2.0.1, 25 มิถุนายน 2014) มีประสิทธิภาพมากขึ้น
ดูการกระทำ 62aad18โดยNguyễnTháiNgọc Duy ( pclouds)

gc --auto: อย่าล็อค refs ในพื้นหลัง

9f673f9 ( gc: ตัวเลือกการกำหนดค่าสำหรับการทำงาน - อัตโนมัติในพื้นหลัง - 2014-02-08, Git 2.0.0) ทำให้ " gc --auto" อยู่ในพื้นหลังเพื่อลดเวลารอของผู้ใช้
ส่วนหนึ่งของการรวบรวมขยะคือแพ็คอ้างอิงและการตัดแต่งกิ่ง reflogs สิ่งเหล่านี้จำเป็นต้องล็อคการอ้างอิงบางอย่างและอาจยกเลิกกระบวนการอื่นที่พยายามล็อคการอ้างอิงเดียวกัน

ถ้าgc --autoยิงในช่วงกลางของสคริปต์, GC ถือครองล็อคในพื้นหลังอาจล้มเหลวสคริปต์ซึ่งไม่เคยเกิดขึ้นก่อน9f673f9

ทำงานต่อไปpack-refsและ " reflog --prune" อยู่เบื้องหน้าเพื่อหยุดการอัปเดตการอ้างอิงแบบขนาน การดำเนินการพื้นหลังที่เหลืออยู่ (การบรรจุหีบห่อและการบรรจุซ้ำ) ไม่ควรส่งผลกระทบต่อการเรียกใช้กระบวนการ git

และ Git 2.22 (Q2 2019) เพิ่มประสิทธิภาพต่อไปgit gc

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.