Mengelola file biner besar dengan Git

523

Saya mencari pendapat tentang bagaimana menangani file biner besar yang menjadi sandaran kode sumber (aplikasi web) saya. Kami sedang mendiskusikan beberapa alternatif:

  1. Salin file biner dengan tangan.
    • Pro: Tidak yakin.
    • Kontra: Saya sangat menentang ini, karena meningkatkan kemungkinan kesalahan ketika membuat situs baru / memigrasikan yang lama. Membangun rintangan lain untuk diambil.
  2. Kelola semuanya dengan Git .
    • Pro: Menghapus kemungkinan untuk 'lupa' untuk menyalin file penting
    • Contra: Membengkak repositori dan mengurangi fleksibilitas untuk mengelola basis kode dan checkout, klon, dll. Akan memakan waktu cukup lama.
  3. Pisahkan repositori.
    • Pro: Memeriksa / mengkloning kode sumber secepat mungkin, dan gambar diarsipkan dengan benar dalam repositori mereka sendiri.
    • Contra: Menghapus kesederhanaan memiliki satu-satunya repositori Git pada proyek. Itu pasti memperkenalkan beberapa hal lain yang belum saya pikirkan.

Apa pengalaman / pemikiran Anda tentang ini?

Juga: Apakah ada yang punya pengalaman dengan beberapa repositori Git dan mengelolanya dalam satu proyek?

File adalah gambar untuk program yang menghasilkan PDF dengan file-file di dalamnya. File-file tidak akan sering berubah (seperti tahun-tahun sebelumnya), tetapi mereka sangat relevan dengan suatu program. Program tidak akan berfungsi tanpa file.

pi.
sumber
26
Bagaimana dengan ketika versi mengendalikan file biner diperlukan? Saya sedang berpikir untuk tim seniman yang mengerjakan aset.
Dan
3
Jika perlu maka Anda harus menyeimbangkan sumber daya yang tersedia (disk, bandwidth, waktu CPU) dengan manfaat yang Anda dapatkan.
pi.
4
Perhatikan bahwa tanpa penguncian file, git tidak bagus ketika banyak orang perlu bekerja pada file biner yang sama.
yoyo
1
Lihat juga bup file cadangan berbasis git .
VonC
1
Inilah mereka bestechvideos.com/tag/gitcasts
doughgle

Jawaban:

177

Jika program tidak akan berfungsi tanpa file, sepertinya membaginya menjadi repo terpisah adalah ide yang buruk. Kami memiliki suite pengujian besar yang kami pecah menjadi repo yang terpisah tetapi itu benar-benar file "tambahan".

Namun, Anda mungkin dapat mengelola file dalam repo yang terpisah dan kemudian menggunakannya git-submoduleuntuk menarik mereka ke dalam proyek Anda dengan cara yang waras. Jadi, Anda masih memiliki riwayat lengkap dari semua sumber Anda, tetapi, seperti yang saya mengerti, Anda hanya akan memiliki satu revisi yang relevan dari submodule gambar Anda. The git-submodulefasilitas akan membantu Anda menjaga versi yang benar dari kode sejalan dengan versi yang benar dari gambar.

Inilah pengantar yang bagus untuk submodul dari Git Book.

