Apa yang harus dilakukan tentang sejarah svn besar saat pindah ke git?

23

Sunting: tidak seperti beberapa pertanyaan serupa seperti Memindahkan repo multi-GB SVN ke Git atau /programming/540535/managing-large-binary-files-with-git Skenario saya tidak melibatkan beberapa sub proyek yang dapat dengan mudah dikonversi menjadi git submoduels, atau beberapa file biner yang sangat besar yang cocok untuk git-annex. Ini adalah repositori tunggal di mana binari adalah suite uji yang digabungkan erat dengan kode sumber utama dari revisi yang sama, sangat mirip jika mereka mengkompilasi aset waktu seperti grafik.

Saya sedang menyelidiki mengganti repositori kode svn yang berukuran sedang / besar (50 pengguna, revisi 60k, riwayat 80Gb, copy pekerjaan 2Gb). Karena jumlah pengguna telah bertambah, ada banyak churn di dalam trunk, dan fitur-fitur sering tersebar pada banyak komit yang membuat peninjauan kode sulit dilakukan. Juga tanpa bercabang tidak ada cara untuk "gerbang" kode buruk keluar, ulasan hanya dapat dilakukan setelah berkomitmen untuk trunk. Saya sedang menyelidiki alternatif. Aku berharap kita bisa pindah ke git, tapi aku punya masalah.

Masalah dengan repo saat ini sejauh git pergi adalah ukuran. Ada banyak cruft tua di sana, dan membersihkannya dengan --filter-cabang saat mengkonversi ke git dapat memotongnya dalam ukuran dengan urutan besarnya, menjadi sekitar 5-10GB. Ini masih terlalu besar. Alasan terbesar untuk ukuran repositori yang besar adalah bahwa ada banyak dokumen biner yang menjadi input untuk pengujian. File-file ini bervariasi antara .5mb dan 30mb, dan ada ratusan. Mereka juga memiliki banyak perubahan. Saya telah melihat submodules, git-annex dll, tetapi memiliki tes dalam submodule terasa salah, seperti halnya memiliki lampiran untuk banyak file yang Anda inginkan riwayat lengkap.

Jadi sifat git yang terdistribusi adalah yang menghalangi saya untuk mengadopsinya. Saya tidak begitu peduli tentang didistribusikan, saya hanya ingin fitur percabangan yang murah dan kuat. Seperti yang saya asumsikan 99,9% dari pengguna git lakukan, kita akan menggunakan repositori sentral yang diberkati dan telanjang.

Saya tidak yakin saya mengerti mengapa setiap pengguna harus memiliki riwayat lokal lengkap saat menggunakan git? Jika alur kerja tidak terdesentralisasi, apa yang dilakukan data pada disk pengguna? Saya tahu bahwa di git versi terbaru Anda dapat menggunakan klon dangkal dengan hanya riwayat terbaru. Pertanyaan saya adalah: apakah layak untuk melakukan ini sebagai mode operasi standar untuk seluruh tim? Bisakah git dikonfigurasi agar selalu dangkal sehingga Anda dapat memiliki riwayat lengkap hanya secara terpusat, tetapi pengguna secara default hanya memiliki 1000 putaran sejarah? Pilihan untuk itu tentu saja untuk hanya mengkonversi 1000 revs ke git, dan menyimpan repo svn untuk arkeologi. Namun dalam skenario itu, kami akan menghadapi masalah yang sama lagi setelah beberapa ribu revisi berikutnya ke dokumen uji.

  • Apa yang baik praktek terbaik untuk menggunakan git dengan repo besar berisi banyak file biner yang Anda lakukan ingin sejarah untuk? Kebanyakan praktik terbaik dan tutorial tampaknya menghindari kasus ini. Mereka memecahkan masalah beberapa binari besar, atau mengusulkan menjatuhkan binari sepenuhnya.
  • Apakah kloning yang dangkal dapat digunakan sebagai mode operasi normal atau itu "hack"?
  • Bisakah submodula digunakan untuk kode di mana Anda memiliki ketergantungan yang ketat antara revisi sumber utama dan revisi submodule (seperti dalam kompilasi dependensi biner waktu, atau unit test unit)?
  • Seberapa besar "terlalu besar" untuk repositori git (di tempat)? Haruskah kita menghindari beralih jika kita bisa turun ke 4GB? 2GB?
