Quản lý tệp nhị phân lớn với Git


523

Tôi đang tìm kiếm ý kiến ​​về cách xử lý các tệp nhị phân lớn mà mã nguồn của tôi (ứng dụng web) phụ thuộc vào. Chúng tôi hiện đang thảo luận về một số lựa chọn thay thế:

  1. Sao chép các tệp nhị phân bằng tay.
    • Pro: Không chắc chắn.
    • Contra: Tôi mạnh mẽ chống lại điều này, vì nó làm tăng khả năng xảy ra lỗi khi thiết lập một trang web mới / di chuyển trang web cũ. Xây dựng một trở ngại khác để có.
  2. Quản lý tất cả với Git .
    • Pro: Loại bỏ khả năng 'quên' để sao chép một tệp quan trọng
    • Contra: Bloats kho lưu trữ và giảm tính linh hoạt để quản lý cơ sở mã và kiểm tra, nhân bản, vv sẽ mất khá nhiều thời gian.
  3. Kho riêng.
    • Pro: Kiểm tra / nhân bản mã nguồn nhanh hơn bao giờ hết và hình ảnh được lưu trữ đúng cách trong kho lưu trữ của riêng họ.
    • Contra: Loại bỏ sự đơn giản khi có kho lưu trữ Git một và duy nhất trong dự án. Nó chắc chắn giới thiệu một số điều khác mà tôi chưa từng nghĩ đến.

Kinh nghiệm / suy nghĩ của bạn về điều này là gì?

Ngoài ra: Có ai có kinh nghiệm với nhiều kho Git và quản lý chúng trong một dự án không?

Các tệp này là hình ảnh cho một chương trình tạo tệp PDF với các tệp trong đó. Các tập tin sẽ không thay đổi rất thường xuyên (như trong năm), nhưng chúng rất phù hợp với một chương trình. Chương trình sẽ không hoạt động mà không có các tập tin.


26
Điều gì về khi phiên bản kiểm soát tệp nhị phân là cần thiết? Tôi đang suy nghĩ cho các nhóm nghệ sĩ làm việc trên tài sản.
Dan

3
Nếu cần thiết thì bạn phải cân bằng các tài nguyên có sẵn (đĩa, băng thông, thời gian CPU) so với lợi ích bạn nhận được.
pi.

4
Lưu ý rằng không có khóa tệp, git sẽ không tuyệt vời khi nhiều người cần làm việc trên cùng một tệp nhị phân.
yoyo


Câu trả lời:


177

Nếu chương trình không hoạt động mà không có các tệp thì có vẻ như tách chúng thành một repo riêng là một ý tưởng tồi. Chúng tôi có các bộ thử nghiệm lớn mà chúng tôi chia thành một repo riêng nhưng đó là những tệp thực sự "phụ trợ".

Tuy nhiên, bạn có thể quản lý các tệp trong một repo riêng và sau đó sử dụng git-submoduleđể kéo chúng vào dự án của bạn một cách lành mạnh. Vì vậy, bạn vẫn có toàn bộ lịch sử của tất cả các nguồn của mình, nhưng theo tôi hiểu, bạn chỉ có một bản sửa đổi có liên quan của mô hình con của bạn. Công cụ git-submodulesẽ giúp bạn giữ đúng phiên bản mã phù hợp với phiên bản chính xác của hình ảnh.

Đây là một giới thiệu tốt về mô hình con từ Git Book.


11
"theo tôi hiểu, bạn chỉ có một bản sửa đổi có liên quan của mô hình con của bạn." Tôi không nghĩ rằng điều này là chính xác.
Robin Green

22
Thật. Một mô hình con là một kho lưu trữ Git đầy đủ, tình cờ được lồng bên trong kho mẹ. Nó biết toàn bộ lịch sử của nó. Bạn có thể cam kết ít thường xuyên hơn trong đó, nhưng nếu bạn lưu trữ những thứ tương tự trong đó bạn sẽ có trong cha mẹ, nó sẽ có cùng các vấn đề mà cha mẹ sẽ có.
Cascabel

5
Đây là một giải pháp khá kém nếu bạn có các tệp nhị phân lớn đang thay đổi theo một khoảng thời gian thông thường. Chúng tôi có một kho lưu trữ khủng khiếp vì một tệp nhị phân mới được lưu trữ trong đó với mỗi bản dựng. Nếu bạn không ở trên Windows, như được đề cập dưới đây, Phụ lục là một giải pháp tốt. Nếu bạn đang ở trên Windows ... sẽ phải tiếp tục tìm kiếm.
Aps Grapsas

