Zarządzanie dużymi plikami binarnymi za pomocą Git

523

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:

  1. 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.
  2. 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.
  3. 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.

Liczba Pi.
źródło
26
A co, gdy konieczna jest wersja kontrolująca plik binarny? Myślę o zespołach artystów pracujących nad aktywami.
Dan
3
Jeśli jest to konieczne, musisz zrównoważyć dostępne zasoby (dysk, przepustowość, czas procesora) z uzyskaną korzyścią.
pi.
4
Zauważ, że bez blokowania plików, git nie jest świetny, gdy wiele osób musi pracować na tym samym pliku binarnym.
yoyo
1
Zobacz także plik kopii zapasowej oparty na git .
VonC
1
Oto one bestechvideos.com/tag/gitcasts
doughgle

Odpowiedzi:

177

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-submoduledo 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ędzie git-submodulepowinno pomóc w utrzymaniu poprawnej wersji kodu zgodnej z poprawną wersją obrazów.

Oto dobre wprowadzenie do submodułów z Git Book.

Pat Notz
źródło
11
„Rozumiem, że masz tylko jedną odpowiednią wersję podmodułu swoich zdjęć”. Nie sądzę, żeby to było poprawne.
Robin Green,
22
W rzeczy samej. Podmoduł to pełne repozytorium Git, które po prostu zagnieżdżone jest w repozytorium nadrzędnym. Zna całą swoją historię. Możesz w nim popełniać rzadziej, ale jeśli przechowujesz w nim te same rzeczy, które miałbyś w rodzicu, będą miały te same problemy, co rodzic.
Cascabel
5
Jest to dość kiepskie rozwiązanie, jeśli masz duże pliki binarne, które zmieniają się w regularnych odstępach czasu. Mamy repozytorium, które jest strasznie rozdęte, ponieważ nowy plik binarny jest zapisywany w nim przy każdej kompilacji. Jeśli nie korzystasz z systemu Windows, jak wspomniano poniżej, dobrym rozwiązaniem jest załącznik. Jeśli korzystasz z systemu Windows ... będziesz musiał nadal szukać.
AA Grapsas
4
Innym problemem związanym z posiadaniem dużych plików binarnych w repozytorium jest wydajność. Git nie został zaprojektowany do obsługi dużych plików binarnych, a gdy rozmiar repo wzrośnie do 3G +, wydajność szybko spada. Oznacza to, że posiadanie dużych plików binarnych w repozytorium ogranicza opcje hostingu.
zoul
Podmoduły mogą zmniejszyć wymagania dotyczące przesyłania danych do kasy, jeśli twórczo niewłaściwie wykorzystasz submoduł: jeśli chcesz zaktualizować zawartość submodułu, utwórz nowy zatwierdzenie bez elementu nadrzędnego, a następnie skieruj superprojekt (główne repozytorium git) do nowo utworzonego zatwierdzenia bez elementu nadrzędnego. Logicznie tworzy to odłączoną historię dla podmodułu, ale w zamian każda wersja tego podmoduła jest łatwiejsza do przeniesienia, ponieważ ta wersja nie ma historii.
Mikko Rantalainen,
310

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 .:

$ 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

Dostępnych jest wiele poleceń, a na stronie znajduje się świetna dokumentacja. Pakiet jest dostępny na Debianie .

rafak
źródło
11
Zaraz! Głosuj za wspaniałość! To wdraża pomysł, który ostatnio miałem, i wiele więcej. Jest napisany nie mniej w Haskell. Nawiasem mówiąc, git-media jest dobrą alternatywą.
cdunn2001
33
Ale załącznik nie obsługuje systemu Windows. Co jest problematyczne dla twórców gier.
AA Grapsas
7
Słyszałem, że Steam rezygnuje z obsługi okien i dodaje obsługę Linuksa ...;) poważnie, ale jak ciężko może to być portowane? Myślę, że twój przeciętny twórca gier mógłby to zrobić.
Sam Watkins,
4
@EstebanBrenes Prawdziwym rozwiązaniem jest to, że w normalnej konfiguracji dowiązania symboliczne Windows wymagają podniesionych uprawnień do tworzenia.
Laurens Holst
4
Właśnie znalazłem tę stronę . Czyta, że ​​teraz git annexjest również dostępny w systemie Windows . Jeśli ktoś kiedykolwiek przetestował to w systemie Windows, chciałbym usłyszeć o jego doświadczeniach!
Kouichi C. Nakamura
49

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.

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