Pat Notz
sumber
11
"Seperti yang saya mengerti, Anda hanya akan memiliki satu revisi yang relevan dari submodule gambar Anda." Saya pikir ini tidak benar.
Robin Green
22
Memang. Sebuah submodule adalah repositori Git lengkap, yang kebetulan bersarang di dalam repositori induk. Ia tahu seluruh sejarahnya. Anda bisa melakukan lebih sedikit komit di dalamnya, tetapi jika Anda menyimpan hal yang sama di dalamnya Anda akan miliki di orangtua, itu akan memiliki masalah yang sama dengan yang dimiliki orangtua.
Cascabel
5
Ini adalah solusi yang sangat buruk jika Anda memiliki file biner besar yang berubah secara berkala. Kami memiliki repositori yang sangat membengkak karena file biner baru disimpan di dalamnya dengan setiap build. Jika Anda tidak menggunakan Windows, seperti yang disebutkan di bawah ini, Annex adalah solusi yang baik. Jika Anda menggunakan Windows ... Anda harus terus mencari.
AA Grapsas
4
Masalah lain dalam memiliki file biner besar dalam repo adalah kinerja. Git tidak dirancang untuk mengatasi file biner besar dan begitu ukuran repo naik ke 3G +, kinerja dengan cepat turun. Ini berarti memiliki binari besar dalam repo membatasi opsi hosting Anda.
zoul
Submodules dapat mengurangi persyaratan transfer data checkout jika Anda secara kreatif menyalahgunakan submodule: ketika Anda ingin memperbarui konten submodule, buat komit baru tanpa orangtua dan kemudian arahkan proyek super (repositori git utama) ke komit yang baru dibuat tanpa orangtua. Logikanya ini membuat riwayat terputus untuk submodule tetapi sebagai imbalannya, setiap versi submodule lebih mudah untuk ditransfer karena versi itu tidak memiliki riwayat.
Mikko Rantalainen
310

Saya menemukan git-lampiran baru - baru ini yang menurut saya luar biasa. Itu dirancang untuk mengelola file besar secara efisien. Saya menggunakannya untuk koleksi foto / musik saya (dll.). Pengembangan git-annex sangat aktif. Konten file dapat dihapus dari repositori Git, hanya hierarki pohon dilacak oleh Git (melalui symlinks). Namun, untuk mendapatkan konten file, langkah kedua diperlukan setelah menarik / mendorong, misalnya:

$ 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

Ada banyak perintah yang tersedia, dan ada dokumentasi yang bagus di situs web. Paket tersedia di Debian .

rafak
sumber
11
Wah! Suara positif untuk kedahsyatan! Ini mengimplementasikan ide yang saya miliki baru-baru ini, dan banyak lagi. Ada tertulis dalam Haskell. Ngomong-ngomong, git-media adalah alternatif yang bagus.
cdunn2001
33
Tapi, Annex tidak mendukung Windows. Yang bermasalah untuk pengembang game.
AA Grapsas
7
Saya mendengar Steam menjatuhkan dukungan untuk windows, dan menambahkan dukungan untuk Linux ...;) serius, betapa sulitnya untuk port ini? Saya kira pengembang rata-rata game Anda bisa melakukannya.
Sam Watkins
4
@EstebanBrenes Real deal-breaker adalah bahwa dalam konfigurasi normal, symlink Windows memerlukan hak istimewa yang tinggi untuk membuat.
Laurens Holst
4
Saya baru saja menemukan halaman ini . Bunyinya sekarang git annextersedia di Windows juga. Jika ada yang pernah mengujinya di Windows, saya ingin mendengar tentang pengalamannya!
Kouichi C. Nakamura
49

Solusi lain, sejak April 2015 adalah Git Large File Storage (LFS) (oleh GitHub).

Ia menggunakan git-lfs (lihat git-lfs.github.com ) dan diuji dengan server yang mendukungnya: lfs-test-server :
Anda dapat menyimpan metadata hanya di repo git, dan file besar di tempat lain.

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

VONC
sumber
3
lfs-test-serverdinyatakan tidak untuk penggunaan produksi. Sebenarnya, saya sedang mengerjakan server LFS produksi ( github.com/artemkin/git-lfs-server ). Ini sedang dalam proses, tetapi sudah bisa diperbaiki, dan kami sedang mengujinya sendiri.
Stas
Bisakah Anda checkout versi sebelumnya dari file biner menggunakan git lfs?
mucaho
1
@mucaho Anda harus: sintaks git checkout tidak berubah dan skrip lfs smudge masih harus dipanggil.
VonC
31

Lihat git bup yang merupakan ekstensi Git untuk secara cerdas menyimpan binari besar dalam repositori Git.

Anda ingin memilikinya sebagai submodule, tetapi Anda tidak perlu khawatir tentang repositori semakin sulit ditangani. Salah satu contoh kasus penggunaan mereka adalah menyimpan gambar VM di Git.

Saya belum benar-benar melihat tingkat kompresi yang lebih baik, tetapi repositori saya tidak memiliki binari yang sangat besar di dalamnya.