4
Một vấn đề khác trong việc có các tệp nhị phân lớn trong repo là hiệu suất. Git không được thiết kế để đối phó với các tệp nhị phân lớn và một khi kích thước repo leo lên 3G +, hiệu suất sẽ nhanh chóng giảm xuống. Điều này có nghĩa là có các nhị phân lớn trong repo giới hạn các tùy chọn lưu trữ của bạn.
zoul

Các mô hình con có thể giảm yêu cầu chuyển dữ liệu kiểm tra nếu bạn sử dụng sai mục đích của mô hình con: khi bạn muốn cập nhật nội dung mô hình con, tạo một cam kết mới mà không có cha mẹ và sau đó trỏ superproject (main git repo) vào cam kết mới được tạo mà không có cha mẹ. Về mặt logic, điều này tạo ra một lịch sử bị ngắt kết nối cho mô hình con nhưng bù lại, bất kỳ phiên bản nào của mô hình con sẽ dễ dàng chuyển hơn vì phiên bản đó không có lịch sử.
Mikko Rantalainen

310

Tôi phát hiện ra git-annex gần đây mà tôi thấy tuyệt vời. Nó được thiết kế để quản lý các tệp lớn một cách hiệu quả. Tôi sử dụng nó cho các bộ sưu tập ảnh / âm nhạc của tôi (vv). Sự phát triển của git-annex rất tích cực. Nội dung của các tệp có thể được xóa khỏi kho Git, chỉ phân cấp cây được Git theo dõi (thông qua các liên kết tượng trưng). Tuy nhiên, để có được nội dung của tệp, bước thứ hai là cần thiết sau khi kéo / đẩy, ví dụ:

$ git annex add mybigfile
$ git commit -m'add mybigfile'
$ git push myremote
$ git annex copy --to myremote mybigfile ## This command copies the actual content to myremote
$ git annex drop mybigfile ## Remove content from local repo
...
$ git annex get mybigfile ## Retrieve the content
## or to specify the remote from which to get:
$ git annex copy --from myremote mybigfile

Có rất nhiều lệnh có sẵn, và có một tài liệu tuyệt vời trên trang web. Một gói có sẵn trên Debian .


11
Ái chà! Upvote cho sự tuyệt vời! Điều này thực hiện một ý tưởng mà tôi đã có gần đây, và nhiều hơn nữa. Nó được viết bằng Haskell không hơn không kém. Nhân tiện, git-media là một lựa chọn tốt.
cdunn2001

33
Nhưng, Phụ lục không hỗ trợ Windows. Đó là vấn đề cho các nhà phát triển trò chơi.
Aps Grapsas

7
Tôi nghe nói Steam đang bỏ hỗ trợ cho các cửa sổ và thêm hỗ trợ cho Linux ...;) một cách nghiêm túc, làm thế nào khó để chuyển cái này? Tôi đoán nhà phát triển trò chơi trung bình của bạn có thể làm điều đó.
Sam Watkins

4
@EstebanBrenes Công cụ phá vỡ giao dịch thực sự là trong cấu hình bình thường, các liên kết Windows yêu cầu các đặc quyền nâng cao để tạo.
Laurens Holst

4
Tôi chỉ tìm thấy trang này . Nó đọc rằng bây giờ git annexcũng có sẵn trên Windows . Nếu bất cứ ai đã từng thử nghiệm nó trong Windows, tôi muốn nghe về trải nghiệm của mình!
Kouichi C. Nakamura

49

Một giải pháp khác, kể từ tháng 4 năm 2015 là Git Large File Storage (LFS) (bởi GitHub).

Nó sử dụng git-lfs (xem git-lfs.github.com ) và được thử nghiệm với một máy chủ hỗ trợ nó: lfs-test-server :
Bạn chỉ có thể lưu trữ siêu dữ liệu trong git repo và tệp lớn ở nơi khác.

https://cloud.githubusercontent.com/assets/1319791/7051226/c4570828-ddf4-11e4-87eb-8fc165e5ece4.gif


3
lfs-test-serverđược tuyên bố là không sử dụng cho sản xuất. Trên thực tế, tôi đang làm việc trên máy chủ LFS sản xuất ( github.com/artemkin/git-lfs-server ). Nó đang được tiến hành, nhưng đã được bảo dưỡng và chúng tôi đang thử nghiệm nội bộ.
Stas

Bạn có thể kiểm tra các phiên bản trước của tệp nhị phân như vậy bằng git lfs không?
mucaho

1
@mucaho Bạn nên: cú pháp kiểm tra git không thay đổi và tập lệnh smfs smfs vẫn nên được gọi.
VonC

31

Hãy xem git bup là một phần mở rộng Git để lưu trữ thông minh các nhị phân lớn trong kho Git.

