Giới hạn tập tin trong Git (số lượng và kích thước) là gì?


Câu trả lời:


161

Thông điệp này từ chính Linus có thể giúp bạn với một số giới hạn khác

[...] CVS, tức là nó thực sự được định hướng khá nhiều cho mô hình "một tệp tại một thời điểm".

Điều tuyệt vời là bạn có thể có một triệu tệp, và sau đó chỉ kiểm tra một vài trong số chúng - thậm chí bạn sẽ không bao giờ thấy tác động của 999.995 tệp khác.

Git về cơ bản không bao giờ thực sự nhìn ít hơn toàn bộ repo. Ngay cả khi bạn giới hạn mọi thứ một chút (ví dụ: chỉ kiểm tra một phần hoặc lịch sử quay lại chỉ một chút), git cuối cùng vẫn luôn quan tâm đến toàn bộ mọi thứ và mang theo kiến ​​thức xung quanh.

Vì vậy, quy mô git thực sự tồi tệ nếu bạn buộc nó phải xem mọi thứ như một kho lưu trữ khổng lồ . Tôi không nghĩ rằng phần đó thực sự có thể sửa được, mặc dù chúng ta có thể cải thiện nó.

Và vâng, sau đó là các vấn đề "tập tin lớn". Tôi thực sự không biết phải làm gì về các tập tin lớn. Chúng tôi mút chúng, tôi biết.

Xem thêm trong câu trả lời khác của tôi : giới hạn với Git là mỗi kho lưu trữ phải đại diện cho một " tập hợp mạch lạc ", "tất cả hệ thống" trong chính nó (bạn không thể gắn thẻ "một phần của kho lưu trữ").
Nếu hệ thống của bạn được làm từ các bộ phận tự trị (nhưng phụ thuộc lẫn nhau), bạn phải sử dụng các mô hình con .

Như được minh họa bởi câu trả lời của Talljoe , giới hạn có thể là một hệ thống (số lượng lớn tệp), nhưng nếu bạn hiểu bản chất của Git (về sự kết hợp dữ liệu được biểu thị bằng các khóa SHA-1 của nó), bạn sẽ nhận ra "giới hạn" thực sự là một cách sử dụng : tức là, bạn không nên cố gắng lưu trữ mọi thứ trong kho Git, trừ khi bạn chuẩn bị luôn lấy hoặc gắn thẻ mọi thứ lại. Đối với một số dự án lớn, nó sẽ không có ý nghĩa.


Để có cái nhìn sâu hơn về giới hạn git, hãy xem " git với các tệp lớn "
(trong đó đề cập đến git-lfs : một giải pháp để lưu trữ các tệp lớn bên ngoài repo git. GitHub, tháng 4 năm 2015)

Ba vấn đề giới hạn một repo git:

  • các tệp lớn ( xdelta cho packfile chỉ có trong bộ nhớ, không tốt với các tệp lớn)
  • số lượng tệp khổng lồ , có nghĩa là, một tệp trên mỗi blob và git gc chậm để tạo một packfile tại một thời điểm.
  • packfile lớn , với chỉ số packfile không hiệu quả để lấy dữ liệu từ packfile (rất lớn).

Một chủ đề gần đây hơn (tháng 2 năm 2015) minh họa các yếu tố giới hạn cho một repo Git :

Một vài bản sao đồng thời từ máy chủ trung tâm cũng sẽ làm chậm các hoạt động đồng thời khác cho người dùng khác?

Không có khóa trong máy chủ khi nhân bản, vì vậy trong lý thuyết nhân bản không ảnh hưởng đến các hoạt động khác. Nhân bản có thể sử dụng rất nhiều bộ nhớ (và rất nhiều cpu trừ khi bạn bật tính năng bitmap khả năng tiếp cận, mà bạn nên).

'' Sẽ git pullchậm chứ?

Nếu chúng tôi loại trừ phía máy chủ, kích thước của cây của bạn là yếu tố chính , nhưng các tệp 25k của bạn sẽ ổn (linux có 48k tệp).

' git push'?

Điều này không bị ảnh hưởng bởi lịch sử của người bạn sâu bao nhiêu, hoặc cây của bạn rộng bao nhiêu, vì vậy nên nhanh chóng ..

