Saya memulai sebuah proyek beberapa bulan yang lalu dan menyimpan semuanya di dalam direktori utama. Di direktori utama saya "Project", ada beberapa subdirektori yang berisi hal-hal berbeda: Project / paper berisi dokumen yang ditulis dalam LaTeX Project / sourcecode / RailsApp berisi aplikasi rel saya.
"Project" adalah GITified dan ada banyak komit di direktori "paper" dan "RailsApp". Sekarang, karena saya ingin menggunakan cruisecontrol.rb untuk "RailsApp" saya, saya ingin tahu apakah ada cara untuk membuat submodul dari "RailsApp" tanpa kehilangan histori.
git
git-submodules
Cœur
sumber
sumber
Jawaban:
Saat ini ada cara yang jauh lebih mudah untuk melakukannya daripada secara manual menggunakan git filter-branch: git subtree
Instalasi
CATATAN
git-subtree
sekarang menjadi bagian darigit
(jika Anda menginstal contrib) mulai 1.7.11, jadi Anda mungkin sudah menginstalnya. Anda dapat memeriksanya dengan menjalankangit subtree
.Untuk menginstal git-subtree dari sumber (untuk versi git yang lebih lama):
Atau jika Anda menginginkan halaman manual dan semuanya
Pemakaian
Bagi yang lebih besar menjadi potongan yang lebih kecil:
Untuk dokumentasi rinci (halaman manual), silakan baca
git-subtree.txt
.sumber
git rm -rf ./foo
menghapusfoo
dariHEAD
tapi tidak memfiltermy-project
riwayat lengkap. Kemudian,git submodule add [email protected]:my-user/new-project.git foo
hanya membuatfoo
submodul mulai dariHEAD
. Dalam hal ini, scriptingfilter-branch
lebih unggul karena memungkinkan untuk mencapai "lakukan seolah-olah subdir adalah submodul sejak awal"Lihat git filter-branch .
The
Examples
bagian dari halaman manual menunjukkan cara mengekstrak sub-direktori dalam proyek itu sendiri sekaligus menjaga semua sejarah itu dan membuang sejarah file lain / direktori (hanya apa yang Anda cari).sumber
Salah satu cara untuk melakukannya adalah kebalikannya - hapus semuanya kecuali file yang ingin Anda simpan.
Pada dasarnya, buat salinan repositori, lalu gunakan
git filter-branch
untuk menghapus semuanya kecuali file / folder yang ingin Anda simpan.Misalnya, saya memiliki proyek tempat saya ingin mengekstrak file
tvnamer.py
ke repositori baru:Itu menggunakan
git filter-branch --tree-filter
untuk melewati setiap komit, menjalankan perintah dan komit ulang konten direktori yang dihasilkan. Ini sangat merusak (jadi Anda seharusnya hanya melakukan ini pada salinan repositori Anda!), Dan dapat memakan waktu cukup lama (sekitar 1 menit pada repositori dengan 300 komit dan sekitar 20 file)Perintah di atas hanya menjalankan skrip-shell berikut pada setiap revisi, yang tentunya harus Anda modifikasi (untuk membuatnya mengecualikan sub-direktori Anda, bukan
tvnamer.py
):Masalah terbesar yang jelas adalah meninggalkan semua pesan komit, bahkan jika pesan itu tidak terkait dengan file yang tersisa. Skrip git-remove-empty-commits , perbaiki ini ..
Anda perlu menggunakan
-f
argumen kekuatan, jalankanfilter-branch
lagi dengan apa pun direfs/original/
(yang pada dasarnya adalah cadangan)Tentu saja ini tidak akan pernah sempurna, misalnya jika pesan komit Anda menyebutkan file lain, tetapi ini sedekat yang diizinkan oleh git saat ini (sejauh yang saya ketahui).
Sekali lagi, jalankan ini hanya pada salinan repositori Anda! - tetapi secara ringkas, untuk menghapus semua file kecuali "thisismyfilename.txt":
sumber
git filter-branch
memiliki (sekarang?) opsi bawaan untuk menghapus komit kosong, yaitu--prune-empty
. Panduan yang lebih baikgit filter-branch
ada dalam jawaban atas pertanyaan ini: stackoverflow.com/questions/359424/…Baik CoolAJ86 dan jawaban apenwarr sangat mirip. Saya bolak-balik di antara keduanya mencoba memahami bagian yang hilang dari salah satunya. Di bawah ini adalah kombinasi keduanya.
Pertama navigasikan Git Bash ke root repo git yang akan dipecah. Dalam contoh saya inilah
~/Documents/OriginalRepo (master)
Di bawah ini adalah salinan di atas dengan nama yang dapat disesuaikan diganti dan menggunakan https sebagai gantinya. Folder root sekarang
~/Documents/_Shawn/UnityProjects/SoProject (master)
sumber
Jika Anda ingin mentransfer beberapa subset file ke repositori baru tetapi menyimpan riwayatnya, pada dasarnya Anda akan mendapatkan riwayat yang benar-benar baru. Cara kerjanya pada dasarnya adalah sebagai berikut:
Seharusnya agak mudah untuk mengotomatiskan ini jika Anda tidak keberatan menulis skrip kecil tapi berbulu. Terus terang, ya, tapi juga menyakitkan. Orang-orang telah melakukan penulisan ulang riwayat di Git sebelumnya, Anda dapat melakukan penelusuran untuk itu.
Alternatifnya: klon repositori, dan hapus kertas di klon, hapus aplikasi dalam aslinya. Ini akan memakan waktu satu menit, dijamin akan berhasil, dan Anda dapat kembali ke hal-hal yang lebih penting daripada mencoba memurnikan riwayat git Anda. Dan jangan khawatir tentang ruang hard drive yang digunakan oleh salinan riwayat yang berlebihan.
sumber