Bạn muốn có nó như một mô hình con, nhưng bạn sẽ không phải lo lắng về việc kho lưu trữ trở nên khó xử lý. Một trong những trường hợp sử dụng mẫu của họ là lưu trữ hình ảnh VM trong Git.

Tôi thực sự không thấy tốc độ nén tốt hơn, nhưng kho của tôi không có nhị phân thực sự lớn trong đó.

Số dặm của bạn có thể thay đổi.


3
bup cung cấp lưu trữ (sử dụng nội bộ lưu trữ chẵn lẻ để dự phòng và git để nén, khấu trừ và lịch sử), nhưng nó không mở rộng git. git-annex là một phần mở rộng git cung cấp một phụ trợ lưu trữ bup .
Tobu

@Tobu khi tôi đăng bài này, git annex chưa tồn tại (trong các bản phát hành chính thống)
sehe

2
bup chắc chắn là thú vị để quản lý các tập tin lớn. Tôi muốn chỉ ra một sự khác biệt trong UI: bạn sử dụng các lệnh bup bên ngoài bất kỳ bối cảnh kho lưu trữ nào và git là một chi tiết triển khai.
Tobu

27

Bạn cũng có thể sử dụng git-fat . Tôi thích nó chỉ phụ thuộc vào chứng khoán Python và rsync. Nó cũng hỗ trợ luồng công việc Git thông thường, với các lệnh tự giải thích sau:

git fat init
git fat push
git fat pull

Ngoài ra, bạn cần kiểm tra tệp .gitfat vào kho lưu trữ của bạn và sửa đổi .gitattribution của bạn để chỉ định các tiện ích mở rộng tệp bạn muốn git fatquản lý.

Bạn thêm một nhị phân bằng cách sử dụng bình thường git add, lần lượt gọi git fatdựa trên các quy tắc gitattribution của bạn.

Cuối cùng, có một lợi thế là vị trí lưu trữ nhị phân của bạn thực sự có thể được chia sẻ trên các kho lưu trữ và người dùng và hỗ trợ mọi thứ rsync.

CẬP NHẬT: Không sử dụng git-fat nếu bạn đang sử dụng cầu Git-SVN. Nó sẽ kết thúc việc xóa các tệp nhị phân khỏi kho lưu trữ Subversion của bạn. Tuy nhiên, nếu bạn đang sử dụng kho lưu trữ Git thuần túy, nó hoạt động rất đẹp.


26

Tôi sẽ sử dụng các mô hình con (như Pat Notz) hoặc hai kho lưu trữ riêng biệt. Nếu bạn sửa đổi các tệp nhị phân của mình quá thường xuyên, thì tôi sẽ cố gắng giảm thiểu tác động của kho lưu trữ khổng lồ làm sạch lịch sử:

Tôi đã gặp một vấn đề rất giống nhau vài tháng trước: ~ 21 GB tệp MP3, chưa được phân loại (tên xấu, id3 xấu, không biết tôi có thích tệp MP3 đó hay không ...) và được sao chép trên ba máy tính.

Tôi đã sử dụng một ổ đĩa cứng ngoài với kho lưu trữ Git chính và tôi đã nhân bản nó vào mỗi máy tính. Sau đó, tôi bắt đầu phân loại chúng theo cách theo thói quen (đẩy, kéo, hợp nhất ... xóa và đổi tên nhiều lần).

Cuối cùng, tôi chỉ có ~ 6 GB tệp MP3 và ~ 83 GB trong thư mục .git. Tôi đã sử dụng git-write-treegit-commit-treeđể tạo một cam kết mới, không có tổ tiên cam kết và bắt đầu một nhánh mới chỉ vào cam kết đó. "Nhật ký git" cho chi nhánh đó chỉ hiển thị một cam kết.

Sau đó, tôi đã xóa chi nhánh cũ, chỉ giữ lại chi nhánh mới, xóa nhật ký ref và chạy "git prune": sau đó, các thư mục .git của tôi chỉ nặng ~ 6 GB ...

Thỉnh thoảng bạn có thể "thanh lọc" kho lưu trữ khổng lồ theo cùng một cách: "git clone" của bạn sẽ nhanh hơn.


Tôi đã làm một cái gì đó tương tự khi tôi phải tách một kho lưu trữ mà tôi vô tình hợp nhất thành hai kho riêng biệt. Mô hình sử dụng thú vị mặc dù. :)
pi.

1
Điều này sẽ giống như chỉ: rm -f .git; git init; git thêm. ; git commit -m "Thùng rác lịch sử."
Pat Notz

