Saya telah bereksperimen dengan menggunakan subtree git dan telah mengalami situasi berikut.
Saya menggunakan subtree git untuk menambahkan proyek eksternal ke repo saya, saya sengaja menyimpan semua sejarah untuk proyek hulu karena saya ingin dapat merujuk ke sejarah proyek dan juga berkontribusi kembali ke proyek hulu nanti.
Ternyata, kontributor lain untuk proyek upstream secara tidak sengaja mendorong file besar ke cabang master. Untuk mengatasinya, proyek hulu menulis ulang sejarah dan kekuatan didorong ke master. Saat membuat "monorepo" saya, saya menyertakan komit ini dan saya juga ingin menghapusnya.
Bagaimana saya bisa memperbarui repositori saya untuk mencerminkan sejarah baru subtree?
Upaya pertama saya adalah menggunakan cabang-filter untuk sepenuhnya menghapus subtree dan semua riwayat.
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch upstream-project-dir' --prune-empty HEAD
Setelah versi subtree lama dihapus, saya bisa menambahkan ulang subtree menggunakan master hulu yang baru. Namun, ini tidak berhasil karena untuk beberapa alasan sejarah komit masih muncul di git log output.
Memperbarui
Saya telah menulis langkah-langkah untuk membuat contoh yang dapat direproduksi secara minimal.
Pertama buat git repo kosong.
git init test-monorepo cd ./test-monorepo
Buat komit awal.
echo hello world > README git add README git commit -m 'initial commit'
Sekarang tambahkan subtree untuk proyek eksternal.
git remote add thirdparty [email protected]:teivah/algodeck.git git fetch thirdparty git subtree add --prefix algodeck thirdparty master
Buat beberapa komitmen di monorepo
echo dont panic >> algodeck/README.md git commit -a -m 'test commit'
Sekarang coba gunakan cabang-filter git untuk menghapus subtree.
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch algodeck' --prune-empty HEAD
Memeriksa output log git, saya berharap hanya melihat komit awal saya.
git log
git gc --prune=now
hanya menghapus komit yang tidak munculgit log
?git log
, tidak ada argumen dan saya masih melihat komitmen lama.Jawaban:
Anda sudah mendapatkan komitmen buruk dalam riwayat Anda dan Anda harus menyingkirkannya sebelum melanjutkan
mari kita asumsikan Anda memiliki
master
komit terakhir dialihkan dan belum dapat melakukan hal lain (saya benar-benar tidak memiliki cabang Anda di depan mata, jadi saya perlu mengasumsikan sesuatu untuk memulai dengan)Anda dapat checkout ke komit sebelumnya dan mendorong penanda cabang Anda 1 langkah mundur (atau X langkah mundur) yang tidak akan berbahaya dalam hal apa pun dan kemudian tarik lagi
misalnya
git checkout master~1
untuk memeriksa komitmen induk, git memperingatkan kita dari cabanggit branch master -f
untuk memaksa checkout saat ini untuk menjadi master lagi, yaitu benar-benar memutar ulang cabang master ke komit sebelumnya (atau X komit sebelumnya), dan dari sini, tidak masalah apakah hulu melakukan kekuatan atau tidak, kita dapat melanjutkan secara normal, atau bahkan kembali ke langkah di atas jika diperlukan, kita hanya dapat menarik master lagi, tanpa kehilangan apa pun dari hulu (yang bagi kita bisa dibaca-saja juga, kita tidak akan mendorong apa pun untuk ini)git checkout master
untuk berada di cabang master "rewound" kami, komit yang sama dengan yang kami tuju, tetapi sekarang berada di cabanggit pull
untuk menarik master lagi (bisa dengan atau tanpa--prune
), jika hulu dialihkan, kita akan kembali ke jalur dari sini, jika tidak, kita akan mendapatkan yang sama yang kita miliki, jika kita mendapatkan yang sama dan tidak seharusnya, mungkin kita perlu kembali ke langkah 1 di atas dan memundurkan lebih banyak komitmen, misalnyagit checkout master~5
atau apa pun (sesuai kebutuhan)sumber
git subtree
pada repo Anda, bersihkan riwayat commit untuk remote ini:
jika salah satu dari komit Anda memiliki komit yang menyertakan file besar, tulis ulang riwayat Anda sehingga file besar ini tidak lagi direferensikan
Dengan dua langkah ini, file besar tidak akan direferensikan lagi oleh komit di repo Anda.
Ini juga akan dihapus dari hard drive Anda pada suatu saat, ketika git menjalankan pengumpul sampahnya dan penundaan kadaluarsa untuk gumpalan yang menggantung telah tercapai.
Jika Anda memiliki kebutuhan mendesak untuk menghapus file besar ini ASAP dari hard drive Anda:
Lari secara manual
sumber