Jarak tempuh Anda mungkin beragam.

lihat
sumber
3
bup menyediakan penyimpanan (secara internal menggunakan arsip paritas untuk redundansi dan git untuk kompresi, dedup, dan riwayat), tetapi itu tidak memperpanjang git. git-annex adalah ekstensi git yang menyediakan backend penyimpanan bup .
Tobu
@Tobu ketika saya memposting ini, git lampiran belum ada (dalam rilis utama)
sehe
2
bup jelas menarik untuk mengelola file besar. Saya ingin menunjukkan perbedaan di UI: Anda menggunakan perintah bup di luar konteks repositori mana pun, dan git adalah detail implementasi.
Tobu
27

Anda juga bisa menggunakan git-fat . Saya suka itu hanya tergantung pada stok Python dan rsync. Ini juga mendukung alur kerja Git yang biasa, dengan perintah cukup jelas berikut ini:

git fat init
git fat push
git fat pull

Selain itu, Anda perlu memeriksa file .gitfat ke dalam repositori Anda dan memodifikasi .gitattributes Anda untuk menentukan ekstensi file yang ingin Anda git fatkelola.

Anda menambahkan biner menggunakan normal git add, yang pada gilirannya memanggil git fatberdasarkan aturan gitattributes Anda.

Akhirnya, ini memiliki keuntungan bahwa lokasi penyimpanan biner Anda sebenarnya dapat dibagikan di seluruh repositori dan pengguna dan mendukung apa pun yang rsyncdilakukan.

UPDATE: Jangan gunakan git-fat jika Anda menggunakan jembatan Git-SVN. Ini akhirnya akan menghapus file biner dari repositori Subversion Anda. Namun, jika Anda menggunakan repositori Git murni, ini berfungsi dengan baik.

Carl
sumber
26

Saya akan menggunakan submodules (sebagai Pat Notz) atau dua repositori yang berbeda. Jika Anda memodifikasi file biner Anda terlalu sering, maka saya akan mencoba untuk meminimalkan dampak dari repositori besar yang membersihkan riwayat:

Saya memiliki masalah yang sangat mirip beberapa bulan yang lalu: ~ 21 GB file MP3, tidak diklasifikasikan (nama buruk, id3 buruk, tidak tahu apakah saya suka file MP3 itu atau tidak ...), dan direplikasi pada tiga komputer.

Saya menggunakan hard disk drive eksternal dengan repositori Git utama, dan saya mengkloningnya ke setiap komputer. Kemudian, saya mulai mengklasifikasikan mereka dengan cara biasa (mendorong, menarik, menggabungkan ... menghapus dan mengganti nama berkali-kali).

Pada akhirnya, saya hanya punya ~ 6 GB file MP3 dan ~ 83 GB di direktori .git. Saya menggunakan git-write-treedan git-commit-treeuntuk membuat komit baru, tanpa komit leluhur, dan memulai cabang baru menunjuk komit itu. "Log git" untuk cabang itu hanya memperlihatkan satu komit.

Kemudian, saya menghapus cabang lama, hanya menyimpan cabang baru, menghapus ref-log, dan menjalankan "git prune": setelah itu, folder .git saya hanya berbobot ~ 6 GB ...

Anda dapat "membersihkan" repositori besar dari waktu ke waktu dengan cara yang sama: "git clone" Anda akan lebih cepat.

Daniel Fanjul
sumber
Saya melakukan sesuatu yang serupa sekali di mana saya harus membagi satu repositori yang saya gabungkan secara tidak sengaja menjadi dua yang berbeda. Namun, pola penggunaannya menarik. :)
pi.
1
Apakah ini sama dengan hanya: rm -f .git; git init; git add. ; git commit -m "Sampah sejarah."
Pat Notz
1
Ya, ini sama saja dalam case mp3 saya. Tetapi kadang-kadang Anda tidak ingin menyentuh cabang dan tag Anda (tidak ada pengurangan ruang dalam repositori publik) tetapi Anda ingin mempercepat "git clone / fetch / pull" hanya cabang (lebih sedikit ruang untuk didedikasikan-ke-itu- repositori cabang).
Daniel Fanjul
13