Anders Forsgren
sumber
kemungkinan duplikat Memindahkan repo multi-GB SVN ke Git
gnat
Saya mencari banyak info tentang ini, dan tidak menemukan apa pun yang menjawab pertanyaan saya. Dalam pertanyaan terkait, workaounrds (submodules, annex, dll.) Akan bekerja jauh lebih baik daripada dalam skenario saya.
Anders Forsgren
1
Git LFS
CodesInChaos
Perforce mungkin merupakan opsi yang lebih baik daripada git, karena ia dirancang untuk mengatasi banyak file biner besar, karenanya digunakan oleh banyak pengembang game. Plasticscm juga layak dilihat.
Ian
Di samping itu: hindari submitules git jika Anda bisa, karena terlalu memperumit sistem build (yang sudah rumit dalam kasus Anda).
IgorGanapolsky

Jawaban:

10

Wow, itu pertanyaan panjang (dan masalah yang rumit). Saya akan mencoba melakukannya.

Saya tidak yakin saya mengerti mengapa setiap pengguna harus memiliki riwayat lokal lengkap saat menggunakan git?

Ini adalah keputusan desain utama dengan git. Untuk alasan yang tepat Anda harus bertanya kepada penulis (Linus Torvalds), tetapi sejauh yang saya tahu, alasan utamanya adalah kecepatan: Memiliki segala sesuatu yang lokal (pada disk cepat atau bahkan di-cache dalam RAM) membuat operasi pada sejarah lebih cepat dengan menghindari akses jaringan.

Alasan terbesar untuk ukuran repositori yang besar adalah bahwa ada banyak dokumen biner yang menjadi input untuk pengujian. File-file ini bervariasi antara 0,5mb dan 30mb, dan ada ratusan. Mereka juga memiliki banyak perubahan.

Itulah poin yang akan saya pikirkan pertama kali. Memiliki begitu banyak file biner yang terus berubah dalam kontrol sumber tampaknya bermasalah bagi saya (bahkan dengan SVN). Tidak bisakah Anda menggunakan pendekatan yang berbeda? Ide ide:

  • Tidak seperti kode sumber, file biner 3 MB mungkin tidak ditulis dengan tangan. Jika beberapa alat / proses menghasilkannya, pertimbangkan untuk mengintegrasikannya ke dalam build Anda, alih-alih menyimpan data.

  • Jika itu tidak praktis, file biner biasanya lebih baik dalam repositori artefak (seperti Artifactory for Maven & co.). Mungkin itu pilihan bagi Anda.

Saya telah melihat submodules, git-annex dll, tetapi memiliki tes dalam submodule terasa salah, seperti halnya memiliki lampiran untuk banyak file yang Anda inginkan riwayat lengkap.

Sebenarnya, ini terlihat seperti git-lampiran akan sangat cocok. git-annex pada dasarnya memungkinkan Anda untuk menyimpan konten file di luar repositori git (repositori malah berisi placeholder). Anda dapat menyimpan konten file dalam berbagai cara (central git repo, drive bersama, penyimpanan cloud ...), dan Anda dapat mengontrol konten mana yang ingin Anda miliki secara lokal.

Apakah Anda mungkin salah paham bagaimana git-lampiran bekerja? git-annex menyimpan histori penuh untuk semua file yang dikelolanya - itu hanya memungkinkan Anda memilih konten file mana yang ingin Anda miliki secara lokal.

Akhirnya, tentang pertanyaan Anda:

Apa praktik terbaik yang baik untuk menggunakan git dengan repo besar yang berisi banyak file biner yang ingin Anda riwayatkan?