1
Vâng, nó chỉ giống nhau trong trường hợp mp3 của tôi. Nhưng đôi khi bạn không muốn chạm vào các nhánh và thẻ của mình (không giảm dung lượng trong kho lưu trữ công cộng) nhưng bạn muốn tăng tốc "git clone / fetch / pull" của một nhánh (ít không gian dành riêng cho điều đó kho lưu trữ chi nhánh).
Daniel Fanjul

13

Giải pháp tôi muốn đề xuất dựa trên các nhánh mồ côi và lạm dụng một chút cơ chế thẻ, từ đó được gọi là * Lưu trữ nhị phân thẻ mồ côi (OTABS)

TL; DR 12-01-2017 Nếu bạn có thể sử dụng LFS của github hoặc một số bên thứ 3 khác, bằng mọi cách bạn nên làm. Nếu bạn không thể, sau đó đọc tiếp. Được cảnh báo, giải pháp này là một hack và nên được xử lý như vậy.

Thuộc tính mong muốn của OTABS

  • nó là một git tinh khiếtgit chỉ giải pháp - nó được công việc thực hiện mà không bất kỳ phần mềm của bên thứ 3 (như git-phụ lục) hoặc cơ sở hạ tầng bên thứ 3 (như LFS github của).
  • nó lưu trữ các tệp nhị phân một cách hiệu quả , tức là nó không làm mờ lịch sử kho lưu trữ của bạn.
  • git pullgit fetch, bao gồm cả băng thônggit fetch --all vẫn hiệu quả , tức là không phải tất cả các nhị phân lớn đều được kéo từ xa theo mặc định.
  • nó hoạt động trên Windows .
  • nó lưu trữ mọi thứ trong một kho git duy nhất .
  • nó cho phép xóa các nhị phân lỗi thời (không giống như bup).

Thuộc tính không mong muốn của OTABS

  • nó làm cho git clonetiềm năng không hiệu quả (nhưng không nhất thiết, tùy thuộc vào cách sử dụng của bạn). Nếu bạn triển khai giải pháp này, bạn có thể phải tư vấn cho đồng nghiệp của mình sử dụng git clone -b master --single-branch <url>thay vì git clone. Điều này là do git clone theo mặc định theo nghĩa đen là sao chép toàn bộ kho lưu trữ, bao gồm cả những thứ bạn thường không muốn lãng phí băng thông của mình, như các cam kết không được kiểm soát. Lấy từ SO 4811434 .
  • nó làm cho git fetch <remote> --tagsbăng thông không hiệu quả, nhưng không nhất thiết là lưu trữ không hiệu quả. Bạn luôn có thể khuyên đồng nghiệp không sử dụng nó.
  • bạn sẽ phải định kỳ sử dụng một git gcmẹo để dọn kho lưu trữ của mình khỏi bất kỳ tệp nào bạn không muốn nữa.
  • nó không hiệu quả như bup hay git-bigfiles . Nhưng nó tương ứng phù hợp hơn cho những gì bạn đang cố gắng thực hiện và nhiều thứ khác. Bạn có thể gặp rắc rối với hàng trăm ngàn tệp nhỏ hoặc với các tệp trong phạm vi gigabyte, nhưng hãy đọc để giải quyết.

Thêm tệp nhị phân

Trước khi bạn bắt đầu đảm bảo rằng bạn đã cam kết tất cả các thay đổi của mình, cây làm việc của bạn được cập nhật và chỉ mục của bạn không chứa bất kỳ thay đổi không được cam kết nào. Có thể là một ý tưởng tốt để đẩy tất cả các chi nhánh địa phương của bạn đến điều khiển từ xa (github, v.v.) trong trường hợp có thảm họa xảy ra.

  1. Tạo một nhánh mồ côi mới. git checkout --orphan binaryStuffsẽ thực hiện các mẹo. Điều này tạo ra một nhánh hoàn toàn bị ngắt kết nối với bất kỳ nhánh nào khác và cam kết đầu tiên bạn thực hiện trong nhánh này sẽ không có cha mẹ, điều này sẽ khiến nó trở thành một cam kết gốc.
  2. Làm sạch chỉ mục của bạn bằng cách sử dụng git rm --cached * .gitignore.
  3. Hít một hơi thật sâu và xóa toàn bộ cây làm việc bằng cách sử dụng rm -fr * .gitignore. Thư mục nội bộ .gitsẽ không bị ảnh hưởng, vì *ký tự đại diện không khớp với nó.
  4. Sao chép trong VeryBigBinary.exe hoặc VeryHeavyDirectory / của bạn.
  5. Thêm nó && cam kết nó.
  6. Bây giờ nó trở nên khó khăn - nếu bạn đẩy nó vào điều khiển từ xa như một nhánh, tất cả các nhà phát triển của bạn sẽ tải xuống vào lần tiếp theo khi họ gọi git fetchkết nối của họ. Bạn có thể tránh điều này bằng cách đẩy một thẻ thay vì một nhánh. Điều này vẫn có thể ảnh hưởng đến băng thông và lưu trữ hệ thống tệp của đồng nghiệp nếu họ có thói quen gõ git fetch <remote> --tags, nhưng hãy đọc tiếp để giải quyết. Đi trước vàgit tag 1.0.0bin
  7. Đẩy thẻ mồ côi của bạn git push <remote> 1.0.0bin.
  8. Chỉ để bạn không bao giờ đẩy chi nhánh nhị phân của mình một cách tình cờ, bạn có thể xóa nó git branch -D binaryStuff. Cam kết của bạn sẽ không được đánh dấu cho bộ sưu tập rác, bởi vì thẻ mồ côi chỉ vào nó 1.0.0binlà đủ để giữ cho nó tồn tại.

