Szukam opinii na temat obsługi dużych plików binarnych, od których zależy mój kod źródłowy (aplikacja internetowa). Obecnie omawiamy kilka alternatyw:
- Skopiuj pliki binarne ręcznie.
- Pro: Nie jestem pewien.
- Przeciw: jestem zdecydowanie temu przeciwny, ponieważ zwiększa to prawdopodobieństwo błędów podczas konfigurowania nowej witryny / migrowania starej. Stwarza kolejną przeszkodę do pokonania.
- Zarządzaj nimi wszystkimi za pomocą Git .
- Pro: usuwa możliwość „zapomnienia” o skopiowaniu ważnego pliku
- Contra: Nadęża repozytorium i zmniejsza elastyczność zarządzania bazą kodu, a kasy, klony itp. Zajmą sporo czasu.
- Oddzielne repozytoria.
- Pro: Sprawdzanie / klonowanie kodu źródłowego jest szybkie jak zawsze, a obrazy są odpowiednio archiwizowane w ich własnym repozytorium.
- Contra: Usuwa prostotę posiadania jedynego repozytorium Git w projekcie. Z pewnością wprowadza kilka innych rzeczy, o których nie myślałem.
Jakie są twoje doświadczenia / przemyślenia na ten temat?
Ponadto: Czy ktoś ma doświadczenie z wieloma repozytoriami Git i zarządzaniem nimi w jednym projekcie?
Pliki są obrazami dla programu, który generuje pliki PDF z zawartymi w nich plikami. Pliki nie zmieniają się bardzo często (jak w latach), ale są bardzo istotne dla programu. Program nie będzie działać bez plików.
git
version-control
large-files
binaryfiles
Liczba Pi.
źródło
źródło
Odpowiedzi:
Jeśli program nie będzie działał bez plików, wydaje się, że podzielenie ich na osobne repozytorium jest złym pomysłem. Mamy duże pakiety testowe, które dzielimy na osobne repozytorium, ale są to naprawdę pliki „pomocnicze”.
Jednak możesz być w stanie zarządzać plikami w osobnym repozytorium, a następnie użyć
git-submodule
do wciągnięcia ich do projektu w rozsądny sposób. Tak więc nadal będziesz mieć pełną historię wszystkich swoich źródeł, ale, jak rozumiem, będziesz mieć tylko jedną odpowiednią wersję podmodułu swoich zdjęć. Narzędziegit-submodule
powinno pomóc w utrzymaniu poprawnej wersji kodu zgodnej z poprawną wersją obrazów.Oto dobre wprowadzenie do submodułów z Git Book.
źródło
Niedawno odkryłem załącznik git, który wydaje mi się niesamowity. Został zaprojektowany do wydajnego zarządzania dużymi plikami. Używam go do moich kolekcji zdjęć / muzyki (itp.). Rozwój git-Annex jest bardzo aktywny. Zawartość plików można usunąć z repozytorium Git, tylko hierarchia drzewa jest śledzona przez Git (poprzez dowiązania symboliczne). Jednak, aby uzyskać zawartość pliku, po pociągnięciu / pchnięciu konieczny jest drugi krok, np .:
Dostępnych jest wiele poleceń, a na stronie znajduje się świetna dokumentacja. Pakiet jest dostępny na Debianie .
źródło
git annex
jest również dostępny w systemie Windows . Jeśli ktoś kiedykolwiek przetestował to w systemie Windows, chciałbym usłyszeć o jego doświadczeniach!Kolejnym rozwiązaniem, od kwietnia 2015 r., Jest Git Large File Storage (LFS) (firmy GitHub).
Używa git-lfs (patrz git-lfs.github.com ) i przetestowano na serwerze, który go obsługuje: lfs-test-server :
metadane można przechowywać tylko w repozytorium git, a duży plik w innym miejscu.
źródło
lfs-test-server
jest zadeklarowany jako nieprzeznaczony do użytku produkcyjnego. Właściwie pracuję na produkcyjnym serwerze LFS ( github.com/artemkin/git-lfs-server ). Jest w toku, ale już można go naprawić, a my testujemy go na miejscu.Spójrz na git bup, który jest rozszerzeniem Git do inteligentnego przechowywania dużych plików binarnych w repozytorium Git.
Chciałbyś mieć go jako submoduł, ale nie będziesz musiał się martwić, że repozytorium będzie trudne w obsłudze. Jednym z przykładowych przypadków użycia jest przechowywanie obrazów VM w Git.
Właściwie nie widziałem lepszych współczynników kompresji, ale moje repozytoria nie mają naprawdę dużych plików binarnych.
Twój przebieg może się różnić.
źródło
Możesz także użyć git-fat . Podoba mi się, że to zależy tylko od zapasów Python i
rsync
. Obsługuje również zwykły obieg pracy Git, za pomocą następujących poleceń wyjaśniających:Ponadto musisz zarejestrować plik .gitfat w repozytorium i zmodyfikować atrybuty .gitattat, aby określić rozszerzenia plików, którymi chcesz
git fat
zarządzać.Dodajesz plik binarny przy użyciu normalnego
git add
, który z kolei wywołuje sięgit fat
na podstawie reguł gitattributes.Wreszcie ma tę zaletę, że miejsce, w którym faktycznie przechowywane są pliki binarne, może być współużytkowane przez repozytoria i użytkowników i obsługuje wszystko, co
rsync
robi.AKTUALIZACJA: Nie używaj git-fat, jeśli używasz mostu Git-SVN. Spowoduje to usunięcie plików binarnych z repozytorium Subversion. Jeśli jednak używasz czystego repozytorium Git, działa ono pięknie.
źródło
Użyłbym submodułów (jako Pat Notz) lub dwóch różnych repozytoriów. Jeśli zbyt często modyfikujesz swoje pliki binarne, to spróbuję zminimalizować wpływ ogromnego repozytorium czyszczącego historię:
Kilka miesięcy temu miałem bardzo podobny problem: ~ 21 GB plików MP3, niesklasyfikowane (złe nazwy, złe id3, nie wiem, czy podoba mi się ten plik MP3, czy nie ...) i powielone na trzech komputerach.
Użyłem zewnętrznego dysku twardego z głównym repozytorium Git i sklonowałem go na każdym komputerze. Następnie zacząłem klasyfikować je w zwykły sposób (pchanie, ciągnięcie, łączenie ... usuwanie i zmiana nazwy wiele razy).
Na koniec miałem tylko ~ 6 GB plików MP3 i ~ 83 GB w katalogu .git. Użyłem
git-write-tree
igit-commit-tree
do utworzenia nowego zatwierdzenia, bez przodków zatwierdzeń, i założyłem nową gałąź wskazującą na to zatwierdzenie. „Git log” dla tej gałęzi pokazał tylko jedno zatwierdzenie.Następnie usunąłem starą gałąź, zachowałem tylko nową gałąź, usunąłem dzienniki referencji i uruchomiłem „git prune”: potem moje foldery .git ważyły tylko ~ 6 GB ...
Możesz od czasu do czasu „wyczyścić” ogromne repozytorium w ten sam sposób: Twój „git clone” będzie szybszy.
źródło
Rozwiązanie, które chciałbym zaproponować, opiera się na sierocych gałęziach i lekkim nadużyciu mechanizmu tagów, odtąd zwanym * Orphan Tags Binary Storage (OTABS)
TL; DR 12-01-2017 Jeśli możesz korzystać z LFS github lub innej strony trzeciej, to zdecydowanie powinieneś. Jeśli nie możesz, czytaj dalej. Ostrzegamy, że to rozwiązanie jest hackem i powinno być traktowane jako takie.
Pożądane właściwości OTABS
git pull
igit fetch
, w tymgit fetch --all
nadal są wydajne w zakresie przepustowości , tj. domyślnie nie wszystkie duże pliki binarne są pobierane ze zdalnego.Niepożądane właściwości OTABS
git clone
potencjalnie nieefektywnym (ale niekoniecznie, w zależności od użytkowania) Jeśli wdrożyć to rozwiązanie może trzeba doradzić swoich kolegów do użyciagit clone -b master --single-branch <url>
zamiastgit clone
. Wynika to z tego, że git klonuje domyślnie dosłownie klonuje całe repozytorium, w tym rzeczy, na które normalnie nie chciałbyś tracić przepustowości, takie jak nieprecyzyjne zatwierdzenia. Zaczerpnięte z SO 4811434 .git fetch <remote> --tags
przepustowość jest nieefektywna, ale niekoniecznie nieefektywna. Zawsze możesz poradzić kolegom, aby go nie używali.git gc
sztuczki, aby wyczyścić repozytorium z plików, których już nie chcesz.Dodawanie plików binarnych
Przed rozpoczęciem upewnij się, że dokonałeś wszystkich zmian, twoje drzewo robocze jest aktualne, a Twój indeks nie zawiera żadnych niezatwierdzonych zmian. Dobrym pomysłem może być zepchnięcie wszystkich lokalnych oddziałów do zdalnego (github itp.) Na wypadek katastrofy.
git checkout --orphan binaryStuff
da rade. Powoduje to utworzenie gałęzi całkowicie odłączonej od jakiejkolwiek innej gałęzi, a pierwsze zatwierdzenie dokonane w tej gałęzi nie będzie miało elementu nadrzędnego, co spowoduje, że będzie to zatwierdzenie główne.git rm --cached * .gitignore
.rm -fr * .gitignore
..git
Katalog wewnętrzny pozostanie nietknięty, ponieważ*
symbol wieloznaczny nie pasuje do niego.git fetch
zatykanie połączenia. Można tego uniknąć, naciskając tag zamiast gałęzi. Może to nadal wpływać na przepustowość i pamięć systemu współpracownika, jeśli mają one zwyczaj pisaniagit fetch <remote> --tags
, ale czytają w celu obejścia tego problemu. Śmiało igit tag 1.0.0bin
git push <remote> 1.0.0bin
.git branch -D binaryStuff
. Twoje zatwierdzenie nie zostanie oznaczone do odśmiecania, ponieważ wskazany na nim sierocy tag1.0.0bin
wystarczy, aby utrzymać go przy życiu.Sprawdzanie pliku binarnego
git checkout 1.0.0bin -- VeryBigBinary.exe
.1.0.0bin
pobrałeś sierocego znacznika , w takim przypadku musisz to zrobićgit fetch <remote> 1.0.0bin
wcześniej.VeryBigBinary.exe
do swojego mistrza.gitignore
, aby nikt z twojego zespołu nie przypadkiem zanieczyścił główną historię projektu plikiem binarnym.Całkowicie usuwając plik binarny
Jeśli zdecydujesz się całkowicie usunąć VeryBigBinary.exe z lokalnego repozytorium, zdalnego repozytorium i repozytoriów współpracownika, możesz po prostu:
git push <remote> :refs/tags/1.0.0bin
git tag -l | xargs git tag -d && git fetch --tags
. Zaczerpnięte z SO 1841341 z niewielkimi modyfikacjami.git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@"
. Spowoduje to również usunięcie wszystkich innych niepowiązanych zatwierdzeń. Zaczerpnięte z SO 1904860git clone -b master --single-branch <url>
zamiast tegogit clone
.2.0.0bin
. Jeśli martwisz się, że koledzy piszągit fetch <remote> --tags
, możesz to nazwać ponownie1.0.0bin
. Zapewni to, że następnym razem, gdy pobiorą wszystkie tagi, stare nie1.0.0bin
będą się odwoływać i zostaną oznaczone do późniejszego wyrzucania elementów bezużytecznych (przy użyciu kroku 3). Kiedy próbujesz zastąpić tag na pilocie, musisz użyć-f
tego w następujący sposób:git push -f <remote> <tagname>
Posłowie
OTABS nie dotyka twojego głównego ani żadnego innego kodu źródłowego / gałęzi programistycznych. Hasła zatwierdzania, cała historia i niewielki rozmiar tych gałęzi pozostają nienaruszone. Jeśli już rozdęłeś swoją historię kodu źródłowego plikami binarnymi, musisz ją wyczyścić jako osobny kawałek pracy. Ten skrypt może być przydatny.
Potwierdzony do pracy w systemie Windows z git-bash.
Dobrym pomysłem jest zastosowanie zestawu standardowych trików, aby zwiększyć efektywność przechowywania plików binarnych. Częste uruchamianie
git gc
(bez żadnych dodatkowych argumentów) powoduje, że git optymalizuje podstawowe przechowywanie plików za pomocą binarnych delt. Jeśli jednak twoje pliki raczej nie będą podobne do zatwierdzonych, możesz całkowicie wyłączyć binarne delty. Dodatkowo, ponieważ nie ma sensu kompresować już skompresowanych lub zaszyfrowanych plików, takich jak .zip, .jpg lub .crypt, git pozwala wyłączyć kompresję podstawowej pamięci. Niestety jest to ustawienie „wszystko albo nic”, które wpływa również na kod źródłowy.Możesz napisać skrypt do części OTABS, aby umożliwić szybsze użycie. W szczególności wykonywanie skryptów w krokach 2–3 od całkowitego
update
usunięcia plików binarnych do haka git może dać przekonującą, ale być może niebezpieczną semantykę pobierania git („pobierz i usuń wszystko, co jest nieaktualne”).Możesz pominąć krok 4 Całkowicie usuwając pliki binarne, aby zachować pełną historię wszystkich zmian binarnych na pilocie, kosztem wzdęcia centralnego repozytorium. Lokalne repozytoria z czasem pozostaną szczupłe.
W świecie Java można połączyć to rozwiązanie z,
maven --offline
aby stworzyć odtwarzalną kompilację offline przechowywaną całkowicie w twojej kontroli wersji (łatwiej jest z maven niż z gradem). W świecie Golang możliwe jest wykorzystanie tego rozwiązania do zarządzania GOPATH zamiastgo get
. W świecie python można to połączyć z virtualenv, aby stworzyć niezależne środowisko programistyczne bez polegania na serwerach PyPi dla każdej kompilacji od zera.Jeśli pliki binarne zmieniają się bardzo często, jak budowania artefakty, to może być dobry pomysł, aby skrypt roztworze, który przechowuje 5 najnowsze wersje artefaktów w znacznikach sierocych
monday_bin
,tuesday_bin
, ...,friday_bin
, a także znacznik sierota dla każdego wydania1.7.8bin
2.0.0bin
itp. Możesz codziennie obracaćweekday_bin
i usuwać stare pliki binarne. W ten sposób otrzymujesz to, co najlepsze z dwóch światów: przechowujesz całą historię kodu źródłowego, ale tylko odpowiednią historię zależności binarnych. Bardzo łatwo jest również pobrać pliki binarne dla danego znacznika bez pobierania całego kodu źródłowego z całą jego historią:git init && git remote add <name> <url> && git fetch <name> <tag>
należy to zrobić za Ciebie.źródło
git gc
” - przestał czytać w tym miejscu. Dlaczego ktokolwiek miałby zrezygnować z ostatniego pasa bezpieczeństwa na rzecz włamania?git gc
nie jest niebezpieczny w uruchomieniu. Wszystkie zwisające zobowiązania będą domyślnie bezpiecznie przechowywane na dysku twardym przez co najmniej 30 dni: git-scm.com/docs/git-gcgit push <remote> 1.0.0bin
-remote: error: GH001: Large files detected. You may want to try Git Large File Storage
. Wygląda na to, że GitHub już tego nie obsługuje? Plik binarny miał rozmiar 100 MB.Moim zdaniem, jeśli prawdopodobnie często modyfikujesz te duże pliki, lub jeśli zamierzasz zrobić dużo
git clone
lubgit checkout
, powinieneś poważnie rozważyć użycie innego repozytorium Git (lub może innego sposobu dostępu do tych plików).Ale jeśli pracujesz tak jak my, a twoje pliki binarne nie są często modyfikowane, pierwszy klon / kasa będzie długi, ale potem powinien być tak szybki, jak chcesz (biorąc pod uwagę, że użytkownicy nadal używają pierwszego sklonowanego repozytorium, miał).
źródło
SVN wydaje się radzić sobie z deltami binarnymi wydajniej niż Git.
Musiałem zdecydować się na system kontroli wersji dokumentacji (pliki JPEG, pliki PDF i pliki .odt). Właśnie przetestowałem dodanie pliku JPEG i czterokrotne obrócenie go o 90 stopni (aby sprawdzić skuteczność delt binarnych). Repozytorium Gita wzrosło o 400%. Repozytorium SVN wzrosło tylko o 11%.
Wygląda więc na to, że SVN jest znacznie wydajniejszy w przypadku plików binarnych.
Więc wybrałem Git dla kodu źródłowego i SVN dla plików binarnych, takich jak dokumentacja.
źródło
git gc
całkowitym rozmiarze repozytorium git zmniejszono do 184 KB. Następnie zmieniłem pojedynczy piksel z białego na czarny i zatwierdziłem tę zmianę, całkowity rozmiar repozytorium git zwiększył się do 388 KB, a pogit gc
zmniejszeniu rozmiaru całkowitego repozytorium git do 184 KB . To pokazuje, że git jest całkiem dobry w kompresowaniu i znajdowaniu delt plików binarnych.git clone --filter
z Git 2.19 + płytkie klonyTa nowa opcja może ostatecznie stać się ostatecznym rozwiązaniem problemu z plikiem binarnym, jeśli deweloperzy Git i GitHub uczynią go wystarczająco przyjaznym dla użytkownika (czego zapewne wciąż nie osiągnęli dla podmodułów ).
Umożliwia pobieranie plików i katalogów tylko dla serwera i został wprowadzony wraz ze zdalnym rozszerzeniem protokołu.
Dzięki temu możemy najpierw wykonać płytki klon, a następnie zautomatyzować, które obiekty BLOB mają być pobierane za pomocą systemu kompilacji dla każdego typu kompilacji.
Jest nawet już
--filter=blob:limit<size>
która pozwala ograniczyć maksymalny rozmiar obiektu blob do pobrania.Podałem minimalny szczegółowy przykład tego, jak wygląda ta funkcja: Jak sklonować podkatalog tylko repozytorium Git?
źródło
Osobiście natknąłem się na awarie synchronizacji z Git na niektórych moich hostach w chmurze, gdy moje dane binarne aplikacji internetowych spadły powyżej 3 GB . Zastanawiałem się wtedy nad BFT Repo Cleaner , ale czułem się jak hack. Od tego czasu zacząłem trzymać pliki poza zasięgiem Git, zamiast tego wykorzystując specjalnie zaprojektowane narzędzia, takie jak Amazon S3, do zarządzania plikami, wersjonowania i tworzenia kopii zapasowych.
Tak. Motywami Hugo zarządza się przede wszystkim w ten sposób. To trochę kudłate, ale wykonuje pracę.
Moją propozycją jest wybranie odpowiedniego narzędzia do pracy . Jeśli jest to dla firmy i zarządzasz linią w GitHub, zapłać pieniądze i skorzystaj z Git-LFS. W przeciwnym razie możesz odkryć bardziej kreatywne opcje, takie jak zdecentralizowane, szyfrowane przechowywanie plików za pomocą blockchain .
Dodatkowe opcje do rozważenia to Minio i s3cmd .
źródło
Spójrz na camlistore . Nie jest tak naprawdę oparty na Git, ale uważam, że jest bardziej odpowiedni do tego, co musisz zrobić.
źródło