Dalam pengalaman saya, opsi biasanya adalah:

  • hindari kebutuhan akan binari dalam repo (hasilkan sesuai permintaan, simpan di tempat lain)
  • gunakan git-annex (atau solusi serupa, seperti Git LFS)
  • hidup dengan repo besar (tidak semua operasi git dipengaruhi oleh file besar, dan jika Anda memiliki komputer dan drive yang cepat, itu bisa sangat bisa diterapkan)

Apakah kloning yang dangkal dapat digunakan sebagai mode operasi normal atau itu "hack"?

Itu mungkin bisa dilakukan; Namun, saya tidak berpikir ini akan menyelesaikan masalah Anda:

  • Anda akan kehilangan manfaat git yang berasal dari memiliki riwayat lengkap, seperti pencarian cepat dari riwayat tersebut
  • penggabungan dapat menjadi rumit, karena AKAIK Anda harus memiliki setidaknya sejarah kembali ke titik cabang untuk bergabung
  • pengguna perlu mengkloning ulang secara berkala untuk menjaga ukuran klon mereka kecil
  • itu hanya cara yang tidak biasa menggunakan git, jadi Anda mungkin akan mengalami masalah dengan banyak alat

Seberapa besar "terlalu besar" untuk repositori git (di tempat)? Haruskah kita menghindari beralih jika kita bisa turun ke 4GB? 2GB?

Itu tergantung pada struktur repo (beberapa / banyak file dll), pada apa yang ingin Anda lakukan, pada seberapa gemuk komputer Anda, dan pada kesabaran Anda :-).

Untuk memberi Anda ide cepat: Pada laptop saya (agak baru, tapi rendah spesifikasi), melakukan file 500 MB membutuhkan waktu 30-60 detik. Hanya daftar riwayat (git log dll.) Tidak terpengaruh oleh file besar; hal-hal seperti "git log -S" yang harus memindai konten file sangat lambat - namun, kecepatannya didominasi oleh I / O, jadi itu bukan kesalahan git.

Pada repo 3 GB dengan sedikit revisi, "git log -S" membutuhkan waktu sekitar satu menit.

Jadi saya akan mengatakan beberapa GB baik-baik saja, meskipun tidak ideal. Lebih dari 10-20 GB mungkin mendorongnya, tetapi mungkin bisa dilakukan - Anda harus mencobanya.

sleske
sumber
Terima kasih atas balasan terperinci Anda. Saya pasti akan melihat ke dalam menggunakan lampiran untuk dokumen uji. Bilah untuk "kinerja wajar" mungkin "dekat dengan svn", yaitu jika secara signifikan lebih lambat untuk operasi apa pun maka akan ada terlalu banyak gesekan untuk beralih.
Anders Forsgren
Saya pikir Git LFS juga dapat digunakan untuk penyimpanan file biner yang besar.
IgorGanapolsky
@ IGG .: Ya, Git LFS adalah alternatif, ada yang lain. Terima kasih telah menunjukkannya, saya mengedit posting saya.
sleske
4

Karena jumlah pengguna telah bertambah, ada banyak churn di trunk, dan fitur-fitur sering tersebar di beberapa komit yang membuat peninjauan kode sulit dilakukan. Juga tanpa bercabang tidak ada cara untuk "gerbang" kode buruk, ulasan hanya dapat dilakukan setelah berkomitmen untuk trunk

Pindah ke git tidak akan menyelesaikan masalah ini, itu adalah masalah dalam cara Anda menggunakan alat dan jika Anda menggunakan git dengan cara yang sama, masalah akan tetap ada.

