git rebase -i <any earlier commit>. Ini menampilkan daftar komit di editor teks Anda yang dikonfigurasi.
Temukan komit yang ingin Anda masukkan setelahnya (anggap saja itu a1b2c3d). Di editor Anda, untuk baris itu, ubah pickkeedit .
Mulailah rebase dengan menutup editor teks Anda (simpan perubahan Anda). Ini membuat Anda berada pada prompt perintah dengan komit yang Anda pilih sebelumnya ( a1b2c3d) seolah-olah itu baru saja dilakukan .
Lakukan perubahan Anda dan 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.
Ini menambahkan komit baru setelah komit, yang setelah komit yang saya rebasing ke (juga komit terakhir), alih-alih tepat setelah yang saya ubah. Hasilnya sama seperti jika saya baru saja membuat komit baru di akhir dengan perubahan yang ingin saya sisipkan. Sejarah saya menjadi A -- B -- C -- Dbukan diinginkan A -- D -- B -- C.
XedinTak Diketahui
2
@XedinTak Diketahui: Maka Anda tidak menggunakan Rebase dengan benar.
SLaks
3
Sekarang 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 Bpick, kami menyisipkan baris barupick 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.
Kaz
1
@Kaz Sepertinya jawaban yang berbeda dan valid.
BartoszKP
3
Lebih mudah lagi, Anda dapat menggunakan breakkata kunci di editor pada barisnya sendiri di antara dua komit (atau pada baris pertama, untuk memasukkan komit sebelum komit yang Anda tentukan).
SimonT
30
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.
Saya tidak bisa mengikuti jawaban yang diterima oleh SLaks, tetapi ini berhasil untuk saya. Setelah saya mendapatkan riwayat komit yang saya inginkan, saya harus git push --forcemengubah repo jarak jauh.
escapecharacter
1
Saat menggunakan rebase menggunakan opsi -Xtheirs otomatis menyelesaikan konflik dengan benar, jadi git rebase temp branch -Xtheirs. Jawaban yang berguna untuk memasukkan skrip!
David C
Untuk pemula seperti saya, saya ingin menambahkannya setelahnya 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.
Pugsley
19
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
Ide yang bagus, namun mungkin sulit untuk memperkenalkan D pada C, jika Anda bermaksud agar perubahan ini ditulis. kepada A.
BartoszKP
Saya memiliki situasi di mana saya memiliki 3 komitmen yang ingin saya buat ulang bersama dan komitmen di tengah yang tidak terkait. Ini sangat bagus untuk bisa memindahkan komit itu sebelumnya atau nanti ke baris komit.
melepaskan
13
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.
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.
Maaf, tapi saya kesulitan memahami bagaimana ini "menghindari rebase". Anda sedang berlari di rebasesini. Tidak banyak perbedaan apakah Anda akan membuat komit selama rebase atau sebelumnya.
BartoszKP
Waduh, maksud saya menghindari "edit hack" selama rebase, saya kira saya mengucapkannya dengan buruk.
axerologementy
Baik. Jawaban saya juga tidak menggunakan fitur "edit" rebase. Namun, ini adalah pendekatan valid lainnya - terima kasih! :-)
BartoszKP
Sejauh ini, ini adalah solusi terbaik!
Theodore R. Smith
6
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.
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, ubahpick
keedit
.a1b2c3d
) seolah-olah itu baru saja dilakukan .git commit
( BUKAN mengubah, tidak seperti kebanyakanedit
). 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.
sumber
A -- B -- C -- D
bukan diinginkanA -- D -- B -- C
.D
bisa menjadi komit di mana saja. Misalkan kita memilikiA - B - C
dan kita memiliki beberapa komitD
yang bahkan tidak ada di cabang ini. Kami tahu SHA-nya, tapi kami bisa melakukannyagit rebase -i HEAD~3
. Sekarang di antara garisA
danB
pick
, kami menyisipkan baris barupick
yang mengatakanpick SHA
, memberikan hash yang diinginkanD
. Tidak perlu hash lengkap, cukup hash yang dipersingkat.git rebase -i
hanya cherry picks apa pun yang terdaftar denganpick
baris di buffer; mereka tidak harus yang asli yang terdaftar untuk Anda.break
kata 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
):melakukan perubahan dan mengkomitnya, membuat komit, sebut saja
N
:(atau
git add
diikuti olehgit commit
)rebase komit yang ingin Anda miliki setelah komit baru (dalam hal ini komit
B
danC
) ke komit baru:(mungkin Anda perlu menggunakan
-p
untuk mempertahankan penggabungan, jika ada - terima kasih kepada komentar tidak lagi ada oleh ciekawy )hapus cabang sementara:
Setelah ini, sejarahnya terlihat sebagai berikut:
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.
sumber
git push --force
mengubah repo jarak jauh.git rebase temp branch -Xtheirs
. Jawaban yang berguna untuk memasukkan skrip!git rebase temp branch
, tetapi sebelumnyagit branch -d temp
, yang harus Anda lakukan hanyalah memperbaiki dan menyelesaikan konflik dan masalah penggabungangit rebase --continue
, yaitu tidak perlu melakukan apa pun, dll.Solusi yang lebih mudah:
Buat komit baru Anda di akhir, D.Sekarang Anda memiliki:
Lalu lari:
Git akan membuka editor Anda dan akan terlihat seperti ini:
Pindahkan saja D ke atas seperti ini, lalu simpan dan keluar
Sekarang Anda akan memiliki:
sumber
Dengan asumsi bahwa riwayat komit adalah
preA -- A -- B -- C
, jika Anda ingin menyisipkan komit antaraA
danB
, langkah-langkahnya adalah sebagai berikut:git rebase -i hash-of-preA
Git akan membuka editor Anda. Kontennya mungkin seperti ini:
Ubah yang pertama
pick
menjadiedit
: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 diff
untuk menemukan penanda konflik dan mengatasinya. Setelah menyelesaikan semua konflik, Anda perlu menggunakangit 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
.sumber
Berikut adalah strategi yang menghindari melakukan "edit hack" selama rebase terlihat pada jawaban lain yang saya baca.
Dengan menggunakan
git rebase -i
Anda mendapatkan daftar komit sejak komit itu. Tambahkan saja "break" di bagian atas file, ini akan menyebabkan rebase rusak pada saat itu.Setelah diluncurkan,
git rebase
sekarang akan berhenti di titik "istirahat". Anda sekarang dapat mengedit file Anda dan membuat komit Anda secara normal. Anda kemudian dapat melanjutkan rebase dengangit rebase --continue
. Ini dapat menyebabkan konflik yang harus Anda perbaiki. Jika Anda tersesat, jangan lupa Anda selalu dapat membatalkan penggunaangit 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.sumber
rebase
sini. 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
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
master
untuk nama cabang Anda)1) Mulailah dengan mengarahkan HEAD ke tempat yang tepat
(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
3) Kemudian bawa salinan dari komit B dan C yang terakhir hilang (akan menjadi baris yang sama jika ada lebih banyak komit)
(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
C
danC'
, apakah OK atau KO.(BAIK) 4-OK) Akhirnya, pindahkan ref dari
master
(OR) 4-KO) Biarkan
master
tidak berubahJika 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 kembaliHEAD
dengangit checkout master
Dalam kedua kasus tersebut (OK atau KO), pada saat ini hanya checkout
master
lagi untuk memasang kembaliHEAD
.sumber