Solusi yang ingin saya ajukan didasarkan pada cabang-cabang yatim dan sedikit penyalahgunaan mekanisme tag, untuk selanjutnya disebut sebagai * Orphan Tags Binary Storage (OTABS)

TL; DR 12-01-2017 Jika Anda dapat menggunakan LFS github atau pihak ketiga lainnya, tentu saja Anda harus melakukannya. Jika Anda tidak bisa, maka baca terus. Berhati-hatilah, solusi ini adalah peretasan dan harus diperlakukan seperti itu.

Properti yang diinginkan OTABS

  • itu adalah git murni dan git hanya solusi - mendapat pekerjaan yang dilakukan tanpa perangkat lunak pihak ke-3 (seperti git-lampiran) atau infrastruktur pihak ke-3 (seperti github ini LFS).
  • ia menyimpan file biner secara efisien , artinya ia tidak mengasapi riwayat repositori Anda.
  • git pulldan git fetch, termasuk git fetch --allmasih bandwidth efisien , yaitu tidak semua binari besar ditarik dari jarak jauh secara default.
  • ini bekerja pada Windows .
  • ia menyimpan semuanya dalam satu repositori git .
  • memungkinkan penghapusan binari yang ketinggalan zaman (tidak seperti bup).

Properti OTABS yang tidak diinginkan

  • itu git cloneberpotensi tidak efisien (tetapi tidak harus, tergantung pada penggunaan Anda). Jika Anda menyebarkan solusi ini Anda mungkin harus nasihat rekan Anda untuk menggunakan git clone -b master --single-branch <url>bukan git clone. Ini karena git clone secara default benar-benar mengkloning seluruh repositori, termasuk hal-hal yang biasanya tidak ingin Anda buang bandwidthnya, seperti komitmen yang tidak direferensikan. Diambil dari SO 4811434 .
  • itu membuat git fetch <remote> --tagsbandwidth tidak efisien, tetapi tidak selalu penyimpanan tidak efisien. Anda selalu dapat menyarankan kolega Anda untuk tidak menggunakannya.
  • Anda harus secara berkala menggunakan git gctrik untuk membersihkan repositori Anda dari file yang tidak Anda inginkan lagi.
  • itu tidak seefisien bup atau git-bigfiles . Tetapi masing-masing lebih cocok untuk apa yang Anda coba lakukan dan lebih banyak lagi. Anda mungkin mengalami masalah dengan ratusan ribu file kecil atau dengan file dalam kisaran gigabyte, tetapi baca terus untuk mengetahui solusinya.

Menambahkan File Biner

Sebelum Anda mulai memastikan bahwa Anda telah melakukan semua perubahan, pohon kerja Anda mutakhir dan indeks Anda tidak mengandung perubahan yang tidak dikomit. Mungkin merupakan ide yang bagus untuk mendorong semua cabang lokal Anda ke remote Anda (github dll.) Seandainya terjadi bencana.

  1. Buat cabang yatim baru. git checkout --orphan binaryStuffakan melakukan trik. Ini menghasilkan cabang yang sepenuhnya terputus dari cabang lain, dan komit pertama yang Anda buat di cabang ini tidak memiliki induk, yang akan menjadikannya komit root.
  2. Bersihkan indeks Anda menggunakan git rm --cached * .gitignore.
  3. Ambil napas dalam-dalam dan hapus seluruh pohon yang bekerja menggunakan rm -fr * .gitignore. .gitDirektori internal akan tetap tidak tersentuh, karena *wildcard tidak cocok dengan itu.
  4. Salin di VeryBigBinary.exe Anda, atau VeryHeavyDirectory Anda /.
  5. Tambahkan && komit.
  6. Sekarang ini menjadi rumit - jika Anda mendorongnya ke remote sebagai cabang, semua pengembang Anda akan mengunduhnya saat berikutnya mereka meminta git fetchpenyumbatan koneksi mereka. Anda dapat menghindari ini dengan mendorong tag bukannya cabang. Ini masih dapat memengaruhi bandwidth dan penyimpanan sistem file rekan Anda jika mereka memiliki kebiasaan mengetik git fetch <remote> --tags, tetapi baca terus untuk mencari solusinya. Silakan dangit tag 1.0.0bin
  7. Dorong tag anak yatim Anda git push <remote> 1.0.0bin.
  8. Agar Anda tidak pernah mendorong cabang biner Anda secara tidak sengaja, Anda dapat menghapusnya git branch -D binaryStuff. Komit Anda tidak akan ditandai untuk pengumpulan sampah, karena tag anak yatim yang menunjuk padanya 1.0.0bincukup untuk membuatnya tetap hidup.

