Ada 2 langkah untuk mencapai ini:
- Buat komit kosong baru
- Tulis ulang riwayat untuk memulai dari komit kosong ini
Kami akan menempatkan komit kosong yang baru di cabang sementara newroot
untuk kenyamanan.
1. Buat komit kosong baru
Ada beberapa cara Anda bisa melakukan ini.
Hanya menggunakan pipa ledeng
Pendekatan terbersih adalah dengan menggunakan pipa ledeng Git hanya untuk membuat komit secara langsung, yang menghindari menyentuh copy pekerjaan atau indeks atau cabang mana yang diperiksa, dll.
Buat objek pohon untuk direktori kosong:
tree=`git hash-object -wt tree --stdin < /dev/null`
Bungkus sebuah komit di sekitarnya:
commit=`git commit-tree -m 'root commit' $tree`
Buat referensi untuk itu:
git branch newroot $commit
Anda tentu saja dapat mengatur ulang seluruh prosedur menjadi satu-liner jika Anda cukup tahu shell Anda.
Tanpa pipa ledeng
Dengan perintah porselen biasa, Anda tidak dapat membuat komit kosong tanpa memeriksa newroot
cabang dan memperbarui indeks dan copy pekerjaan berulang kali, tanpa alasan yang bagus. Tetapi beberapa mungkin menemukan ini lebih mudah untuk dipahami:
git checkout --orphan newroot
git rm -rf .
git clean -fd
git commit --allow-empty -m 'root commit'
Perhatikan bahwa pada versi Git yang sangat lama yang tidak memiliki --orphan
sakelar checkout
, Anda harus mengganti baris pertama dengan ini:
git symbolic-ref HEAD refs/heads/newroot
2. Tulis ulang riwayat untuk memulai dari komit kosong ini
Anda memiliki dua opsi di sini: rebasing, atau penulisan ulang riwayat bersih.
Rebasing
git rebase --onto newroot --root master
Ini memiliki sifat kesederhanaan. Namun, itu juga akan memperbarui nama dan tanggal committer pada setiap komit terakhir di cabang.
Juga, dengan beberapa riwayat kasus tepi, itu bahkan mungkin gagal karena menggabungkan konflik - terlepas dari kenyataan bahwa Anda rebasing ke komit yang tidak mengandung apa pun.
Menulis ulang sejarah
Pendekatan yang lebih bersih adalah menulis ulang cabang. Berbeda dengan dengan git rebase
, Anda harus mencari komit yang dimulai dari cabang Anda:
git replace <currentroot> --graft newroot
git filter-branch master
Penulisan ulang terjadi pada langkah kedua, jelas; itu langkah pertama yang perlu penjelasan. Apa yang git replace
dilakukan itu memberi tahu Git bahwa setiap kali ia melihat referensi ke objek yang ingin Anda ganti, Git seharusnya melihat penggantian objek itu.
Dengan --graft
sakelar, Anda mengatakan sesuatu yang sedikit berbeda dari biasanya. Anda mengatakan belum memiliki objek pengganti, tetapi Anda ingin mengganti <currentroot>
objek komit dengan salinan dirinya sendiri kecuali komit induk pengganti haruslah yang terdaftar (yaitu newroot
komit ). Kemudian git replace
lanjutkan dan buat komit ini untuk Anda, dan kemudian nyatakan komit itu sebagai pengganti komit asli Anda.
Sekarang jika Anda melakukan git log
, Anda akan melihat bahwa segala sesuatu sudah terlihat seperti yang Anda inginkan: cabang dimulai newroot
.
Namun, perhatikan bahwa git replace
sebenarnya tidak memodifikasi histori - juga tidak menyebar keluar dari repositori Anda. Itu hanya menambahkan redirect lokal ke repositori Anda dari satu objek ke objek lain. Artinya, tidak ada orang lain yang melihat efek dari penggantian ini - hanya Anda.
Itu sebabnya filter-branch
langkah ini perlu. Dengan git replace
Anda membuat salinan yang tepat dengan komitmen induk yang disesuaikan untuk komit root; git filter-branch
kemudian ulangi proses ini untuk semua komitmen berikut juga. Di situlah sejarah sebenarnya ditulis ulang sehingga Anda dapat membagikannya.