Tự động đóng gói kho lưu trữ cho hiệu suất tối ưu có nghĩa là gì?


225

Tôi có một vấn đề với repo git của tôi. Trong vài ngày qua, bất cứ khi nào tôi đẩy máy chủ, tôi nhận được thông báo này: "Tự động đóng gói kho lưu trữ để có hiệu suất tối ưu" và dường như nó không biến mất và trả lại vỏ.

Tôi cũng đã thử kiểm tra một nhánh mới và sau đó thực hiện rebase trên nhánh trước của mình và sau đó thực hiện git gcđể xóa các đối tượng lịch sử không sử dụng và sau đó thực hiện một cú đẩy nhưng thông báo này vẫn xuất hiện. Xin vui lòng cho tôi biết những gì đang xảy ra với repo của tôi.

Câu trả lời:


305

Phiên bản ngắn: có nghĩa là những gì nó nói, và nếu bạn chỉ để nó kết thúc, tất cả sẽ ổn.

Trong hầu hết các hoạt động có khả năng làm tăng số lượng các đối tượng lỏng lẻo (không giải nén) trong kho lưu trữ (bao gồm các lần đẩy), Git gọi git gc --auto. Nếu có đủ các đối tượng lỏng lẻo (theo mặc định, ít nhất là 6700), thì nó sẽ gọi git repack -d -lđể đóng gói chúng. Nếu có quá nhiều gói riêng biệt, nó cũng sẽ đóng gói lại thành một.

Một gói là một tệp duy nhất được nén delta, chứa một số lượng lớn các đối tượng. Việc lưu trữ các đối tượng theo gói sẽ hiệu quả hơn, nhưng cần có thời gian để đóng gói (nén) các đối tượng, do đó, Git ban đầu tạo ra các đối tượng lỏng lẻo, sau đó đóng gói chúng theo lô ngay bây giờ và sau đó, thông qua việc gọi tự động git gc --auto.

Nếu bạn để Git hoàn thành việc đóng gói lại, điều này sẽ không xảy ra một lần nữa. Nó thực sự có thể mất một lúc, đặc biệt là nếu bạn có nhiều đối tượng nhị phân lớn, nhưng nếu nó kích hoạt, thì đó là một dấu hiệu cho thấy nó có thể sẽ làm giảm đáng kể dung lượng đĩa được lấy bởi repo. Nếu bạn thực sự không muốn nó xảy ra, bạn có thể thay đổi tham số cấu hình gc.auto. Nếu bạn tăng nó lên một cái gì đó lớn hơn nhiều so với 6700, nó sẽ xảy ra ít thường xuyên hơn, nhưng mất nhiều thời gian hơn khi nó xảy ra. Nếu bạn giảm nó, nó vẫn sẽ phải thực hiện đóng gói lại hiện tại của bạn, nhưng sau đó nó sẽ xảy ra thường xuyên hơn và kết thúc nhanh hơn. Nếu bạn đặt thành 0, nó sẽ tắt tự động đóng gói lại.

Xem man git-gc(dưới --auto) và man git-config(dưới gc.auto) để biết thêm thông tin.


14
Thật vậy, điều này mất khoảng 5 phút cho tôi, nhưng nó đã kết thúc. Câu trả lời chính xác.
Joshua Pinter

6
Chúng ta đang thấy điều đó xảy ra với mỗi lần đẩy (mất một vài giây, heh).

2
@dpk: Điều đó không nên xảy ra trong các trường hợp thông thường - số lượng đối tượng trong một lần đẩy không đủ lớn để kích hoạt nó (trừ khi kho lưu trữ của bạn rất lớn và / hoặc bạn đang đẩy hàng tấn cam kết), vì vậy, một khi thành công hoàn thành (bạn đang để nó hoàn thành, phải không?) nó sẽ không xảy ra nữa cho đến khi bạn xây dựng nó. Nếu bạn không thể tìm ra nó, hãy hỏi một câu hỏi riêng.
Cascabel

