Masalah Fail Besar di Git
Secara tradisinya, syarikat dan institusi tertentu menjauhkan diri dari Git kerana ketidakcekapan dalam pengendalian fail binari yang besar. Pembangun permainan video dan syarikat media harus berurusan dengan tekstur kompleks, video gerakan penuh, dan fail audio berkualiti tinggi. Institut penyelidikan harus mengawasi set data besar yang dapat berupa gigabyte atau terabyte. Git sukar mengekalkan fail besar ini.
Untuk memahami masalahnya, kita perlu melihat bagaimana Git memantau fail. Setiap kali ada komit, Git membuat simpul objek dengan penunjuk kepada ibu bapa atau ibu bapa berganda. Model data Git dikenali sebagai graf asiklik terarah (DAG). Model DAG memastikan hubungan ibu bapa-ke-anak tidak dapat membentuk sebarang kitaran.
Kami dapat memeriksa cara kerja dalaman model DAG. Berikut adalah contoh tiga komit di repositori:
$ git log - talian2beb263 Komit C: tambah gambar1.jpeg
866178e Komitmen B: tambah b.txt
d48dd8b Komit A: tambah a.txt
Dalam Komit A dan B, kami menambahkan fail teks a.txt dan b.txt. Kemudian di Commit C, kami menambahkan fail gambar yang disebut image1.jpeg. Kami dapat menggambarkan DAG seperti berikut:
Komit C Komitmen B Komitmen A2beb263 -> 866178e -> d48dd8b
Sekiranya kita memeriksa komit terakhir dengan arahan berikut:
$ git cat-file -p 2beb263pokok 7cc17ba5b041fb227b9ab5534d81bd836183a4e3
ibu bapa 866178e37df64d9f19fa77c00d5ba9d3d4fc68f5
pengarang Zak H
pelaku Zak H
Komit C: tambah gambar1.jpeg
Kita dapat melihat bahawa Commit C (2beb263) mempunyai Commit B (866178e) sebagai induk. Sekarang jika kita memeriksa objek pokok Commit C (7cc17ba), kita dapat melihat gumpalan (objek besar binari):
$ git cat-file -p 7cc17ba100644 gumpalan e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a.txt
100644 gumpalan e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 b.txt
100644 gumpalan a44a66f9e06a8faf324d3ff3e11c9fa6966bfb56 gambar1.jpeg
Kami dapat memeriksa ukuran gumpalan gambar:
$ git cat-file -s a44a66f9e871680
Git mengawasi perubahan struktur pokok ini. Mari buat pengubahsuaian pada gambar1.jpeg dan periksa sejarah:
$ git log - talian2e257db Komitmen D: gambar yang diubah suai1.jpeg
2beb263 Komit C: tambah gambar1.jpeg
866178e Komitmen B: tambah b.txt
d48dd8b Komit A: tambah a.txt
Sekiranya kita memeriksa objek Commit D (2e257db):
$ git cat-file -p 2e257dbpokok 2405fad67610acf0f57b87af36f535c1f4f9ed0d
ibu bapa 2beb263523725e1e8f9d96083140a4a5cd30b651
pengarang Zak H
pelaku Zak H
Komitmen D: gambar yang diubah suai1.jpeg
Dan pokok (2405fad) di dalamnya:
$ git cat-file -p 2405fad100644 gumpalan e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 a.txt
100644 gumpalan e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 b.txt
100644 gumpalan cb4a0b67280a92412a81c60df36a15150e713095 gambar1.jpeg
Perhatikan bahawa hash SHA-1 untuk gambar1.jpeg telah berubah. Ini bermaksud ia telah mencipta gumpalan baru untuk image1.jpeg. Kami dapat memeriksa ukuran gumpalan baru:
$ git cat-file -s cb4a0b61063696
Berikut adalah cara untuk menggambarkan struktur DAG di atas:
Komit D Komitmen C Komitmen B Komitmen A| | | |
2e257db -> 2beb263 -> 866178e -> d48dd8b
| | | |
Pokok4 Pokok3 Pohon2 Pokok1
| | | |
Gumpalan gumpalan gumpalan gumpalan
Setiap objek komit mengekalkan pokoknya sendiri. Gumpalan dikekalkan di dalam pokok itu. Git mengoptimumkan ruang dengan memastikan ia hanya menyimpan perbezaan dan menggunakan pemampatan untuk penyimpanan. Tetapi untuk perubahan fail binari, Git harus menyimpan keseluruhan fail dalam gumpalan kerana sukar untuk menentukan perbezaannya. Juga, fail gambar, video dan audio sudah dimampatkan. Akibatnya, untuk setiap contoh fail binari yang diubah, pokok berakhir dengan gumpalan besar.
Mari kita fikirkan satu contoh di mana kita membuat banyak perubahan pada fail gambar 100 MB.
Komit C -> Komitmen B -> Komitmen A| | |
Pokok3 Pokok2 Pokok1
| | |
Blob3 Blob2 Blob1
300 MB 200MB 100MB
Setiap kali kita menukar fail, Git harus membuat gumpalan 100 MB. Oleh itu, hanya selepas 3 komit, repositori Git adalah 300 MB. Anda dapat melihat bahawa ukuran repositori Git dapat meletup dengan cepat. Kerana Git adalah kawalan versi yang diedarkan, anda akan memuat turun keseluruhan repositori ke contoh tempatan anda dan banyak bekerja dengan cawangan. Oleh itu, gumpalan besar menjadi hambatan prestasi.
Git LFS menyelesaikan masalah dengan mengganti gumpalan dengan fail penunjuk ringan (PF) dan membuat mekanisme untuk menyimpan gumpalan di tempat lain.
Komit C -> Komitmen B -> Komitmen A| | |
Pokok3 Pokok2 Pokok1
| | |
PF3 PF2 PF1
Git secara tempatan menyimpan gumpalan dalam cache Git LFS, dan dari jauh ia akan menyimpannya di kedai Git LFS di GitHub atau BitBucket.
PF1 -> Blob1PF2 -> Blob2
PF3 -> Blob3
Sekarang apabila anda berurusan dengan repositori Git, fail PF ringan akan digunakan untuk operasi rutin. Gumpalan hanya akan diambil apabila perlu. Sebagai contoh, jika anda membuat pembayaran Komit C, maka Git LFS akan mencari penunjuk PF3 dan memuat turun Blob3. Oleh itu, repositori yang berfungsi akan lebih ramping dan prestasinya akan lebih baik. Anda tidak perlu risau tentang fail penunjuk. Git LFS akan menguruskannya di belakang tabir.
Memasang dan Menjalankan Git LFS
Terdapat usaha sebelumnya untuk menyelesaikan masalah fail besar Git. Tetapi Git LFS telah berjaya kerana senang digunakan. Anda hanya perlu memasang LFS dan memberitahu fail mana yang hendak dijejaki.
Anda boleh memasang Git LFS menggunakan arahan berikut:
$ sudo apt-get install software-properties-common$ curl -s https: // packagecloud.io / install / repositori / github / git-lfs / skrip.deb.sh | sudo bash
$ sudo apt-get install git-lfs
$ git lfs memasang
Setelah memasang Git LFS, anda boleh mengesan fail yang anda mahukan:
trek $ git lfs "*.jpeg "Penjejakan "*.jpeg "
Hasilnya menunjukkan bahawa Git LFS sedang mengesan fail JPEG. Apabila anda mula menjejaki dengan LFS, anda akan menemui .fail gitattributes yang akan mempunyai entri yang menunjukkan fail yang dilacak. The .fail gitattributes menggunakan notasi yang sama seperti .fail gitignore. Inilah caranya kandungan .gitattribut kelihatan:
$ kucing .gitattribut*.penapis jpeg = lfs diff = lfs penggabungan = lfs -teks
Anda juga dapat mencari fail mana yang dilacak menggunakan perintah berikut:
trek $ git lfsMenyenaraikan corak yang dikesan
*.jpeg (.sifat gitatt)
Sekiranya anda ingin berhenti menjejaki fail, anda boleh menggunakan perintah berikut:
$ git lfs unrack "*.jpeg "Tidak menjejaki "*.jpeg "
Untuk operasi Git umum, anda tidak perlu risau tentang LFS. Ia akan menguruskan semua tugas backend secara automatik. Setelah anda menyediakan Git LFS, anda boleh mengerjakan repositori seperti projek lain.
Sambung belajar
Untuk topik yang lebih maju, lihat sumber berikut:
- Memindahkan repositori Git LFS antara host
- Memadam fail Local Git LFS
- Mengeluarkan fail Git LFS jauh dari pelayan
- Laman Web Git LFS
- Dokumentasi Git LFS
Rujukan:
- git-lfs.github.com: Repo GitHub
- github.com / git-lfs / git-lfs / tree / master / docs: Dokumentasi GitHub untuk Git LFS
- atlassian.com / git / tutorial / git-lfs: Tutorial Atlassian
- Youtube.com: Apa itu Git LFS
- Youtube.com: Menjejaki Fail Besar dengan Git LFS oleh Tim Pettersen, Atlassian
- Youtube.com: Menguruskan fail besar pada storan yang betul dengan Git LFS, YouTube
- Youtube.com: Penyimpanan Fail Besar Git - Cara Bekerja dengan Fail Besar, YouTube
- askubuntu.com / soalan / 799341: cara-pemasangan-git-lfs-di-ubuntu-16-04
- github.com / git-lfs / git-lfs / blob / master / MEMASANG.md: Panduan Pemasangan