Memeriksa File Biner

  1. Bagaimana cara saya (atau kolega saya) memeriksakan VeryBigBinary.exe ke pohon kerja saat ini? Jika cabang kerja Anda saat ini adalah contohnya master, Anda cukup git checkout 1.0.0bin -- VeryBigBinary.exe.
  2. Ini akan gagal jika Anda tidak memiliki tag anak yatim yang 1.0.0bindiunduh, dalam hal ini Anda harus git fetch <remote> 1.0.0binterlebih dahulu.
  3. Anda dapat menambahkannya VeryBigBinary.exeke master Anda .gitignore, sehingga tidak ada seorang pun di tim Anda yang akan mencemari sejarah utama proyek dengan biner secara tidak sengaja.

Sepenuhnya Menghapus File Biner

Jika Anda memutuskan untuk sepenuhnya membersihkan VeryBigBinary.exe dari repositori lokal Anda, repositori jarak jauh dan repositori kolega Anda, Anda bisa:

  1. Hapus tag anak yatim di remote git push <remote> :refs/tags/1.0.0bin
  2. Hapus tag anak yatim secara lokal (hapus semua tag yang tidak direferensikan lainnya) git tag -l | xargs git tag -d && git fetch --tags. Diambil dari SO 1841341 dengan sedikit modifikasi.
  3. Gunakan trik git gc untuk menghapus komit Anda yang sekarang tidak direferensikan secara lokal. git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc "$@". Ini juga akan menghapus semua komitmen yang tidak direferensikan lainnya. Diambil dari SO 1904860
  4. Jika memungkinkan, ulangi trik git gc pada remote. Mungkin saja jika Anda meng-hosting repositori Anda sendiri dan mungkin tidak dapat dilakukan dengan beberapa penyedia git, seperti github atau di beberapa lingkungan perusahaan. Jika Anda hosting dengan penyedia yang tidak memberi Anda akses ssh ke kendali jarak jauh biarkan saja. Mungkin saja infrastruktur penyedia Anda akan membersihkan komit yang tidak direferensikan dalam waktu mereka sendiri yang manis. Jika Anda berada di lingkungan perusahaan, Anda dapat menyarankan TI Anda untuk menjalankan tugas cron mengumpulkan sampah Anda sekali seminggu atau lebih. Apakah mereka melakukannya atau tidak tidak akan berdampak pada tim Anda dalam hal bandwidth dan penyimpanan, selama Anda menyarankan kolega Anda untuk selalu git clone -b master --single-branch <url>melakukannya git clone.
  5. Semua kolega Anda yang ingin menyingkirkan tag anak yatim yang usang hanya perlu menerapkan langkah 2-3.
  6. Anda kemudian dapat mengulangi langkah 1-8 dari Menambahkan File Biner untuk membuat tag anak yatim 2.0.0bin. Jika Anda khawatir tentang mengetik rekan kerja, git fetch <remote> --tagsAnda sebenarnya dapat memberi nama lagi 1.0.0bin. Ini akan memastikan bahwa lain kali mereka mengambil semua tag yang lama 1.0.0binakan direferensikan dan ditandai untuk pengumpulan sampah berikutnya (menggunakan langkah 3). Ketika Anda mencoba untuk menimpa tag pada remote Anda harus menggunakan -fseperti ini:git push -f <remote> <tagname>

