Git lfs

Git lfs
Git har blitt de facto -versjonskontrollsystemet for programvareutviklere over hele verden. Dette open source, distribuerte versjonskontrollsystemet er raskere enn konkurrentene. Det er brukervennlig for forgrening og sammenslåing av kode. Imidlertid har det et ytelsesproblem med store binære filer. Git Large File Storage (LFS) ble utviklet for å løse dette problemet.

Det store filproblemet i git

Tradisjonelt har visse selskaper og institusjoner holdt seg unna Git på grunn av ineffektiviteten i stor binærfilhåndtering. Videospillutviklere og medieselskaper må håndtere komplekse teksturer, fullbevegelsesvideoer og lydfiler av høy kvalitet. Forskningsinstitutter må følge med på store datasett som kan være gigabyte eller terabyte. Git har problemer med å opprettholde disse store filene.

For å forstå problemet, må vi se på hvordan Git holder rede på filer. Hver gang det er en forpliktelse, oppretter Git en objektnode med en peker til foreldrene eller flere foreldre. Git -datamodellen er kjent som den rettede acykliske grafen (DAG). DAG-modellen sikrer at forholdet mellom foreldre og barn aldri kan danne noen sykluser.

Vi kan inspisere den indre funksjonen til DAG -modellen. Her er et eksempel på tre forpliktelser i et depot:

$ git log --oneline
2BEB263 Commit C: Lagt til Image1.JPEG
866178e Commit B: Legg til B.tekst
D48DD8B forplikter A: Legg til en.tekst

I forpliktelse A og B la vi til tekstfil a.txt og b.tekst. Så i Commit C la vi til en bildefil som heter Image1.JPEG. Vi kan visualisere DAG som følger:

Forpliktelse c forpliktelse b forpliktelse a
2BEB263 -> 866178E -> D48DD8B

Hvis vi inspiserer den siste forpliktelsen med følgende kommando:

$ git cat -fil -p 2beb263
tre 7cc17ba5b041fb227b9ab5534d81bd836183a4e3
Foreldre 866178e37df64d9f19fa77c00d5ba9d3d4fc68f5
Forfatter Zak H 1513259427 -0800
Committer Zak H 1513259427 -0800
Forplikt C: Lagt til Image1.JPEG

Vi kan se at Commit C (2BEB263) har forpliktelse B (866178E) som overordnede. Hvis vi inspiserer treobjektet med forpliktelse C (7CC17BA), kan vi se klatterne (binære store objekter):

$ git cat -fil -p 7cc17ba
100644 BLOB E69DE29BB2D1D6434B8B29AE775AD8C2E48C5391 A.tekst
100644 BLOB E69DE29BB2D1D6434B8B29AE775AD8C2E48C5391 B.tekst
100644 BLOB A44A66F9E06A8FAF324D3FF3E11C9FA6966BFB56 IMAGE1.JPEG

Vi kan sjekke størrelsen på bildeblomsten:

$ git cat -fil -s a44a66f9e
871680

Git holder rede på endringene i denne trestrukturen. La oss gjøre en modifisering av Image1.JPEG og sjekk historien:

$ git log --oneline
2E257DB Commit D: Modified Image1.JPEG
2BEB263 Commit C: Lagt til Image1.JPEG
866178e Commit B: Legg til B.tekst
D48DD8B forplikter A: Legg til en.tekst

Hvis vi sjekker Commit D -objektet (2E257DB):

$ git cat -fil -p 2e257db
tre 2405fad67610acf0f57b87af36f535c1f4f9ed0d
Foreldre 2BEB263523725E1E8F9D96083140A4A5CD30B651
Forfatter Zak H 1513272250 -0800
Committer Zak H 1513272250 -0800
Forpliktelse d: modifisert image1.JPEG

Og treet (2405fad) inni det:

$ git cat -fil -p 2405fad
100644 BLOB E69DE29BB2D1D6434B8B29AE775AD8C2E48C5391 A.tekst
100644 BLOB E69DE29BB2D1D6434B8B29AE775AD8C2E48C5391 B.tekst
100644 BLOB CB4A0B67280A92412A81C60DF36A15150E713095 Image1.JPEG

Legg merke til at SHA-1 hash for Image1.JPEG har endret seg. Det betyr at den har laget en ny klatt for image1.JPEG. Vi kan sjekke størrelsen på den nye Blob:

$ git cat -fil -s cb4a0b6
1063696

Her er en måte å visualisere den ovennevnte DAG -strukturen:

Forpliktelse d forpliktelse c forpliktelse b forpliktelse a
| | | |
2E257DB -> 2BEB263 -> 866178E -> D48DD8B
| | | |
Tree4 Tree3 Tree2 Tree1
| | | |
Klatter klatter klatter klatter
[/cce_c]
Hvert forpliktelsesobjekt opprettholder sitt eget tre. Klatter opprettholdes inne i det treet. Git optimaliserer plass ved å sørge for at den bare lagrer forskjellene og bruker komprimering for lagring. Men for endringer i binære filer, må Git lagre hele filer i klatterne fordi det er vanskelig å bestemme forskjellene. Også bilde, video- og lydfiler er allerede komprimert. Som et resultat, for hver forekomst av en modifisert binær fil, ender treet opp med en stor klatt.
La oss tenke på et eksempel der vi gjør flere endringer i en 100 MB -bildefil.
[CC bredde = "100%" høyde = "100%" rømte = "true" tema = "blackboard" nowrap = "0"]
Forplikte c -> forplikte b -> forpliktelse a
| | |
Tree3 Tree2 Tree1
| | |
Blob3 Blob2 Blob1
300 MB 200MB 100MB
[/cce_c]
Hver gang vi endrer filen, må Git opprette en 100 MB -klatt. Så først etter 3 forpliktelser er Git -depotet 300 MB. Du kan se at størrelsen på Git -depotet raskt kan blåse opp. Fordi Git er en distribuert versjonskontroll, vil du laste ned hele depotet til din lokale forekomst og jobbe med filialer mye. Så de store klatterne blir en flaskehals.
GIT LFS løser problemet ved å erstatte klattene med lette pekerfiler (PF) og lage en mekanisme for å lagre klatter andre steder.
[CC bredde = "100%" høyde = "100%" rømte = "true" tema = "blackboard" nowrap = "0"]
Forplikte c -> forplikte b -> forpliktelse a
| | |
Tree3 Tree2 Tree1
| | |
PF3 PF2 PF1
[/cce_c]
Lokalt lagrer Git Blobs i Git LFS -cachen, og eksternt vil den lagre dem i Git LFS -butikken på GitHub eller Bitbucket.
[CC bredde = "100%" høyde = "100%" rømte = "true" tema = "blackboard" nowrap = "0"]
PF1 -> Blob1
PF2 -> BLOB2
PF3 -> Blob3
[/cce_bash]
Nå når du har å gjøre med Git -depotet, vil de lette PF -filene bli brukt til rutinemessige operasjoner. Klatringene vil bare bli hentet når det er nødvendig. For eksempel, hvis du sjekker ut forplikte C, vil Git LFS slå opp PF3 -pekeren og laste ned BLOB3. Så det arbeidsstedet vil være slankere og ytelsen blir bedre. Du trenger ikke å bekymre deg for pekerfilene. Git LFS vil administrere dem bak kulissene.

Installere og kjøre Git LFS


Det har vært tidligere forsøk på å løse det store filproblemet. Men Git LFS har lyktes fordi det er enkelt å bruke. Du må bare installere LFS og fortelle det hvilke filer du vil spore.
Du kan installere GIT LFS ved å bruke følgende kommandoer:
[CC bredde = "100%" høyde = "100%" rømte = "true" tema = "blackboard" nowrap = "0"]
$ sudo apt-get install software-properties-common
$ Curl -S https: // packagecloud.IO/install/depoter/github/git-lfs/manus.Deb.sh | sudo bash
$ sudo apt-get install git-lfs
$ git lfs installasjon

Når du har installert Git LFS, kan du spore filene du ønsker:

$ git lfs spor "*.jpeg "
Sporing "*.jpeg "

Utgangen viser deg at Git LFS sporer JPEG -filene. Når du begynner å spore med LFS, finner du en .Gitattributes -fil som vil ha en oppføring som viser de sporede filene. De .gitattributter -fil Bruk den samme notasjonen som .Gitignore -fil. Slik er innholdet i .Gitattributter ser ut:

$ katt .gitattributter
*.JPEG -filter = LFS Diff = LFS Merge = LFS -Text

Du kan også finne hvilke filer som er sporet ved hjelp av følgende kommando:

$ git lfs spor
Liste over sporede mønstre
*.JPEG (.gitattributter)

Hvis du vil slutte å spore en fil, kan du bruke følgende kommando:

$ git lfs untrack "*.jpeg "
Untracking "*.jpeg "

For generelle git -operasjoner trenger du ikke å bekymre deg for LFS. Det vil ta vare på alle backend -oppgavene automatisk. Når du har satt opp Git LFS, kan du jobbe med depotet som alle andre prosjekt.


Videre studier

For mer avanserte emner, se på følgende ressurser:

  • Flytter Git LFS -depot mellom vertene
  • Slette lokale Git LFS -filer
  • Fjerning av eksterne Git LFS -filer fra serveren
  • Git LFS nettsted
  • Git LFS -dokumentasjon

Referanser:

  • git-lfs.github.com: github repo
  • github.com/git-lfs/git-lfs/tree/master/docs: github dokumentasjon for git lfs
  • Atlassian.com/git/tutorials/git-lfs: Atlassian tutorials
  • YouTube.com: Hva er git lfs
  • YouTube.com: Sporing av enorme filer med Git LFS av Tim Pettersen, Atlassian
  • YouTube.com: Administrere enorme filer på riktig lagring med git lfs, youtube
  • YouTube.com: git stor fillagring - Hvordan jobbe med store filer, YouTube
  • github.com/git-lfs/git-lfs/blob/master/installering.MD: Installasjonsveiledning