Kiểm tra tệp nhị phân

  1. Làm cách nào để tôi (hoặc đồng nghiệp của tôi) kiểm tra VeryBigBinary.exe vào cây làm việc hiện tại? Nếu chi nhánh làm việc hiện tại của bạn là ví dụ chủ, bạn có thể đơn giản git checkout 1.0.0bin -- VeryBigBinary.exe.
  2. Điều này sẽ thất bại nếu bạn không 1.0.0bintải xuống thẻ mồ côi , trong trường hợp đó bạn sẽ phải làm git fetch <remote> 1.0.0bintrước.
  3. Bạn có thể thêm VeryBigBinary.exevào chủ của mình .gitignore, để không ai trong nhóm của bạn gây ô nhiễm lịch sử chính của dự án với nhị phân một cách tình cờ.

Xóa hoàn toàn tệp nhị phân

Nếu bạn quyết định thanh lọc hoàn toàn VeryBigBinary.exe khỏi kho lưu trữ cục bộ, kho lưu trữ từ xa và kho lưu trữ của đồng nghiệp, bạn chỉ có thể:

  1. Xóa thẻ mồ côi trên điều khiển từ xa git push <remote> :refs/tags/1.0.0bin
  2. Xóa thẻ mồ côi cục bộ (xóa tất cả các thẻ không được ước tính khác) git tag -l | xargs git tag -d && git fetch --tags. Lấy từ SO 1841341 với một chút sửa đổi.
  3. Sử dụng thủ thuật git gc để xóa cam kết không được ước tính của bạn cục bộ. git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@". Nó cũng sẽ xóa tất cả các cam kết không được ước tính khác. Lấy từ SO 1904860
  4. Nếu có thể, hãy lặp lại thủ thuật git gc trên điều khiển từ xa. Có thể nếu bạn tự lưu trữ kho lưu trữ của mình và có thể không khả dụng với một số nhà cung cấp git, như github hoặc trong một số môi trường công ty. Nếu bạn đang lưu trữ với một nhà cung cấp không cung cấp cho bạn quyền truy cập ssh vào điều khiển từ xa, hãy cứ để nó. Có thể cơ sở hạ tầng của nhà cung cấp của bạn sẽ làm sạch cam kết không được ước tính của bạn trong thời gian ngọt ngào của họ. Nếu bạn ở trong môi trường công ty, bạn có thể khuyên IT nên chạy rác công việc định kỳ thu thập điều khiển từ xa mỗi tuần một lần. Cho dù họ có làm hay không sẽ không có bất kỳ tác động nào đến nhóm của bạn về băng thông và lưu trữ, miễn là bạn khuyên đồng nghiệp luôn luôn git clone -b master --single-branch <url>thay vì git clone.
  5. Tất cả các đồng nghiệp của bạn, những người muốn thoát khỏi các thẻ mồ côi lỗi thời chỉ cần áp dụng các bước 2-3.
  6. Sau đó, bạn có thể lặp lại các bước 1-8 của Thêm tệp nhị phân để tạo thẻ mồ côi mới 2.0.0bin. Nếu bạn lo lắng về việc đồng nghiệp của mình gõ, git fetch <remote> --tagsbạn thực sự có thể đặt tên lại 1.0.0bin. Điều này sẽ đảm bảo rằng lần tiếp theo họ tìm nạp tất cả các thẻ cũ 1.0.0binsẽ không được kiểm tra và đánh dấu cho bộ sưu tập rác tiếp theo (sử dụng bước 3). Khi bạn cố ghi đè một thẻ trên điều khiển từ xa, bạn phải sử dụng -fnhư thế này:git push -f <remote> <tagname>