Kata penutup

  • OTABS tidak menyentuh master Anda atau cabang kode sumber / pengembangan lainnya. Hash komit, semua sejarah, dan ukuran kecil dari cabang-cabang ini tidak terpengaruh. Jika Anda sudah membengkak riwayat kode sumber Anda dengan file biner Anda harus membersihkannya sebagai bagian dari pekerjaan. Skrip ini mungkin berguna.

  • Dikonfirmasi untuk bekerja di Windows dengan git-bash.

  • Ini adalah ide yang baik untuk menerapkan satu set tric standar untuk membuat penyimpanan file biner lebih efisien. Menjalankan yang sering dari git gc(tanpa argumen tambahan) membuat git mengoptimalkan penyimpanan yang mendasari file Anda dengan menggunakan delta biner. Namun, jika file Anda tidak mungkin tetap sama dengan komit, Anda dapat menonaktifkan delta biner sama sekali. Selain itu, karena tidak masuk akal untuk mengompres file yang sudah dikompresi atau dienkripsi, seperti .zip, .jpg atau .crypt, git memungkinkan Anda untuk mematikan kompresi penyimpanan yang mendasarinya. Sayangnya ini adalah pengaturan semua atau tidak sama sekali yang mempengaruhi kode sumber Anda juga.

  • Anda mungkin ingin membuat skrip bagian-bagian dari OTABS untuk memungkinkan penggunaan yang lebih cepat. Secara khusus, langkah scripting 2-3 dari Completely Deleting Binary Files ke dalam updategit hook dapat memberikan semantik yang menarik tapi mungkin berbahaya untuk git fetch ("ambil dan hapus semua yang sudah ketinggalan zaman").

  • Anda mungkin ingin melewati langkah 4 dari File Biner yang Dihapus Sepenuhnya untuk menyimpan riwayat lengkap semua perubahan biner pada remote dengan biaya mengasapi repositori pusat. Repositori lokal akan tetap ramping dari waktu ke waktu.

  • Di dunia Java dimungkinkan untuk menggabungkan solusi ini dengan maven --offlinemembuat bangunan offline yang dapat direproduksi, yang disimpan sepenuhnya dalam kontrol versi Anda (lebih mudah dengan pakar daripada dengan gradle). Di dunia Golang, layak untuk membangun solusi ini untuk mengelola GOPATH Anda go get. Dalam dunia python adalah mungkin untuk menggabungkan ini dengan virtualenv untuk menghasilkan lingkungan pengembangan mandiri tanpa bergantung pada server Pypi untuk setiap build dari awal.

  • Jika file biner Anda terlalu sering berubah, seperti membangun artefak, mungkin ide yang baik untuk naskah solusi yang menyimpan 5 versi terbaru dari artefak di tag yatim monday_bin, tuesday_bin, ..., friday_bin, dan juga tag yatim piatu untuk setiap rilis 1.7.8bin 2.0.0bin, dll. Anda dapat memutar weekday_bindan menghapus binari lama setiap hari. Dengan cara ini Anda mendapatkan yang terbaik dari dua dunia: Anda menyimpan seluruh sejarah kode sumber Anda tetapi hanya riwayat yang relevan dari dependensi biner Anda. Juga sangat mudah untuk mendapatkan file biner untuk tag yang diberikan tanpa mendapatkan seluruh kode sumber dengan semua riwayatnya: git init && git remote add <name> <url> && git fetch <name> <tag>harus melakukannya untuk Anda.