Ah số lượng ref có thể ảnh hưởng đến cả git-pushgit-pull.
Tôi nghĩ Stefan biết rõ hơn tôi trong lĩnh vực này.

' git commit'? (Nó được liệt kê là chậm trong tài liệu tham khảo 3. ) ' git status'? (Chậm lại trong tham chiếu 3 mặc dù tôi không thấy nó.)
(Cũng git-add)

Một lần nữa, kích thước của cây của bạn. Với kích thước của bạn, tôi không nghĩ bạn cần phải lo lắng về điều đó.

Một số hoạt động có thể không phải là hàng ngày nhưng nếu chúng được gọi thường xuyên bởi web front-end đến GitLab / Stash / GitHub, v.v. thì chúng có thể trở thành nút cổ chai. (ví dụ ' git branch --contains' dường như bị ảnh hưởng xấu bởi số lượng lớn các chi nhánh.)

git-blame có thể bị chậm khi một tập tin được sửa đổi rất nhiều.


4
@ Thr4wn: xem thêm stackoverflow.com/questions/1979167/git-submodule-update/ mẹo để biết thêm về trang mô hình con GitPro. Đối với phiên bản ngắn hơn: stackoverflow.com/questions/2065559/ từ
VonC

1
Liên kết được cập nhật cho tài liệu của git Suboules = git-scm.com/book/en/Git-Tools-Submodules
JHowIX

Tôi thực sự tự hỏi, với rất nhiều sqlite và nhiều lựa chọn cơ sở dữ liệu có sẵn trên linux, tại sao họ không thể đơn giản sử dụng cơ sở dữ liệu dễ dàng sao lưu, sao chép và chia tỷ lệ.
Akash Kava

"Git quy mô thực sự tồi tệ nếu bạn buộc nó phải xem mọi thứ như một kho lưu trữ khổng lồ " điều này nói gì về khả năng mở rộng của monorepose?
phù du

@ephemer Điều được nói là ... trích dẫn đó là từ 10 năm trước. Kể từ đó, vào năm 2017, Microsoft đã có monorepo của riêng mình ( devbloss.microsoft.com/bharry/iêu : 300GB +) và các cải tiến vẫn sẽ đến vào năm 2019: stackoverflow.com/a/57129687/6309
VonC

36

Không có giới hạn thực sự - mọi thứ đều được đặt tên bằng tên 160 bit. Kích thước của tệp phải được thể hiện bằng số 64 bit để không có giới hạn thực sự ở đó.

Có một giới hạn thực tế, mặc dù. Tôi có một kho lưu trữ ~ 8GB với> 880.000 tệp và git gc mất một lúc. Cây làm việc khá lớn nên các hoạt động kiểm tra toàn bộ thư mục làm việc mất khá nhiều thời gian. Repo này chỉ được sử dụng để lưu trữ dữ liệu, vì vậy nó chỉ là một loạt các công cụ tự động xử lý nó. Kéo các thay đổi từ repo là nhiều, nhanh hơn nhiều so với việc kết hợp cùng một dữ liệu.

%find . -type f | wc -l
791887
%time git add .
git add .  6.48s user 13.53s system 55% cpu 36.121 total
%time git status
# On branch master
nothing to commit (working directory clean)
git status  0.00s user 0.01s system 0% cpu 47.169 total
%du -sh .
29G     .
%cd .git
%du -sh .
7.9G    .

2
Mặc dù có một câu trả lời "đúng hơn" ở trên nói về những hạn chế về mặt lý thuyết, nhưng câu trả lời này có vẻ hữu ích hơn đối với tôi vì nó cho phép so sánh tình huống của chính bạn với bạn. Cảm ơn.
Tuneweizen

1
Rất thú vị. Làm thế nào có thể bản sao làm việc lớn hơn .gitthư mục? Giả định ngây thơ của tôi là cái .gitchứa một bản sao của thư mục làm việc cộng với lịch sử, vì vậy nó phải lớn hơn. Bất cứ ai có thể chỉ cho tôi một tài nguyên hiểu làm thế nào các kích thước này có liên quan?
bluenote10

1
@ bluenote10 Nội dung trong .gitthư mục được nén. Vì vậy, một kho lưu trữ với tương đối ít cam kết có thể có một lịch sử nén nhỏ hơn so với thư mục làm việc không nén. Kinh nghiệm của tôi cho thấy rằng trong thực tế, với mã C ++, toàn bộ lịch sử thường có cùng kích thước với thư mục làm việc.
prapin