Lời bạt

  • OTABS không chạm vào chủ của bạn hoặc bất kỳ chi nhánh phát triển / mã nguồn nào khác. Các băm cam kết, tất cả lịch sử và kích thước nhỏ của các nhánh này không bị ảnh hưởng. Nếu bạn đã làm mờ lịch sử mã nguồn của mình bằng các tệp nhị phân, bạn sẽ phải dọn sạch nó như một phần công việc riêng biệt. Kịch bản này có thể hữu ích.

  • Xác nhận hoạt động trên Windows với git-bash.

  • Đó là một ý tưởng tốt để áp dụng một bộ các tiêu chuẩn để làm cho việc lưu trữ các tệp nhị phân hiệu quả hơn. Việc chạy thường xuyên git gc(không có bất kỳ đối số bổ sung nào) làm cho git tối ưu hóa lưu trữ cơ bản của các tệp của bạn bằng cách sử dụng deltas nhị phân. Tuy nhiên, nếu các tệp của bạn không có khả năng giữ nguyên từ tương tự từ cam kết đến cam kết, bạn có thể tắt hoàn toàn deltas nhị phân. Ngoài ra, vì không có ý nghĩa gì khi nén các tệp đã được nén hoặc mã hóa, như .zip, .jpg hoặc .crypt, git cho phép bạn tắt nén bộ nhớ bên dưới. Thật không may, đó cũng là một cài đặt toàn bộ hoặc không có gì ảnh hưởng đến mã nguồn của bạn.

  • Bạn có thể muốn tập lệnh lên các phần của OTABS để cho phép sử dụng nhanh hơn. Cụ thể, kịch bản các bước 2-3 từ Xóa hoàn toàn các tệp nhị phân vào một updategit hook có thể mang lại một ngữ nghĩa hấp dẫn nhưng có lẽ nguy hiểm để git fetch ("tìm nạp và xóa mọi thứ đã lỗi thời").

  • Bạn có thể muốn bỏ qua bước 4 của Xóa hoàn toàn các tệp nhị phân để giữ toàn bộ lịch sử của tất cả các thay đổi nhị phân trên điều khiển từ xa với chi phí của kho lưu trữ trung tâm. Các kho lưu trữ địa phương sẽ ở lại theo thời gian.

  • Trong thế giới Java, có thể kết hợp giải pháp này với maven --offlineviệc tạo một bản dựng ngoại tuyến có thể lặp lại được lưu trữ hoàn toàn trong kiểm soát phiên bản của bạn (dễ dàng hơn với maven so với lớp). Trong thế giới Golang, có thể xây dựng dựa trên giải pháp này để quản lý GOPATH của bạn thay vì go get. Trong thế giới python, có thể kết hợp điều này với virtualenv để tạo ra một môi trường phát triển khép kín mà không cần dựa vào các máy chủ PyPi cho mọi bản dựng từ đầu.

  • Nếu tập tin nhị phân của bạn thay đổi rất thường xuyên, như xây dựng hiện vật, nó có thể là một ý tưởng tốt để kịch bản một giải pháp mà các cửa hàng 5 hầu hết các phiên bản gần đây của các đồ tạo tác trong các thẻ mồ côi monday_bin, tuesday_bin, ..., friday_bin, và cũng là một đứa trẻ mồ côi từ khóa cho mỗi bản phát hành 1.7.8bin 2.0.0bin, v.v. Bạn có thể xoay weekday_binvà xóa các nhị phân cũ hàng ngày. Bằng cách này, bạn sẽ có được hai thế giới tốt nhất: bạn giữ toàn bộ lịch sử mã nguồn của mình nhưng chỉ lịch sử liên quan đến các phụ thuộc nhị phân của bạn. Cũng rất dễ dàng để có được các tệp nhị phân cho một thẻ nhất định mà không cần lấy toàn bộ mã nguồn với tất cả lịch sử của nó: git init && git remote add <name> <url> && git fetch <name> <tag>nên làm điều đó cho bạn.


"Bạn phải định kỳ sử dụng git gc" - dừng đọc ngay tại đó. Tại sao bất cứ ai sẽ từ bỏ vành đai an toàn cuối cùng của họ để ủng hộ một số hack?
dùng1643723

@ user1643723 git gckhông an toàn để chạy. Tất cả các cam kết lơ lửng của bạn sẽ được giữ an toàn trên ổ cứng trong ít nhất 30 ngày theo mặc định: git-scm.com/docs/git-gc
Adam Kurkiewicz