Adam Kurkiewicz
sumber
"Anda harus menggunakan git gc" - berhenti membaca di sana secara berkala . Mengapa ada orang yang melepaskan sabuk pengaman terakhir mereka demi melakukan peretasan?
user1643723
@ user1643723 git gctidak aman untuk dijalankan. Semua komitmen Anda yang menggantung akan tetap tersimpan
Adam Kurkiewicz
Terima kasih untuk luncuran lengkap. Saya ingin mencoba ini sebagai cara untuk menyimpan beberapa dependensi biner di repo GitHub saya sedemikian rupa sehingga tidak diunduh secara default ketika seseorang mengkloning repo, tetapi dapat diunduh secara manual & memperbarui repo lokal. Namun, saya mendapat kesalahan pada langkah ini: git push <remote> 1.0.0bin- remote: error: GH001: Large files detected. You may want to try Git Large File Storage. Sepertinya mungkin GitHub tidak lagi mendukung ini? Biner yang dimaksud berukuran 100MB.
user5359531
1
Sejujurnya, jika Anda diizinkan menggunakan github untuk pekerjaan Anda, apa yang membuat Anda tidak menggunakan LFS? Orang-orang di github telah bekerja keras untuk membuat produk ini, dan mereka bahkan menyediakannya untuk Anda dan infrastruktur mereka dioptimalkan saat menggunakannya. Retasan ini dimaksudkan untuk situasi ketika Anda benar-benar tidak dapat menggunakan LFS atau pihak ketiga lainnya dan Anda mencari solusi murni-git.
Adam Kurkiewicz
Saya juga memperbarui jawabannya agar lebih jelas tentang seberapa sebenarnya solusi ini.
Adam Kurkiewicz
13

Menurut pendapat saya, jika Anda cenderung sering memodifikasi file-file besar itu, atau jika Anda berniat membuat banyak git cloneatau git checkout, maka Anda harus secara serius mempertimbangkan untuk menggunakan repositori Git lain (atau mungkin cara lain untuk mengakses file-file itu).

Tetapi jika Anda bekerja seperti kami, dan jika file biner Anda tidak sering dimodifikasi, maka klon / checkout pertama akan lama, tetapi setelah itu harus secepat yang Anda inginkan (mengingat pengguna Anda tetap menggunakan repositori hasil kloning pertama mereka punya).

claf
sumber
13
Dan, repo yang terpisah tidak akan membuat waktu checkout menjadi lebih singkat, karena Anda masih harus memeriksa kedua repo!
Emil Sit
@EmilSit repo terpisah dapat membuat checkout jauh lebih pendek jika Anda terus membersihkan sejarah "repo biner". Lagipula para dev tidak akan dipaksa untuk checkout kedua repo setiap kali .
FabienAndre
Mengapa tidak hanya membuat skrip build modul utama untuk mengambil file biner dari repo kedua, mengekstraknya satu per satu (seperti di sini: stackoverflow.com/questions/1125476/… ).
akauppi
1
Bahkan jika file biner Anda tidak sering diubah, file besar masih dapat mematikan alur kerja Anda jika Anda sering mendorong cabang ke repositori untuk tujuan kolaborasi.
Timo Reimann
9

SVN tampaknya menangani delta biner lebih efisien daripada Git.

Saya harus memutuskan sistem versi untuk dokumentasi (file JPEG, file PDF, dan file .odt). Saya baru saja menguji menambahkan file JPEG dan memutarnya 90 derajat empat kali (untuk memeriksa efektivitas delta biner). Repositori Git tumbuh 400%. Repositori SVN hanya tumbuh 11%.

Jadi sepertinya SVN jauh lebih efisien dengan file biner.

Jadi pilihan saya adalah Git untuk kode sumber dan SVN untuk file biner seperti dokumentasi.

