Seringkali Anda menulis sebuah proyek, dan setelah beberapa saat menjadi jelas bahwa beberapa komponen proyek sebenarnya berguna sebagai komponen yang berdiri sendiri (perpustakaan, mungkin). Jika Anda sudah memiliki ide itu sejak awal, maka ada kemungkinan besar sebagian besar kode itu ada di foldernya sendiri.
Apakah ada cara untuk mengubah salah satu sub direktori dalam proyek Git menjadi submodul?
Idealnya ini akan terjadi sedemikian rupa sehingga semua kode dalam direktori itu dihapus dari proyek induk, dan proyek submodule ditambahkan di tempatnya, dengan semua sejarah yang sesuai, dan sedemikian rupa sehingga semua proyek induk menunjuk ke submodul yang benar melakukan .
git
git-submodules
n nothing101
sumber
sumber
Jawaban:
Untuk mengisolasi subdirektori ke dalam repositori sendiri, gunakan
filter-branch
klon dari repositori asli:Maka tidak lebih dari menghapus direktori asli Anda dan menambahkan submodule ke proyek induk Anda.
sumber
git remote rm <name>
setelah cabang filter, dan kemudian mungkin menambahkan remote baru. Juga, jika ada file yang diabaikan, agit clean -xd -f
mungkin berguna-- --all
dapat diganti dengan nama cabang jika submodul hanya diekstrak dari cabang ini.git clone <your_project> <your_submodule>
hanya mengunduh file untuk modul_Anda?git clone source destination
cukup memberi tahu Git lokasi penyimpanan file kloning Anda. Keajaiban sebenarnya untuk memfilter file submodule Anda kemudian terjadi padafilter-branch
langkah tersebut.filter-branch
sudah usang saat ini. Anda dapat menggunakangit clone --filter
, tetapi server Git Anda harus dikonfigurasi untuk memungkinkan pemfilteran, jika tidak Anda akan mendapatkannyawarning: filtering not recognized by server, ignoring
.Pertama ubah dir ke folder yang akan menjadi submodule. Kemudian:
sumber
Saya tahu ini adalah utas lama, tetapi jawaban di sini menghentikan semua komitmen terkait di cabang lain.
Cara sederhana untuk mengkloning dan menyimpan semua cabang dan komitmen ekstra itu:
1 - Pastikan Anda memiliki alias git ini
2 - Kloning remote, tarik semua cabang, ubah remote, filter direktori Anda, dorong
sumber
Itu bisa dilakukan, tapi tidak sederhana. Jika Anda mencari
git filter-branch
,subdirectory
dansubmodule
, ada beberapa artikel yang layak dalam prosesnya. Ini pada dasarnya memerlukan pembuatan dua klon proyek Anda, menggunakangit filter-branch
untuk menghapus semuanya kecuali satu subdirektori di satu, dan menghapus hanya subdirektori di yang lain. Kemudian Anda dapat membuat repositori kedua sebagai submodul dari yang pertama.sumber
Status quo
Anggaplah kita memiliki repositori bernama
repo-old
yang berisi sub direktorisub
yang ingin kita ubah menjadi sub modul dengan reponya sendirirepo-sub
.Lebih lanjut dimaksudkan bahwa repo asli
repo-old
harus diubah menjadi repo yang dimodifikasi direpo-new
mana semua komit yang menyentuh subdirektori yang ada sebelumnyasub
sekarang akan mengarah ke komit yang sesuai dari repo submodul yang kami ekstrakrepo-sub
.Ayo ganti
Hal ini dimungkinkan untuk mencapai ini dengan bantuan
git filter-branch
dalam proses dua langkah:repo-old
kerepo-sub
(sudah disebutkan dalam jawaban yang diterima )repo-old
kerepo-new
(dengan pemetaan komit yang tepat)Catatan : Saya tahu bahwa pertanyaan ini sudah lama dan sudah disebutkan, itu
git filter-branch
agak usang dan mungkin berbahaya. Tetapi di sisi lain, ini mungkin membantu orang lain dengan repositori pribadi yang mudah divalidasi setelah konversi. Jadi berhati - hatilah ! Dan beri tahu saya jika ada alat lain yang melakukan hal yang sama namun tetap aman digunakan!Saya akan menjelaskan bagaimana saya menyadari kedua langkah di linux dengan git versi 2.26.2 di bawah. Versi yang lebih lama mungkin berfungsi sampai batas tertentu tetapi itu perlu diuji.
Demi kesederhanaan, saya akan membatasi diri pada kasus di mana hanya ada
master
cabang danorigin
remote di repo aslirepo-old
. Juga diperingatkan bahwa saya mengandalkan tag git sementara dengan awalantemp_
yang akan dihapus dalam prosesnya. Jadi jika sudah ada tag dengan nama yang mirip, Anda mungkin ingin menyesuaikan awalan di bawah ini. Dan akhirnya perlu diketahui bahwa saya belum menguji ini secara ekstensif dan mungkin ada kasus sudut di mana resep gagal. Jadi harap buat cadangan semuanya sebelum melanjutkan !Cuplikan bash berikut dapat digabungkan menjadi satu skrip besar yang kemudian harus dieksekusi di folder yang sama tempat repo berada
repo-org
. Tidak disarankan untuk menyalin dan menempel semuanya langsung ke jendela perintah (meskipun saya telah berhasil mengujinya)!0. Persiapan
Variabel
Filter skrip
1. Ekstraksi subdirektori
2. Penggantian subdirektori
Keterangan: Jika baru dibuat repo
repo-new
hang selamagit submodule update --init
kemudian mencoba untuk re-clone repositori rekursif sekali bukan:sumber
Ini melakukan konversi di tempat, Anda dapat mengembalikannya seperti yang Anda lakukan pada cabang filter (saya gunakan
git fetch . +refs/original/*:*
).Saya memiliki proyek dengan
utils
perpustakaan yang mulai berguna dalam proyek lain, dan ingin membagi sejarahnya menjadi submodul. Tidak berpikir untuk melihat SO terlebih dahulu jadi saya menulis sendiri, itu membangun sejarah secara lokal sehingga sedikit lebih cepat, setelah itu jika Anda mau, Anda dapat mengatur.gitmodules
file perintah pembantu dan semacamnya, dan mendorong sejarah submodul sendiri di mana saja kamu ingin.Perintah stripped itu sendiri ada di sini, dokumen ada di komentar, di perintah unstripped yang mengikuti. Jalankan sebagai perintahnya sendiri, dengan
subdir
set, sepertisubdir=utils git split-submodule
jika Anda memisahkanutils
direktori. Ini hacky karena ini hanya satu kali, tetapi saya mengujinya di subdirektori Dokumentasi dalam sejarah Git.sumber