Cảm ơn đã viết chi tiết. Tôi muốn thử điều này như một cách để lưu trữ một số phụ thuộc nhị phân trong repo GitHub của tôi theo cách mà chúng không được tải xuống theo mặc định khi ai đó sao chép repo, nhưng có thể được tải xuống thủ công & cập nhật repo cục bộ. Tuy nhiên, tôi đã gặp một lỗi ở bước này: git push <remote> 1.0.0bin- remote: error: GH001: Large files detected. You may want to try Git Large File Storage. Có vẻ như có lẽ GitHub không còn hỗ trợ điều này? Nhị phân trong câu hỏi có kích thước 100MB.
dùng5359531

1
Thành thật mà nói, nếu bạn được phép sử dụng github cho công việc của mình, điều gì ngăn bạn sử dụng LFS? Những người tại github đã làm việc chăm chỉ để tạo ra sản phẩm này và thậm chí họ còn lưu trữ nó cho bạn và cơ sở hạ tầng của họ được tối ưu hóa khi sử dụng nó. Hack này có nghĩa là cho các tình huống khi bạn thực sự không thể sử dụng LFS hoặc các bên thứ ba khác và bạn đang theo đuổi một giải pháp thuần túy.
Adam Kurkiewicz

Tôi cũng đã cập nhật câu trả lời để rõ hơn về giải pháp thực sự của hacky này.
Adam Kurkiewicz

13

Theo tôi, nếu bạn có thể thường xuyên sửa đổi các tệp lớn đó hoặc nếu bạn có ý định tạo ra nhiều git clonehoặc git checkout, thì bạn nên nghiêm túc xem xét sử dụng kho lưu trữ Git khác (hoặc có thể là một cách khác để truy cập các tệp đó).

Nhưng nếu bạn làm việc như chúng tôi và nếu các tệp nhị phân của bạn không thường xuyên được sửa đổi, thì bản sao / kiểm tra đầu tiên sẽ dài, nhưng sau đó sẽ nhanh như bạn muốn (xem xét người dùng của bạn tiếp tục sử dụng kho lưu trữ nhân bản đầu tiên. đã).


13
Và, các repos riêng biệt sẽ không làm cho thời gian thanh toán ngắn hơn nữa, vì bạn vẫn phải kiểm tra cả hai repos!
Emil Ngồi

@EmilSit repo riêng biệt có thể làm cho việc thanh toán ngắn hơn rất nhiều nếu bạn xóa sạch lịch sử của "repo nhị phân". Hơn nữa, các nhà phát triển sẽ không bị buộc phải kiểm tra cả hai repos mỗi lần .
FabienAndre

Tại sao không chỉ có tập lệnh xây dựng của mô-đun chính lấy các tệp nhị phân từ repo thứ hai, trích xuất từng cái một (như ở đây: stackoverflow.com/questions/1125476/ .)
akauppi

1
Ngay cả khi các tệp nhị phân của bạn không thay đổi thường xuyên, các tệp lớn vẫn có thể giết chết luồng công việc của bạn nếu bạn thường đẩy các nhánh đến kho lưu trữ cho mục đích cộng tác.
Timo Reimann

9

SVN dường như xử lý đồng bằng nhị phân hiệu quả hơn Git.

Tôi đã phải quyết định một hệ thống phiên bản cho tài liệu (tệp JPEG, tệp PDF và tệp .odt). Tôi vừa thử nghiệm thêm một tệp JPEG và xoay nó 90 độ bốn lần (để kiểm tra hiệu quả của deltas nhị phân). Kho lưu trữ của Git tăng 400%. Kho lưu trữ của SVN chỉ tăng 11%.

Vì vậy, có vẻ như SVN hiệu quả hơn nhiều với các tệp nhị phân.

Vì vậy, lựa chọn của tôi là Git cho mã nguồn và SVN cho các tệp nhị phân như tài liệu.


33
Bạn chỉ cần chạy "git gc" (đóng gói lại và thu gom rác) sau khi thêm 4 tệp đó. Git không nén ngay lập tức tất cả nội dung đã thêm, do đó bạn sẽ có một nhóm nén tệp (hiệu quả hơn về kích thước) và sẽ không bị chậm khi nén riêng từng đối tượng được thêm vào đó. Nhưng ngay cả khi không có "git gc", git cuối cùng cũng sẽ thực hiện việc nén cho bạn (sau khi nhận thấy, đủ các đối tượng chưa giải nén đã tích lũy).
nightingale