6
"Nếu bạn để Git kết thúc", và nó có thể ... fatal: Out of memory, malloc failed (tried to allocate 79610689 bytes) error: failed to run repack- đây là những gì tôi nhận được khi gắn toàn bộ cơ sở mã của chúng tôi vào một repo git. Đoán tôi sẽ giết ứng dụng và buộc đóng gói lại "thủ công"
ruffin

11
Tôi đang nhận được nó mỗi khi tôi thực hiện một động tác kéo. Tôi đã thực hiện một git gc thủ công, nhưng nó vẫn xảy ra mỗi khi tôi kéo. Kỳ dị.
Barry Kelly

51

Mặc dù Jefroni đúng rằng đôi khi việc đóng gói tự động chỉ cần thời gian để hoàn thành, nếu thông báo đóng gói tự động vẫn tồn tại trong nhiều ngày như OP mô tả, rất có thể việc dọn dẹp của git bị thiếu các đối tượng lơ lửng, như được mô tả trong câu hỏi này .

Để xem liệu các đối tượng lơ lửng có kích hoạt các thông báo liên tục về tự động đóng gói hay không, hãy thử chạy git fsck. Nếu bạn nhận được một danh sách dài các cam kết lơ lửng, bạn có thể làm sạch chúng bằng

git gc --prune=now

Tôi thường phải chạy cái này trên repo của mình sau mỗi 2-3 tháng khi thông báo đóng gói tự động không biến mất sau một lần kéo.


5
Mặc dù không phải là câu trả lời được chấp nhận, đây chính xác là những gì tôi cần. Tôi nhận được tin nhắn mỗi khi tôi làm một git pull, trong nhiều ngày, và fsckthực sự cho thấy rất nhiều cam kết lơ lửng.
Jorn Zaefferer

36

Để vô hiệu hóa cho một dự án:

cd your_project_dir
git config gc.auto 0

Để vô hiệu hóa trên toàn cầu:

git config --global gc.auto 0

2
Tôi nghĩ rằng tôi đã tìm ra cách: đi đến thư mục .git, mở tệp cấu hình và xóa văn bản 'auto = 0' và lưu. Điều đó dường như để kích hoạt lại tự động.
Adrian Keister

18
git config --unset gc.auto
jtatum

10

Git đang chạy git-repack, gói nhiều đối tượng (= tệp, cam kết và cây) vào một tệp gói. Đôi khi Git thực hiện điều này, khi một heuristic nói rằng có thể có không gian được lưu (một tệp gói chứa deltas đối tượng nén, trong khi mỗi tệp trong đối tượng / thư mục chứa nội dung tệp được nén đầy đủ)


2

Hy vọng rằng, git gc --autobước đó bây giờ (git 2.0.1, ngày 25 tháng 6 năm 2014) hiệu quả hơn.
Xem cam kết 62aad18 của Nguyễn Thái Ngọc Duy (pclouds )

gc --auto: không khóa refs trong nền

9f673f9 ( gc: tùy chọn cấu hình để chạy --auto trong nền - 2014 / 02-08 , Git 2.0.0) đặt " gc --auto" trong nền để giảm thời gian chờ của người dùng.
Một phần của việc thu gom rác là các gói ref-refs và cắt tỉa. Những yêu cầu này khóa một số ref và có thể hủy bỏ các tiến trình khác đang cố gắng khóa cùng một ref.

Nếu gc --autobị bắn vào giữa tập lệnh, gc giữ khóa trong nền có thể không thành công tập lệnh, điều này không bao giờ có thể xảy ra trước 9f673f9 .

Tiếp tục chạy pack-refsvà " reflog --prune" ở phía trước để dừng cập nhật ref song song. Các hoạt động nền còn lại (đóng gói lại, cắt tỉa và chạy lại) sẽ không ảnh hưởng đến việc chạy các quy trình git.

Và Git 2.22 (quý 2 năm 2019) tiếp tục tối ưu hóagit gc .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.