
... Kami mengembangkan Gardenscapes. Itu masih memiliki jejak Gardenscapes tua di bawah Windows. Itu bahkan bukan Match-3, tapi Hidden Object. Dan tidak ada yang bisa membayangkan ketinggian yang akan dicapai game itu.
Dan kemudian suatu hari ...
Bagaimana semua ini dimulai
Saat mengakses repositori, kami melihat pesan berikut:
βRepositori ini telah dinonaktifkan. Akses ke repositori ini telah dinonaktifkan oleh staf GitHub karena penggunaan sumber daya yang berlebihan, yang melanggar Persyaratan Layanan kami. Harap hubungi dukungan untuk memulihkan akses ke repositori ini. Baca di sini untuk mempelajari lebih lanjut tentang mengurangi ukuran repositori Anda. "
Seperti yang mungkin sudah Anda duga, kami menggunakan github untuk menghosting repositori git. Jadi, tiba-tiba dan tanpa menyatakan perang, github memblokir repositori kami karena melebihi ukuran maksimum yang diizinkan. Angka pastinya tidak diberikan di situs web mereka. Pada saat penguncian, folder .git berukuran sekitar 25 GB. (Catatan 2020: batasnya sekarang lebih tinggi, dan situs github secara eksplisit menyatakan bahwa ukuran repositori tidak boleh melebihi 100 GB).
Bagaimana kami berhasil membuat repositori sebesar itu? Alasannya jelas: kami menyimpan file biner di dalamnya. Ada tertulis di mana-mana sehingga tidak disarankan untuk melakukan ini, tetapi jauh lebih mudah bagi kita. Kami ingin game segera diluncurkan dari repositori, tanpa upaya tambahan. Oleh karena itu, kami memasukkan grafik dan sumber daya game lainnya ke repositori.
Tapi ini tidak terlalu buruk. Pelajaran penting yang kami pelajari dari keseluruhan cerita ini: jangan pernah
Berjuang untuk sejarah
Jadi, tidak ada yang berhasil untuk siapa pun. Kami memberi tahu tim bahwa mereka harus bekerja secara lokal selama sehari, tetapi tidak berusaha terlalu keras, jika tidak mereka akan menyelesaikan konflik nanti (semua orang sangat kesal dan segera pergi untuk minum teh). Dan mereka mulai berpikir apa yang harus dilakukan. Jelas bahwa repositori baru diperlukan, tetapi apa yang harus dilakukan di sana? Cara yang mudah adalah status semua cabang saat ini. Tapi kami tidak terlalu menyukainya, karena riwayat perubahan akan hilang, perintah git menyalahkan favorit semua orang akan rusak, dan semuanya akan jungkir balik. Oleh karena itu, kami memutuskan untuk melakukan ini: hapus riwayat file biner, dan simpan riwayat file teks.