Anda dapat bercabang di svn dengan mudah di git, dan penggabungan pada umumnya sama mudahnya dan memiliki perangkap yang sama. Git dirancang untuk bekerja dengan kode sumber kernel, sehingga ia membuat beberapa asumsi yang mungkin tidak berlaku dalam semua kasus, seperti milik Anda dengan binari besar dan sejarah besar. Maksud di balik DVCS adalah bahwa setiap pengguna secara efektif bekerja sendiri dan hanya berkolaborasi setelah itu - yaitu mereka memiliki repo sendiri (salinan), bekerja sesuka mereka dan kemudian mendorong perubahan kepada siapa pun yang menginginkannya. Sebuah sistem gabungan yang digunakan dalam pengembangan kernel linux sangat cocok untuk ini - Anda mendorong perubahan Anda ke orang berikutnya di rantai yang menggabungkannya dengan basis kode-nya dan kemudian mendorongnya ke orang berikutnya hingga sampai ke Linus yang memasukkannya ke dalam rilis. Sebagian besar tim menggunakan git dengan cara yang sama, tetapi dengan hanya 1 orang upstream yang sering menjadi repo 'server' sisi server,

Jadi saya akan melihat mengubah alur kerja Anda terlebih dahulu, hanya bermigrasi ke git setelah Anda memiliki cara kerja yang lebih baik. Menerapkan percabangan dan penggabungan dalam SVN, jika Anda tidak mengganti nama file atau penggabungan direktori berjalan dengan baik.

gbjbaanb
sumber
4
"Anda dapat bercabang di svn dengan mudah di git, dan penggabungan pada umumnya sama mudahnya dan memiliki perangkap yang sama", wow itu klaim yang sangat kontroversial. Menggabung dalam git menurut saya biasanya mudah dan dalam svn biasanya mimpi buruk, bahkan dalam versi setelah upaya setengah-terpotong pada pelacakan gabungan diperkenalkan (ya, saya bekerja dengan git, tidak hanya pada repo ini). Alur kerja yang ingin kita miliki adalah di mana Anda membuat cabang fitur, review kode / CI membangun di cabang itu. Tidak ada cara untuk melakukan itu di SVN tanpa frustrasi besar.
Anders Forsgren
2
tidak, kami melakukannya sepanjang waktu di sini. Saya hanya akan melalui 157 cabang di repo SVN saya untuk melihat mana yang bisa dihapus. Kami bercabang, dev, meninjau dan kemudian bergabung hampir setiap hari di sini, kadang-kadang mendapat masalah tetapi itu selalu diperbaiki dengan mengambil cabang baru dari bagasi dan menggabungkan perubahan itu (sehingga dapat dengan mudah digabungkan kembali ke bagasi nanti) . Itu hanya benar-benar berlaku untuk cabang kuno sekalipun. Jika Anda sangat frustrasi, Anda tidak cukup memahaminya. Git juga akan memberi Anda frustrasi besar.
gbjbaanb
2
Aku hanya tidak mengalaminya. Ketika bekerja dengan git (seperti yang saya katakan saya lakukan, tetapi dalam repo yang lebih kecil) saya merasa cukup mudah dan alami untuk melakukan fitur percabangan, rebasing, squashing, dan penggabungan. "Pohon konflik setelah penggantian nama" dll. Terasa jauh lebih jarang, dan fakta bahwa Anda dapat meniru sejarah linier dan sederhana (via rebase + squash dll) sangat penting. Jadi: demi menjaga pertanyaan pada topik (git dengan repo besar): Mari kita asumsikan bahwa svn tidak mendukung alur kerja yang saya butuhkan, dan git melakukannya.
Anders Forsgren
1
Di perusahaan sebelumnya kami menggunakan git, dan saya kenal seseorang di sana yang biasanya kehilangan pekerjaannya secara rutin, jadi itu bukan sistem yang sempurna! Juga bukan SVN, tetapi SVN jauh lebih cocok untuk keadaan Anda daripada git IMHO, dan itu berhasil. Pada topik, bagaimana membuat git bekerja seperti yang Anda inginkan ... Saya benar-benar tidak yakin itu akan, maaf.
gbjbaanb
7
@ gbjbaanb jika seseorang kehilangan pekerjaan mereka dengan Git, mereka melakukan sesuatu yang sangat salah.
RubberDuck
2

