Misalkan saya memiliki riwayat komit berikut di cabang khusus lokal saya:
A -- B -- C
Bagaimana cara menyisipkan komit baru antara Adan B?
Misalkan saya memiliki riwayat komit berikut di cabang khusus lokal saya:
A -- B -- C
Bagaimana cara menyisipkan komit baru antara Adan B?
Jawaban:
Ini bahkan lebih mudah daripada jawaban OP.
git rebase -i <any earlier commit>. Ini menampilkan daftar komit di editor teks Anda yang dikonfigurasi.a1b2c3d). Di editor Anda, untuk baris itu, ubah pickkeedit .a1b2c3d) seolah-olah itu baru saja dilakukan .git commit( BUKAN mengubah, tidak seperti kebanyakan edit). Ini membuat komit baru setelah yang Anda pilih.git rebase --continue. Ini memutar ulang komit yang berurutan, membiarkan komit baru Anda dimasukkan di tempat yang benar.Berhati-hatilah karena ini akan menulis ulang sejarah, dan menghancurkan siapa pun yang mencoba menariknya.
A -- B -- C -- Dbukan diinginkan A -- D -- B -- C.
Dbisa menjadi komit di mana saja. Misalkan kita memiliki A - B - Cdan kita memiliki beberapa komit Dyang bahkan tidak ada di cabang ini. Kami tahu SHA-nya, tapi kami bisa melakukannya git rebase -i HEAD~3. Sekarang di antara garis Adan B pick, kami menyisipkan baris baru pick yang mengatakan pick SHA, memberikan hash yang diinginkan D. Tidak perlu hash lengkap, cukup hash yang dipersingkat. git rebase -ihanya cherry picks apa pun yang terdaftar dengan pickbaris di buffer; mereka tidak harus yang asli yang terdaftar untuk Anda.
breakkata kunci di editor pada barisnya sendiri di antara dua komit (atau pada baris pertama, untuk memasukkan komit sebelum komit yang Anda tentukan).
Ternyata cukup sederhana, jawabannya ada di sini . Misalkan Anda berada di cabang branch. Lakukan langkah-langkah ini:
buat cabang sementara dari komit setelah Anda ingin memasukkan komit baru (dalam hal ini komit A):
git checkout -b temp A
melakukan perubahan dan mengkomitnya, membuat komit, sebut saja N:
git commit -a -m "Message"
(atau git adddiikuti oleh git commit)
rebase komit yang ingin Anda miliki setelah komit baru (dalam hal ini komit B dan C) ke komit baru:
git rebase temp branch
(mungkin Anda perlu menggunakan -puntuk mempertahankan penggabungan, jika ada - terima kasih kepada komentar tidak lagi ada oleh ciekawy )
hapus cabang sementara:
git branch -d temp
Setelah ini, sejarahnya terlihat sebagai berikut:
A -- N -- B -- C
Ada kemungkinan bahwa beberapa konflik akan muncul saat rebasing.
Jika cabang Anda bukan cabang lokal, ini akan memperkenalkan sejarah penulisan ulang, jadi bisa menyebabkan masalah serius.
git push --forcemengubah repo jarak jauh.
git rebase temp branch -Xtheirs. Jawaban yang berguna untuk memasukkan skrip!
git rebase temp branch, tetapi sebelumnya git branch -d temp, yang harus Anda lakukan hanyalah memperbaiki dan menyelesaikan konflik dan masalah penggabungan git rebase --continue, yaitu tidak perlu melakukan apa pun, dll.
Solusi yang lebih mudah:
Buat komit baru Anda di akhir, D.Sekarang Anda memiliki:
A -- B -- C -- D
Lalu lari:
$ git rebase -i hash-of-A
Git akan membuka editor Anda dan akan terlihat seperti ini:
pick 8668d21 B
pick 650f1fc C
pick 74096b9 D
Pindahkan saja D ke atas seperti ini, lalu simpan dan keluar
pick 74096b9 D
pick 8668d21 B
pick 650f1fc C
Sekarang Anda akan memiliki:
A -- D -- B -- C
Dengan asumsi bahwa riwayat komit adalah preA -- A -- B -- C, jika Anda ingin menyisipkan komit antara Adan B, langkah-langkahnya adalah sebagai berikut:
git rebase -i hash-of-preA
Git akan membuka editor Anda. Kontennya mungkin seperti ini:
pick 8668d21 A
pick 650f1fc B
pick 74096b9 C
Ubah yang pertama pickmenjadi edit:
edit 8668d21 A
pick 650f1fc B
pick 74096b9 C
Simpan dan keluar.
Ubah kode Anda lalu git add . && git commit -m "I"
git rebase --continue
Sekarang riwayat komit Git Anda adalah preA -- A -- I -- B -- C
Jika Anda menemui konflik, Git akan berhenti pada komit ini. Anda dapat menggunakan git diffuntuk menemukan penanda konflik dan mengatasinya. Setelah menyelesaikan semua konflik, Anda perlu menggunakan git add <filename>untuk memberi tahu Git bahwa konflik telah diselesaikan dan kemudian menjalankan kembaligit rebase --continue .
Jika Anda ingin membatalkan rebase, gunakan git rebase --abort.
Berikut adalah strategi yang menghindari melakukan "edit hack" selama rebase terlihat pada jawaban lain yang saya baca.
Dengan menggunakan git rebase -iAnda mendapatkan daftar komit sejak komit itu. Tambahkan saja "break" di bagian atas file, ini akan menyebabkan rebase rusak pada saat itu.
break
pick <B's hash> <B's commit message>
pick <C's hash> <C's commit message>
Setelah diluncurkan, git rebasesekarang akan berhenti di titik "istirahat". Anda sekarang dapat mengedit file Anda dan membuat komit Anda secara normal. Anda kemudian dapat melanjutkan rebase dengan git rebase --continue. Ini dapat menyebabkan konflik yang harus Anda perbaiki. Jika Anda tersesat, jangan lupa Anda selalu dapat membatalkan penggunaan git rebase --abort.
Strategi ini dapat digeneralisasikan untuk memasukkan komit di mana saja, cukup letakkan "istirahat" di tempat Anda ingin memasukkan komit.
Setelah menulis ulang sejarah, jangan lupa git push -f. Peringatan biasa tentang orang lain yang mengambil cabang Anda berlaku.
rebasesini. Tidak banyak perbedaan apakah Anda akan membuat komit selama rebase atau sebelumnya.
Sudah banyak jawaban bagus di sini. Saya hanya ingin menambahkan solusi "tanpa rebase", dalam 4 langkah mudah.
Ringkasan
git checkout A
git commit -am "Message for commit D"
git cherry-pick A..C
git branch -f master HEAD
Penjelasan
(Catatan: satu keuntungan dari solusi ini adalah Anda tidak menyentuh cabang Anda sampai langkah terakhir, ketika Anda 100% yakin Anda baik-baik saja dengan hasil akhirnya, jadi Anda memiliki langkah "pra-konfirmasi" yang sangat berguna memungkinkan untuk pengujian AB .)
Keadaan awal (saya asumsikan masteruntuk nama cabang Anda)
A -- B -- C <<< master <<< HEAD
1) Mulailah dengan mengarahkan HEAD ke tempat yang tepat
git checkout A
B -- C <<< master
/
A <<< detached HEAD
(Secara opsional di sini, daripada melepaskan HEAD, kita dapat membuat cabang sementara dengan git checkout -b temp A, yang perlu kita hapus di akhir proses. Kedua varian bekerja, lakukan seperti yang Anda inginkan karena yang lainnya tetap sama)
2) Buat komit D baru untuk dimasukkan
# at this point, make the changes you wanted to insert between A and B, then
git commit -am "Message for commit D"
B -- C <<< master
/
A -- D <<< detached HEAD (or <<< temp <<< HEAD)
3) Kemudian bawa salinan dari komit B dan C yang terakhir hilang (akan menjadi baris yang sama jika ada lebih banyak komit)
git cherry-pick A..C
# (if any, resolve any potential conflicts between D and these last commits)
B -- C <<< master
/
A -- D -- B' -- C' <<< detached HEAD (or <<< temp <<< HEAD)
(Pengujian AB nyaman di sini jika diperlukan)
Sekarang saatnya untuk memeriksa kode Anda, menguji apa pun yang perlu diuji, dan Anda juga dapat membedakan / membandingkan / memeriksa apa yang Anda miliki dan apa yang akan Anda dapatkan setelah operasi.
4) Tergantung pada pengujian Anda antara Cdan C', apakah OK atau KO.
(BAIK) 4-OK) Akhirnya, pindahkan ref darimaster
git branch -f master HEAD
B -- C <<< (B and C are candidates for garbage collection)
/
A -- D -- B' -- C' <<< master
(OR) 4-KO) Biarkan mastertidak berubah
Jika Anda membuat cabang sementara, hapus saja dengan git branch -d <name>, tetapi jika Anda memilih rute HEAD yang terpisah, tidak ada tindakan yang diperlukan sama sekali pada saat ini, komit baru akan memenuhi syarat untuk pengumpulan sampah tepat setelah Anda melampirkan kembali HEADdengangit checkout master
Dalam kedua kasus tersebut (OK atau KO), pada saat ini hanya checkout masterlagi untuk memasang kembali HEAD.