Langkah 1. Hapus riwayat biner
Kami memiliki salinan lokal lengkap dari repositori. Hal pertama yang kami temukan adalah utilitas BFG Repo-Cleaner yang sangat baik . Ini sangat sederhana dan sangat cepat pada saat bersamaan, dan namanya bagus.
Contoh skenario eksekusi:
java -jar bfg.jar bfg --delete-files *.{pvrtc,webp,png,jpeg,fla,swl,swf,pbi,bin,mask,ods,ogv,ogg,ttf,mp4} path_to_repository
Parameter berisi semua ekstensi dari file biner yang bisa kita buat. Dari semua komit di dunia, informasi tentang file dengan ekstensi ini akan dihapus. Utilitasnya cerdas dan saat menghapus riwayat file, ia meninggalkan versi terbarunya. Selain itu, versi terbaru ini akan disertakan dalam komit terbaru di cabang. Kami juga ingin menghapus riwayat file exe dan dll, tetapi utilitas memberikan kesalahan. Rupanya, karena alasan tertentu, pemrosesan dalam bentuk * .exe dilarang. Selain itu, jika Anda secara eksplisit menentukan file, misalnya, gardenscapes.exe, maka semuanya berfungsi. (Catatan 2020: bug mungkin sudah diperbaiki).
Langkah 2. Kompres repositori
Setelah langkah pertama, ukuran repositori masih besar. Alasannya adalah cara kerja git. Kami hanya menghapus tautan ke file, tetapi file itu sendiri tetap ada.
Untuk menghapus file secara fisik, Anda perlu menjalankan perintah git gc, yaitu:
git reflog expire --expire=now --all
dan dari:
git gc --prune=now --aggressive
Ini adalah urutan perintah yang direkomendasikan oleh pembuat utilitas. Disini gc butuh waktu lama banget. Selain itu, dengan pengaturan repositori default, klien git tidak memiliki cukup memori untuk menyelesaikan operasi dan perlu menari dengan rebana. (Catatan 2020: saat itu kami memiliki git versi 32-bit. Kemungkinan besar, masalah ini tidak lagi ada di versi 64-bit).
Langkah 3. Menulis komit ke repositori baru
Ini ternyata menjadi bagian paling menarik dari pencarian.
Untuk memahami yang berikut ini, Anda perlu memahami cara kerja git. Anda dapat membaca lebih lanjut tentang git di banyak tempat, termasuk di blog kami:
- Git: Tips untuk Pemula - Bagian 1
- Git: Tips untuk Pemula - Bagian 2
- Git: Tips untuk Pemula - Bagian 3
Jadi, kami memiliki sangat, sangat banyak komit secara lokal, komit ini benar, tanpa histori binari. Tampaknya cukup mengeksekusi git push dan semuanya akan bekerja dengan sendirinya. Tapi tidak!
Jika Anda baru saja menjalankan perintah git push -u master, lalu git dengan riang memulai proses mengunggah data ke server, tetapi macet dengan kesalahan sekitar 2 GB. Artinya, Anda tidak akan dapat mengupload begitu banyak komitmen sekaligus. Kami akan memakan gajah di beberapa bagian. Kami memperkirakan bahwa 2.000 komitmen mungkin muat dalam 2 GB. Volume total repositori kami saat itu sekitar 20.000 komit, didistribusikan di antara 4 cabang: master-v101-v102-v103. (Catatan 2020: eh, anak muda! Sejak itu semuanya menjadi jauh lebih serius. Sudah ada lebih dari 100.000 komit di repositori ini, dan ada beberapa lusin cabang rilis. Pada saat yang sama, kami masih masuk ke dalam batasan Github)
Pertama-tama, kami mempertimbangkan jumlah komit di cabang saat perintah bantuan:
git rev-list --count <branch-name>
Misalnya, ada sekitar 10.000 komit di cabang master. Sekarang kita dapat menggunakan sintaks yang diperluas untuk perintah git push, yaitu:
git push -u origin HEAD~8000:refs/origin/master
HEAD ~ 8000: refs / origin / master disebut refspec. Sisi kiri mengatakan bahwa Anda perlu mengambil komit hingga komit yang berjarak 8.000 dari HEAD, yaitu, sekitar 2.000 komitmen. Dan sisi kanan adalah Anda perlu mendorongnya ke cabang master jarak jauh. Path lengkap ke cabang refs / origin / master diperlukan di sini.
Setelah itu, masih belum ada cabang master, dan, misalnya, git fetch tidak akan dapat mengunduhnya. Ini tidak mengherankan - lagipula, commit yang mengarah ke HEAD-nya belum ada. Namun demikian, dengan mengulangi perintah git push HEAD ~ 8000: refs / origin / master , kami melihat jawaban bahwa komit ini sudah ada di server, dan, oleh karena itu, pekerjaan sudah selesai.
Selanjutnya, kami berpikir bahwa prosesnya sudah jelas dan pekerjaan lainnya dapat ditetapkan ke skrip. Komitmen terakhir akan menjadi sangat besar, karena akan berisi semua binari. Oleh karena itu, untuk berjaga-jaga, 10 komit terakhir diisi secara terpisah. Skripnya ternyata seperti ini:
git push origin HEAD~6000:refs/origin/master
git push origin HEAD~5000:refs/origin/master
git push origin HEAD~4000:refs/origin/master
git push origin HEAD~3000:refs/origin/master
git push origin HEAD~2000:refs/origin/master
git push origin HEAD~1000:refs/origin/master
git push origin HEAD~10:refs/origin/master
git push origin master
git checkout v101
git push -u origin HEAD~1000:refs/origin/v101
git push origin HEAD~10:refs/origin/v101
git push origin v101
git checkout v102
β¦ ..
Artinya, kami secara konsisten menulis semua cabang kami ke server, 2.000 komit per push, dan 10 komit terakhir secara terpisah.
Seluruh cerita ini memakan banyak waktu, dan jam ditunjukkan mendekati pukul 12 malam. Jadi kami meninggalkan naskah untuk bekerja semalaman, mengucapkan doa yang benar kepada Cthulhu (Catatan 2020: saat itu masih relatif populer) dan pulang.
Akhir. Akhir yang bahagia
Di pagi hari, setelah membuka repositori di situs github, kami memastikan bahwa skrip bekerja dengan sukses dan semua komit dan cabang ada di tempatnya.
Hasilnya: ukuran repositori (folder .git) telah dikurangi dari 25 GB menjadi 7,5 GB. Pada saat yang sama, semua riwayat komit yang penting - semuanya kecuali binari - dipertahankan. Para desainer game meminum lebih banyak teh dari biasanya. Programer mendapat pengalaman yang tak terlupakan. Dan mereka segera mulai memikirkan tentang bagaimana melakukannya sehingga tidak perlu memasukkan file yang dapat dieksekusi ke repositori, tetapi akan lebih mudah untuk bekerja dengannya.