Lihatlah milis GCC. Migrasi pohon sumber penyusun GCC dari SVN ke GIT sedang dibahas saat ini (Agustus & September 2015), sambil tetap menyimpan riwayat GCC. Lihat misalnya repositori untuk mesin konversi & Kriteria penerimaan untuk utas git konversi mail; Anda akan menemukan referensi ke alat dan prosedur yang berkaitan dengan konversi (yang tidak semudah kelihatannya; konversi sejarah basis kode yang begitu besar membutuhkan 36 jam dan sekitar 64Gbytes RAM, IIRC)

Basile Starynkevitch
sumber
Apakah maksud Anda bermigrasi dari SVN ke Git? Bermigrasi dari sistem kontrol versi ke suite kompiler tampaknya agak ... aneh. Juga, ini sedikit lebih mirip komentar daripada jawaban.
8bittree
Iya nih. Maaf atas kesalahan ketiknya.
Basile Starynkevitch
Terima kasih. 36 jam terdengar seperti angin, milik kami dapat dikonversi dalam beberapa minggu ...
Anders Forsgren
2

Jika mengubah seluruh repositori SVN menjadi Git menghasilkan repositori besar yang tidak layak untuk dikloning , Anda dapat mencoba menggunakan SubGit untuk membuat cermin Git yang lebih kecil untuk bagian-bagian tertentu dari repositori Subversion Anda.

Misalnya, Anda dapat mengimpor dan menyinkronkan beberapa subdirektori dari repositori SVN Anda http://domain/repos/trunk/project/src:

subgit configure --layout auto --trunk trunk/project/src http://domain/repos project.git
edit project.git/subgit/config
edit project.git/subgit/authors.txt
subgit install project.git

Untuk detail lebih lanjut tentang penggunaan SubGit, rujuk ke dokumentasinya .

Segera setelah Anda memiliki Git mirror dari direktori itu, Anda dapat menggunakan repositori Git untuk mengirimkan perubahan baru yang langsung tercermin dalam repositori SVN. Karena Anda hanya menyinkronkan bagian tertentu dari repositori SVN yang menyusutkan ukuran repositori Git yang dikonversi secara signifikan dan Anda masih dapat membuat cabang, menggabungkannya, menggunakan alur kerja apa pun dari sisi Git.

Atau, Anda dapat mengimpor seluruh gudang SVN tetapi mengecualikan file besar dari sinkronisasi:

subgit configure --layout auto --trunk trunk http://domain/repos project.git
edit project.git/subgit/config
...
[svn]
    excludePath = *.bin
    excludePath = *.iso
...
edit project.git/subgit/authors.txt
subgit install project.git

Repositori Git yang dihasilkan harus memiliki ukuran yang wajar dan pengembang masih dapat menggunakan Git untuk mengirimkan perubahan mereka ke repositori Subversion.

Perhatikan bahwa solusi ini akan bekerja dengan baik untuk Anda jika Anda siap untuk menjaga server Subversion berjalan dan menggunakan Git di samping repositori SVN Anda.

Penafian: Saya salah satu pengembang SubGit; SubGit adalah perangkat lunak komersial dengan sejumlah opsi gratis yang tersedia.

vadishev
sumber
1

Saya akan mendekati situasi Anda dengan cara berikut:

1) Inisialisasi repositori git di direktori yang sama dengan repo SVN Anda. Lakukan git initdan git remote add originmulai repo git itu. Dengan begitu Anda dapat terus berkomitmen pada SVN dan git secara terpisah tanpa berurusan dengan konversi penuh dari satu ke yang lain sampai Anda siap.

2) Secara aktif menggunakan alat bfg dan filter-cabang untuk mencoba dan mengecilkan git repo Anda, seperti yang dibahas di sini: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html

3) Gunakan git-annex, atau Git LFS, atau hanya server penyimpanan eksternal untuk binari besar Anda (mengangkut file menggunakan skrip shell saat membangun).

4) Setelah Anda merasa nyaman dengan strategi penggabungan / percabangan di git repo Anda, dan merasa nyaman dengan ukuran repo git Anda, Anda kemudian dapat melakukan migrasi penuh dari svn ke git.

Semoga ini membantu.

IgorGanapolsky
sumber