VonC
źródło
3
lfs-test-serverjest 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.
Stas,
Czy możesz sprawdzić poprzednie wersje takiego pliku binarnego za pomocą git lfs?
mucaho
1
@mucaho Powinieneś: składnia git checkout pozostaje niezmieniona, a skrypt smsge lfs powinien być nadal wywoływany.
VonC
31

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ć.

sehe
źródło
3
bup zapewnia pamięć (wewnętrznie przy użyciu archiwów parzystości dla redundancji i git do kompresji, deduplikacji i historii), ale nie rozszerza git. git-annex to rozszerzenie git, które zapewnia backend pamięci bup .
Tobu
@Tobu kiedy pisał ten, git aneks jeszcze nie istnieje (w wydaniach nurtu)
sehe
2
bup jest zdecydowanie interesujący do zarządzania dużymi plikami. Chciałem zwrócić uwagę na różnicę w interfejsie użytkownika: używasz poleceń bup poza kontekstem repozytorium, a git jest szczegółem implementacji.
Tobu
27

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:

git fat init
git fat push
git fat pull

Ponadto musisz zarejestrować plik .gitfat w repozytorium i zmodyfikować atrybuty .gitattat, aby określić rozszerzenia plików, którymi chcesz git fatzarządzać.

Dodajesz plik binarny przy użyciu normalnego git add, który z kolei wywołuje się git fatna 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 rsyncrobi.

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.

Carl
źródło
26

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-treei git-commit-treedo 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.

Daniel Fanjul
źródło
Zrobiłem kiedyś coś podobnego, gdzie musiałem podzielić jedno repozytorium, które przypadkowo połączyłem w dwa odrębne. Ciekawy wzór użytkowania. :)
pi.
1
Czy byłoby to tak samo jak po prostu: rm -f .git; git init; git add. ; git commit -m „Kosz historii”.
Pat Notz
1
Tak, tak samo jest tylko w moim przypadku mp3. Ale czasami nie chcesz dotykać swoich gałęzi i tagów (brak redukcji miejsca w publicznych repozytoriach), ale chcesz przyspieszyć „klonowanie / pobieranie / ściąganie” tylko gałęzi (mniej miejsca na dedykowane to-to- repozytoria oddziałów).
Daniel Fanjul
13

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

  • jest to rozwiązanie typu „ tylko git i git” - wykonuje zadanie bez żadnego oprogramowania zewnętrznego (takiego jak git-annex) lub infrastruktury innej firmy (jak LFS github).
  • skutecznie przechowuje pliki binarne , tzn. nie przesadza z historią Twojego repozytorium.
  • git pulli git fetch, w tym git fetch --allnadal są wydajne w zakresie przepustowości , tj. domyślnie nie wszystkie duże pliki binarne są pobierane ze zdalnego.
  • działa w systemie Windows .
  • przechowuje wszystko w jednym repozytorium git .
  • pozwala na usunięcie przestarzałych plików binarnych (w przeciwieństwie do bup).

Niepożądane właściwości OTABS

  • czyni to git clonepotencjalnie 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życia git clone -b master --single-branch <url>zamiast git 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 .
  • powoduje to, że git fetch <remote> --tagsprzepustowość jest nieefektywna, ale niekoniecznie nieefektywna. Zawsze możesz poradzić kolegom, aby go nie używali.
  • będziesz musiał okresowo korzystać ze git gcsztuczki, aby wyczyścić repozytorium z plików, których już nie chcesz.
  • nie jest tak wydajny jak bup lub git-bigfiles . Ale jest odpowiednio bardziej odpowiedni do tego, co próbujesz zrobić, i bardziej dostępny z półki. Prawdopodobnie będziesz mieć problemy z setkami tysięcy małych plików lub z plikami w zakresie gigabajtów, ale czytaj dalej w celu obejścia tego problemu.

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.

  1. Utwórz nową gałąź osieroconą. git checkout --orphan binaryStuffda 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.
  2. Wyczyść swój indeks za pomocą git rm --cached * .gitignore.
  3. Weź głęboki oddech i usuń całe działające drzewo za pomocą rm -fr * .gitignore. .gitKatalog wewnętrzny pozostanie nietknięty, ponieważ *symbol wieloznaczny nie pasuje do niego.
  4. Skopiuj do VeryBigBinary.exe lub VeryHeavyDirectory /.
  5. Dodaj i zatwierdz go.
  6. Teraz staje się to trudne - jeśli wepchniesz go do pilota jako gałąź, wszyscy twoi programiści pobiorą go następnym razem, gdy wywołają git fetchzatykanie 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 pisania git fetch <remote> --tags, ale czytają w celu obejścia tego problemu. Śmiało igit tag 1.0.0bin
  7. Wciśnij sierotę git push <remote> 1.0.0bin.
  8. Abyś nigdy nie przypadkowo wypchnął gałęzi binarnej, możesz ją usunąć git branch -D binaryStuff. Twoje zatwierdzenie nie zostanie oznaczone do odśmiecania, ponieważ wskazany na nim sierocy tag 1.0.0binwystarczy, aby utrzymać go przy życiu.