24
@jpierson Tôi đã tạo một kho git trống và thêm (và đã cam kết) một hình ảnh bmp hoàn toàn trắng với kích thước 41MB, điều này dẫn đến tổng kho git với kích thước là 328KB. Sau khi git gctổng kích thước kho git đã giảm xuống còn 184KB. Sau đó, tôi đã thay đổi một pixel từ trắng sang đen và cam kết thay đổi này, tổng kích thước kho git tăng lên tới 388KB và sau khi git gckích thước của tổng kho git đã giảm xuống còn 184KB. Điều này cho thấy git khá tốt trong việc nén và tìm deltas của các tệp nhị phân.
Tader

6
@jpierson Một sidenote: Tôi chỉ nhận xét về deltas nhị phân. Git sẽ ăn hết bộ nhớ của bạn và trao đổi nếu nó đang quản lý kho lưu trữ với các tệp lớn (kích thước GB). Đối với điều này, sử dụng git-annex (đã được đề cập trong một câu trả lời khác) ...
Tader

12
@JanDvorak - không ai nhắc đến nó, vì nó hoàn toàn sai sự thật. Subversion Bản sao có giá rẻ - svnbook.red-bean.com/en/1.7/svn.branchmerge.USE.html - khoảng giữa trang.
Joris Timmermans

12
@Tader: bài kiểm tra của bạn rất tệ. Trên thực tế, cái mà bạn gọi là tệp nhị phân (theo quan điểm của git) giống với tệp văn bản hơn - dòng bit được căn chỉnh theo byte và có những khác biệt có ý nghĩa, được bản địa hóa; xét cho cùng, thay đổi một pixel về cơ bản tương đương với thay đổi một ký tự trong tệp văn bản (và hiện tại ai đang sử dụng bitmap không nén?) Hãy thử cùng một thử nghiệm với một video nhỏ, hình ảnh nén, máy ảo, zipfile hoặc bất cứ điều gì - và bạn sẽ tìm thấy git đó không đối phó hiệu quả với đồng bằng; thực sự về cơ bản là không thể với dữ liệu không thể nén được.
Eamon Nerbonne

4

git clone --filter từ Git 2.19 + phân thân nông

Tùy chọn mới này cuối cùng có thể trở thành giải pháp cuối cùng cho vấn đề tệp nhị phân, nếu Git và GitHub phát triển và làm cho nó đủ thân thiện với người dùng ( ví dụ như họ vẫn chưa đạt được cho các mô hình con ).

Nó cho phép thực sự chỉ tìm nạp các tệp và thư mục mà bạn muốn cho máy chủ và được giới thiệu cùng với một phần mở rộng giao thức từ xa.

Với điều này, trước tiên chúng ta có thể thực hiện một bản sao nông, và sau đó tự động hóa các đốm màu để tìm nạp với hệ thống xây dựng cho từng loại bản dựng.

Thậm chí đã có một --filter=blob:limit<size>cái cho phép giới hạn kích thước blob tối đa để tìm nạp.

Tôi đã cung cấp một ví dụ chi tiết tối thiểu về tính năng trông như thế nào : Làm cách nào để sao chép thư mục con chỉ của kho lưu trữ Git?


2

Tôi đang tìm kiếm ý kiến ​​về cách xử lý các tệp nhị phân lớn mà mã nguồn của tôi (ứng dụng web) phụ thuộc vào. Kinh nghiệm / suy nghĩ của bạn về điều này là gì?

Cá nhân tôi đã gặp phải lỗi đồng bộ hóa với Git với một số máy chủ lưu trữ đám mây của mình một khi dữ liệu nhị phân của ứng dụng web của tôi được ghi nhận trên mức 3 GB . Tôi đã xem xét BFT Repo Cleaner tại thời điểm đó, nhưng nó cảm thấy giống như một hack. Kể từ đó, tôi bắt đầu chỉ giữ các tệp bên ngoài Git purview, thay vào đó tận dụng các công cụ được xây dựng có mục đích như Amazon S3 để quản lý tệp, tạo phiên bản và sao lưu.

Có ai có kinh nghiệm với nhiều kho Git và quản lý chúng trong một dự án không?

Đúng. Chủ đề Hugo chủ yếu được quản lý theo cách này. Đó là một chút kudgy, nhưng nó hoàn thành công việc.


Đề nghị của tôi là chọn công cụ phù hợp cho công việc . Nếu đó là cho một công ty và bạn đang quản lý dòng tiền của mình trên GitHub, hãy trả tiền và sử dụng Git-LFS. Nếu không, bạn có thể khám phá các tùy chọn sáng tạo hơn như lưu trữ tệp được mã hóa, phi tập trung bằng cách sử dụng blockchain .

Các tùy chọn bổ sung để xem xét bao gồm Minios3cmd .


0

Có một cái nhìn tại camlistore . Nó không thực sự dựa trên Git, nhưng tôi thấy nó phù hợp hơn với những gì bạn phải làm.

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.