28

Nếu bạn thêm các tệp quá lớn (GB trong trường hợp của tôi, Cygwin, XP, RAM 3 GB), hãy mong đợi điều này.

gây tử vong: Mất trí nhớ, malloc thất bại

Thêm chi tiết tại đây

Cập nhật 3/2/11: Saw tương tự trong Windows 7 x64 với Rùa Git. Hàng tấn bộ nhớ được sử dụng, phản ứng hệ thống rất rất chậm.


17

Trở lại vào tháng 2 năm 2012, có một chủ đề rất thú vị trong danh sách gửi thư Git từ Joshua Redstone, một kỹ sư phần mềm của Facebook đang thử nghiệm Git trên một kho lưu trữ thử nghiệm khổng lồ:

Repo thử nghiệm có 4 triệu cam kết, lịch sử tuyến tính và khoảng 1,3 triệu tệp.

Các thử nghiệm được thực hiện cho thấy đối với một repo Git như vậy là không thể sử dụng được (hoạt động lạnh kéo dài vài phút), nhưng điều này có thể thay đổi trong tương lai. Về cơ bản, hiệu năng bị phạt bởi số lượng stat()cuộc gọi đến mô-đun FS kernel, do đó, nó sẽ phụ thuộc vào số lượng tệp trong repo và hiệu quả bộ đệm của FS. Xem thêm Gist này để thảo luận thêm.


2
+1 Thú vị. Điều đó lặp lại câu trả lời của riêng tôi về giới hạn git nêu chi tiết các giới hạn đối với các tệp / số lượng tệp / gói tệp lớn.
VonC

3

Nó phụ thuộc vào ý nghĩa của bạn là gì. Có giới hạn kích thước thực tế (nếu bạn có nhiều tệp lớn, nó có thể bị chậm một cách nhàm chán). Nếu bạn có nhiều tệp, quét cũng có thể bị chậm.

Mặc dù vậy, không có giới hạn thực sự cho mô hình. Bạn chắc chắn có thể sử dụng nó một cách nghèo nàn và đau khổ.



1

Tôi nghĩ rằng thật tốt khi cố gắng tránh các tệp lớn cam kết là một phần của kho lưu trữ (ví dụ: kết xuất cơ sở dữ liệu có thể tốt hơn ở nơi khác), nhưng nếu xem xét kích thước của hạt nhân trong kho lưu trữ của nó, bạn có thể có thể làm việc thoải mái với bất cứ điều gì kích thước nhỏ hơn và ít phức tạp hơn thế.


1

Tôi có một lượng lớn dữ liệu được lưu trữ trong repo của mình dưới dạng các đoạn JSON riêng lẻ. Có khoảng 75.000 tệp nằm dưới một vài thư mục và nó không thực sự gây bất lợi cho hiệu suất.

Kiểm tra chúng lần đầu tiên, rõ ràng là hơi chậm.


1

Tôi thấy điều này đang cố lưu trữ một số lượng lớn tệp (350k +) trong một repo. Vâng, cửa hàng. Cười.

$ time git add . 
git add . 333.67s user 244.26s system 14% cpu 1:06:48.63 total

Các trích đoạn sau từ tài liệu Bitbucket khá thú vị.

Khi bạn làm việc với một kho lưu trữ DVCS nhân bản, đẩy, bạn đang làm việc với toàn bộ kho lưu trữ và tất cả lịch sử của nó. Trong thực tế, khi kho lưu trữ của bạn lớn hơn 500MB, bạn có thể bắt đầu thấy sự cố.

... 94% khách hàng của Bitbucket có kho lưu trữ dưới 500MB. Cả Linux Kernel và Android đều dưới 900 MB.

Giải pháp được đề xuất trên trang đó là chia dự án của bạn thành các phần nhỏ hơn.


Tôi đoán điều này là khá lỗi thời. Ngay bây giờ, dường như không có gì về repo Android (cũng như linux) trên trang web bạn đang liên kết đến. Nhưng tôi tự hỏi nếu nó không chính xác ngay cả khi đó? Ví dụ so sánh câu trả lời này . Có lẽ họ có ý gì khác?
jjj

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.