Sprawdzanie pliku binarnego

  1. Jak mogę (lub moi koledzy) pobrać VeryBigBinary.exe do bieżącego działającego drzewa? Jeśli Twoja obecna działająca gałąź to na przykład master, możesz po prostu git checkout 1.0.0bin -- VeryBigBinary.exe.
  2. To się nie powiedzie, jeśli nie 1.0.0binpobrałeś sierocego znacznika , w takim przypadku musisz to zrobić git fetch <remote> 1.0.0binwcześniej.
  3. Możesz dodać to VeryBigBinary.exedo 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:

  1. Usuń znacznik osierocony na pilocie git push <remote> :refs/tags/1.0.0bin
  2. Usuń lokalnie znacznik osierocony (usuwa wszystkie inne niepowiązane znaczniki) git tag -l | xargs git tag -d && git fetch --tags. Zaczerpnięte z SO 1841341 z niewielkimi modyfikacjami.
  3. Użyj sztuczki git gc, aby usunąć lokalnie teraz brak odwołania do zatwierdzenia. 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 1904860
  4. Jeśli to możliwe, powtórz lewę git gc na pilocie. Jest to możliwe, jeśli samo hostujesz swoje repozytorium i może nie być możliwe u niektórych dostawców git, takich jak github lub w niektórych środowiskach korporacyjnych. Jeśli prowadzisz hosting u dostawcy, który nie daje ci dostępu ssh do pilota, po prostu pozwól mu być. Możliwe jest, że infrastruktura twojego dostawcy wyczyści twoje niereferencyjne zatwierdzenie w swoim słodkim czasie. Jeśli pracujesz w środowisku korporacyjnym, możesz doradzić działowi IT, aby raz na tydzień uruchamiał śmieci cron, zbierając pilota. To, czy zrobią to, czy nie, nie będzie miało żadnego wpływu na Twój zespół pod względem przepustowości i pamięci, o ile doradzasz kolegom, aby zawsze git clone -b master --single-branch <url>zamiast tego git clone.
  5. Wszyscy twoi koledzy, którzy chcą pozbyć się przestarzałych tagów osieroconych, muszą zastosować tylko kroki 2-3.
  6. Następnie możesz powtórzyć kroki 1-8 dodawania plików binarnych, aby utworzyć nowy znacznik osierocony 2.0.0bin. Jeśli martwisz się, że koledzy piszą git fetch <remote> --tags, możesz to nazwać ponownie 1.0.0bin. Zapewni to, że następnym razem, gdy pobiorą wszystkie tagi, stare nie 1.0.0binbę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ć -ftego 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łkowitegoupdate 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 --offlineaby 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 zamiast go 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 wydania 1.7.8bin 2.0.0binitp. Możesz codziennie obracać weekday_bini 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.

Adam Kurkiewicz
źródło
„Musisz okresowo używać git gc” - przestał czytać w tym miejscu. Dlaczego ktokolwiek miałby zrezygnować z ostatniego pasa bezpieczeństwa na rzecz włamania?
user1643723,
@ user1643723 git gcnie 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-gc
Adam Kurkiewicz
Dziękuję za szczegółowy opis. Chciałem wypróbować to jako sposób na przechowywanie niektórych zależności binarnych w moim repozytorium GitHub w taki sposób, że domyślnie nie są one pobierane, gdy ktoś klonuje repozytorium, ale można je pobrać ręcznie i zaktualizować repozytorium lokalne. Jednak na tym etapie wystąpił błąd: git 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.
user5359531,
1
Szczerze mówiąc, jeśli możesz używać github do swojej pracy, co powstrzymuje cię przed używaniem LFS? Chłopaki z github ciężko pracowali nad stworzeniem tego produktu, a nawet go hostują, a ich infrastruktura jest zoptymalizowana pod kątem korzystania z niego. Ten hack jest przeznaczony do sytuacji, gdy naprawdę nie możesz korzystać z LFS lub innych stron trzecich i szukasz rozwiązania czystego gita.
Adam Kurkiewicz
Zaktualizowałem również odpowiedź, aby wyjaśnić, jak hackerskie jest to rozwiązanie.
Adam Kurkiewicz
13