Tony Diep
sumber
33
Anda hanya perlu menjalankan "git gc" (pengemasan ulang dan pengumpulan sampah) setelah menambahkan 4 file tersebut. Git tidak segera memampatkan semua konten yang ditambahkan, sehingga Anda akan memiliki kompresi kelompok file (yang lebih efisien dalam hal ukuran) dan tidak akan memiliki perlambatan mengompresi secara terpisah setiap objek yang ditambahkan di luar sana. Tetapi bahkan tanpa "git gc", git akhirnya akan melakukan kompresi untuk Anda (setelah diketahui, bahwa cukup banyak objek yang telah dibongkar terakumulasi).
nightingale
24
@jpierson Saya membuat repositori git kosong dan menambahkan (dan berkomitmen) gambar bmp yang sepenuhnya putih dengan ukuran 41MB, ini menghasilkan repositori git total dengan ukuran 328KB. Setelah ukuran git gctotal repositori git dikurangi menjadi 184KB. Kemudian saya mengubah satu pixel dari putih menjadi hitam dan melakukan perubahan ini, ukuran total repositori git meningkat menjadi 388KB, dan setelah git gcukuran total repositori git dikurangi menjadi 184KB. Ini menunjukkan bahwa git cukup baik dalam mengompresi dan menemukan delta file biner.
Tader
6
@ jpierson Catatan sidenote: Saya baru saja mengomentari delta biner. Git akan memakan semua memori Anda dan bertukar jika ia mengelola repositori dengan file besar (ukuran GB). Untuk ini, gunakan git-lampiran (sudah disebutkan dalam jawaban lain) ...
Tader
12
@JanDvorak - tidak ada yang menyebutkannya, karena itu sama sekali tidak benar. Salinan Subversion murah - svnbook.red-bean.com/en/1.7/svn.branchmerge.using.html - sekitar tengah halaman.
Joris Timmermans
12
@ Pemimpin: tes Anda buruk. Apa yang Anda sebut file biner sebenarnya (dari sudut pandang git) lebih seperti file teks - bitstreamnya adalah byte-aligned, dan ada beberapa perbedaan yang bermakna dan dilokalkan untuk dibuat; Lagi pula, mengubah satu piksel pada dasarnya sama dengan mengubah satu karakter dalam file teks (dan siapa yang menggunakan bitmap terkompresi saat ini?) Cobalah eksperimen yang sama dengan video kecil, gambar terkompresi, mesin virtual, zipfile atau apa pun - dan Anda akan menemukan git itu tidak berurusan secara efisien dengan delta; memang itu pada dasarnya tidak mungkin dengan data yang tidak bisa dimampatkan.
Eamon Nerbonne
4

git clone --filter dari Git 2.19 + klon dangkal

Opsi baru ini pada akhirnya mungkin menjadi solusi terakhir untuk masalah file biner, jika Git dan GitHub devs dan membuatnya cukup ramah pengguna (yang mereka mungkin masih belum mencapai untuk submodul misalnya).

Hal ini memungkinkan untuk hanya mengambil file dan direktori yang Anda inginkan untuk server, dan diperkenalkan bersama dengan ekstensi protokol jarak jauh.

Dengan ini, pertama-tama kita bisa melakukan klon dangkal, dan kemudian mengotomatiskan gumpalan mana yang akan diambil dengan sistem build untuk setiap jenis build.

Bahkan sudah ada --filter=blob:limit<size>yang memungkinkan membatasi ukuran gumpalan maksimum untuk mengambil.

Saya telah memberikan contoh detail minimal tentang bagaimana fitur di: Bagaimana cara mengkloning hanya subdirektori dari repositori Git?

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
sumber
2

Saya mencari pendapat tentang bagaimana menangani file biner besar yang menjadi sandaran kode sumber (aplikasi web) saya. Apa pengalaman / pemikiran Anda tentang ini?

Saya pribadi telah mengalami kegagalan sinkronisasi dengan Git dengan beberapa host cloud saya setelah data biner aplikasi web saya berlekuk di atas angka 3 GB . Saya menganggap BFT Repo Cleaner pada saat itu, tetapi rasanya seperti retasan. Sejak itu saya mulai menyimpan file di luar ruang lingkup Git, alih-alih memanfaatkan alat yang dibuat khusus seperti Amazon S3 untuk mengelola file, versi, dan cadangan.

Adakah yang punya pengalaman dengan beberapa repositori Git dan mengelolanya dalam satu proyek?

Iya. Tema Hugo terutama dikelola dengan cara ini. Agak kudgy, tapi itu menyelesaikan pekerjaan.


Saran saya adalah memilih alat yang tepat untuk pekerjaan itu . Jika itu untuk sebuah perusahaan dan Anda sedang mengelola codeline Anda di GitHub, bayar uangnya dan gunakan Git-LFS. Jika tidak, Anda dapat menjelajahi lebih banyak opsi kreatif seperti desentralisasi, penyimpanan file terenkripsi menggunakan blockchain .

Opsi tambahan untuk dipertimbangkan termasuk Minio dan s3cmd .

Josh Habdas
sumber
0

Lihat di camlistore . Ini sebenarnya bukan berbasis Git, tapi saya merasa lebih tepat untuk apa yang harus Anda lakukan.

Hernan
sumber