Kita semua telah mendengar bahwa seseorang harus tidak pernah rebase menerbitkan karya, bahwa itu berbahaya, dll Namun, saya belum melihat resep yang dipasang untuk bagaimana menghadapi situasi dalam kasus rebase yang diterbitkan.
Sekarang, perhatikan bahwa ini hanya benar-benar layak jika repositori hanya diklon oleh sekelompok orang yang dikenal (dan sebaiknya kecil), sehingga siapa pun yang mendorong rebase atau reset dapat memberi tahu semua orang bahwa mereka perlu memperhatikan lain kali mereka mengambil(!).
Satu solusi jelas yang saya lihat akan berfungsi jika Anda tidak memiliki komitmen lokal foo
dan itu didasarkan pada:
git fetch
git checkout foo
git reset --hard origin/foo
Ini hanya akan membuang status lokal yang foo
mendukung riwayatnya sesuai dengan repositori jarak jauh.
Tetapi bagaimana seseorang menghadapi situasi tersebut jika seseorang telah melakukan perubahan lokal yang substansial pada cabang itu?
sumber
git pull --rebase && git push
. Jika Anda bekerjamaster
hanya, maka ini hampir tidak pernah gagal akan melakukan hal yang benar untuk Anda, bahkan jika Anda telah melakukan rebased dan mendorong di ujung yang lain.git reset --hard @{upstream}
sekarang setelah saya tahu mantra refspec ajaib untuk "lupakan apa yang saya miliki / miliki, gunakan apa yang saya ambil dari remote" Lihat komentar terakhir saya ke stackoverflow.com/a/15284176/717355push -f
): lihat jawaban saya di bawahJawaban:
Kembali selaras setelah push rebase sebenarnya tidak terlalu rumit dalam banyak kasus.
Yaitu. pertama-tama Anda menyiapkan bookmark di mana cabang jarak jauh awalnya berada, lalu Anda menggunakannya untuk memutar ulang komitmen lokal Anda sejak saat itu dan seterusnya ke cabang jarak jauh yang direbasis.
Rebasing seperti kekerasan: jika tidak menyelesaikan masalah, Anda hanya membutuhkan lebih banyak. ☺
Anda tentu saja dapat melakukan ini tanpa bookmark, jika Anda mencari
origin/foo
ID commit pra-rebase , dan menggunakannya.Ini juga bagaimana Anda menghadapi situasi di mana Anda lupa membuat bookmark sebelum mengambilnya. Tidak ada yang hilang - Anda hanya perlu memeriksa reflog untuk cabang jarak jauh:
Ini akan mencetak ID komit yang
origin/foo
mengarah ke sebelum pengambilan terbaru yang mengubah riwayatnya.Anda kemudian bisa dengan sederhana
sumber
git reflog show origin/foo
baris pertama yang mengatakan "fetch: forced-update"; itulah yang dicatat oleh git saat pengambilan menyebabkan cabang jarak jauh melakukan apa pun kecuali maju cepat. (Anda bisa melakukannya dengan tangan juga - pembaruan paksa mungkin adalah hal yang paling baru.)Saya akan mengatakan pemulihan dari bagian rebase hulu halaman manual git-rebase mencakup hampir semua ini.
Ini benar-benar tidak ada bedanya dengan memulihkan dari rebase Anda sendiri - Anda memindahkan satu cabang, dan mendasarkan kembali semua cabang yang ada dalam riwayat mereka ke posisi baru.
sumber
Dimulai dengan git 1,9 / 2,0 Q1 2014, Anda tidak perlu menandai asal cabang Anda sebelumnya sebelum rebasing pada cabang hulu ditulis ulang, seperti yang dijelaskan dalam Aristoteles Pagaltzis 's jawabannya :
Lihat komit 07d406b dan berkomitmen d96855f :
Itulah mengapa
git merge-base
perintah tersebut memiliki opsi baru:Misalnya, jika sejarah tampak seperti di mana:
Git 2.1 (Q3 2014) akan menambahkan untuk membuat fitur ini lebih kuat untuk ini: lihat komit 1e0dacd oleh John Keeping (
johnkeeping
)menangani dengan benar skenario di mana kita memiliki topologi berikut ini:
dimana:
B'
adalah versi tetapB
yang tidak identik dengan patchB
;C*
danD*
yang patch-identik denganC
danD
masing-masing dan konflik tekstual jika diterapkan dalam urutan yang salah;E
tergantung secara tekstualD
.Hasil yang benar dari
git rebase master dev
yaitu yangB
diidentifikasi sebagai garpu-titikdev
danmaster
, sehinggaC
,D
,E
adalah commit yang perlu diputar kemaster
; tetapiC
danD
identik dengan patchC*
danD*
dan dan karenanya dapat dihilangkan, sehingga hasil akhirnya adalah:Jika titik percabangan tidak teridentifikasi, maka memilih
B
ke cabang yang berisiB'
hasil dalam konflik dan jika komit yang identik dengan tambalan tidak diidentifikasi dengan benar, maka memilihC
ke cabang yang berisiD
(atau setaraD*
) menghasilkan konflik."
--fork-point
" Mode "git rebase
" mengalami kemunduran saat perintah ditulis ulang di C kembali di era 2.20, yang telah diperbaiki dengan Git 2.27 (Q2 2020).Lihat commit f08132f (09 Des 2019) oleh Junio C Hamano (
gitster
) .(Digabung oleh Junio C Hamano -
gitster
- di commit fb4175b , 27 Mar 2020)sumber