Moim zdaniem, jeśli prawdopodobnie często modyfikujesz te duże pliki, lub jeśli zamierzasz zrobić dużo git clonelub git 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ł).

claf
źródło
13
Oddzielne repo nie skróci czasu realizacji transakcji, ponieważ nadal musisz sprawdzić oba repo!
Emil Sit
@EmilSit oddzielne repozytorium może sprawić, że kasa będzie znacznie krótsza, jeśli będziesz regularnie czyścić historię „repozytorium binarnego”. Co więcej, deweloperzy nie będą zmuszeni sprawdzać obu repozytoriów za każdym razem .
FabienAndre
Dlaczego po prostu skrypt skryptu kompilacji głównego modułu nie pobierze plików binarnych z drugiego repozytorium, wyodrębniając je jeden po drugim (jak tutaj: stackoverflow.com/questions/1125476/… ).
akauppi
1
Nawet jeśli pliki binarne nie są często zmieniane, duże pliki mogą nadal zabijać przepływ pracy, jeśli często wypychasz gałęzie do repozytorium w celu współpracy.
Timo Reimann,
9

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.

Tony Diep
źródło
33
Wystarczy dodać „git gc” (przepakowywanie i odśmiecanie) po dodaniu tych 4 plików. Git nie kompresuje od razu całej dodanej zawartości, dzięki czemu będziesz mieć kompresję grupy plików (która jest bardziej wydajna pod względem rozmiaru) i nie będziesz spowalniać oddzielnej kompresji każdego dodanego obiektu. Ale nawet bez „git gc”, git i tak zrobiłby dla ciebie kompresję (po tym, jak zauważył, że zgromadziło się wystarczająco dużo rozpakowanych obiektów).
słowik
24
@ jpierson Utworzyłem puste repozytorium git i dodałem (i zatwierdziłem) całkowicie biały obraz bmp o rozmiarze 41 MB, co spowodowało całkowite repozytorium git o wielkości 328 KB. Po git gccał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 po git gczmniejszeniu rozmiaru całkowitego repozytorium git do 184 KB . To pokazuje, że git jest całkiem dobry w kompresowaniu i znajdowaniu delt plików binarnych.
Tader
6
@jpierson A sidenote: Właśnie skomentowałem delty binarne. Git zje całą pamięć i zamieni, jeśli będzie zarządzał repozytoriami z dużymi plikami (rozmiar GB). W tym celu użyj załącznika git (wspomnianego już w innej odpowiedzi) ...
Tader
12
@JanDvorak - nikt o tym nie wspominał, ponieważ jest to całkowicie nieprawda. Kopie Subversion są tanie - svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html - mniej więcej w połowie strony.
Joris Timmermans
12
@Tader: twój test jest zły. To, co nazywacie plikiem binarnym, jest w rzeczywistości (z punktu widzenia git) bardziej podobne do pliku tekstowego - strumień bitów jest wyrównany bajtowo, a do zrobienia są znaczące, zlokalizowane różnice; w końcu zmiana jednego piksela jest w zasadzie równoważna zmianie jednego znaku w pliku tekstowym (a kto obecnie używa nieskompresowanych map bitowych?) Spróbuj tego samego eksperymentu z małym wideo, skompresowanym obrazem, maszyną wirtualną, plikiem zip lub czymkolwiek - a znajdziesz ten git nie radzi sobie skutecznie z deltą; w istocie jest to zasadniczo niemożliwe w przypadku danych nieściśliwych.
Eamon Nerbonne,
4

git clone --filter z Git 2.19 + płytkie klony

Ta 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?

Ciro Santilli
źródło
2

Szukam opinii na temat obsługi dużych plików binarnych, od których zależy mój kod źródłowy (aplikacja internetowa). Jakie są twoje doświadczenia / przemyślenia na ten temat?

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.

Czy ktoś ma doświadczenie z wieloma repozytoriami Git i zarządzaniem nimi w jednym projekcie?

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 .

Josh Habdas
źródło
0

Spójrz na camlistore . Nie jest tak naprawdę oparty na Git, ale uważam, że jest bardziej odpowiedni do tego, co musisz zrobić.

Hernan
źródło