Cabang Git menyimpang setelah rebase

112

Saya telah mengubah basis cabang secara lokal yang sudah didorong.

Git menyarankan bahwa cabang dan remote saya telah menyimpang dan bahwa:

"dan masing-masing memiliki 109 dan 73 komit yang berbeda"

Akankah mendorong cabang saya menyelesaikan ini - yaitu apakah ini yang diharapkan setelah rebase?

Marty Wallace
sumber
Saya memiliki masalah yang sama. Bisakah kita mengatakan bahwa "cara yang benar untuk dilakukan" adalah dengan mendasarkan kembali cabang lokal dan baru kemudian mendorong?
Mher Didaryan

Jawaban:

154

Saat Anda me-rebase sebuah cabang, Anda harus menulis ulang komit untuk komit apa pun yang berada di atas komit di cabang tempat Anda melakukan rebasing. Ini karena salah satu properti komit adalah induknya (atau orang tuanya). Saat Anda melakukan rebase, Anda mengubah induk dari komit lokal terlama di cabang Anda - dan dengan demikian mengubah hash komit dari semua komit lokal Anda, karena perubahan ini menggelembung melalui komit secara transitif.

Karena Anda sudah mendorong cabang tersebut, Anda seharusnya telah menggabungkan di cabang sumber, daripada melakukan rebasing terhadapnya. Dimungkinkan untuk "memaksa mendorong" cabang baru Anda (menggunakan -fbendera), tetapi dorongan normal tidak akan berfungsi, karena integritas riwayat cabang akan terganggu. Jika Anda berkolaborasi dengan orang lain di cabang ini, memaksa mendorong adalah ide yang buruk, karena akan menyebabkan kolaborator lain menjadi sangat bingung ketika riwayat mereka tiba-tiba tidak cocok.

TL; DR - Jika Anda tidak berkolaborasi, dorong cabang menggunakan push -f. Jika ya, setel ulang cabang ke keadaan sebelumnya, dan gabungkan di cabang sumber sebagai gantinya.

Jason LeBrun
sumber
1
"Karena Anda sudah mendorong cabang, Anda seharusnya bergabung di cabang sumber" - mengapa demikian?
hammett
1
@HamiltonVerissimo Jason kalimat pertama: "Saat Anda merebase sebuah cabang, Anda harus menulis ulang komit untuk komit apa pun yang berada di atas komit di cabang yang Anda rebasing." Meskipun perubahan yang ditangkap dalam komit "di atas" memiliki konten logis yang sama, perubahan tersebut diterapkan ke basis yang berbeda dan oleh karena itu merupakan komit yang berbeda dengan hash yang berbeda. Jika pengembang lain bekerja dari cabang pra-rebased, maka melakukan git push -f akan sangat mengganggu alur kerja mereka. Jadi, karena cabang ini telah didorong ke sumber publik, dia seharusnya digabungkan.
awolf
4
Anda juga dapat menggunakan push --force-with-lease jika Anda tidak yakin apakah orang lain sudah mendorong sesuatu.
Konsol
1
@ jason-lebrun Bukankah sisi negatif dari menggabungkan perubahan hulu yang dapat Anda timpa pekerjaan Anda sendiri tanpa peringatan? Apakah konflik penggabungan terdeteksi dengan cara yang sama seperti saat melakukan rebasing? Misalnya, jika saya menghapus bagian dari file di cabang saya karena tidak lagi diperlukan, tetapi orang lain membuat perubahan sepele ke bagian yang sama di hulu, seperti menghapus beberapa spasi atau tindakan temukan / ganti global, tidak akan menggabungkan itu di atas cabang saya menggantikan penghapusan saya dengan versi yang diubah sepele?
Chris Bloom
1
Apakah menggabungkan cabang lain dengan Anda bukan ide yang buruk? Misalnya Menggabungkan master menjadi cabang fitur - bukankah itu akan membuat komit baru untuk itu? Akankah itu tidak menghasilkan komit ekstra setelah cabang fitur ini jika digabungkan ke master nanti?
Ross
55

Semua komitmen Anda telah berubah id, jadi pengalihannya tidak benar - benar menyimpang.

Untuk menyelesaikan masalah Anda, Anda harus menimpa cabang jarak jauh Anda:

git push -f origin experiment

http://git-scm.com/book/ch3-6.html

Penjelasan:

Lihat bagaimana di gambar ini C3 tidak diletakkan sebagai C3 setelah rebase, tetapi sebagai C3 '. Ini karena ini bukan C3, tetapi semua kodenya berubah.

Rebase

Pada gambar lain ini Anda mendapatkan gambaran tentang apa yang dilihat rebase ketika remote terlibat, dan mengapa ada pengalihan.

diverge dan git push

Bagaimanapun, setelah Anda melakukan dorongan paksa, itu akan memberi tahu Anda bahwa itu melakukan (pembaruan paksa), Anda seharusnya baik-baik saja pada saat itu.

Lihat link di atas, dan cari "git push --force". Anda akan melihat penjelasan yang lebih detail.

mimoralea
sumber
3
Ya. Saya rasa ini menyelesaikan masalah. Namun, dorongan paksa mungkin tidak berfungsi saat Anda bekerja dalam tim saat dorongan Anda mungkin menimpa pekerjaan terbaru yang didorong oleh orang lain. Apakah saya benar?
Hari Krishna Ganji
Ini mungkin tidak memiliki efek yang diinginkan. Pastikan Anda menggabungkan perubahan Anda 'maju cepat' sebelum melakukan rebase.
mimoralea
1

Saya berhasil dengan penyimpangan rebase untuk dorongan dengan melakukan hal berikut:

git checkout mybranch
git pull
git push origin mybranch

Tarikan menyelesaikan perbedaan.

SEBELUM menariknya

Your branch and 'origin/mybranch' have diverged,
and have 2 and 1 different commit(s) each, respectively.

Keluaran TARIK

Penggabungan dilakukan secara rekursif. mypath / myfile.py | 12 +++++++++++ - 1 file diubah, 11 penyisipan (+), 1 penghapusan (-)

SETELAH menarik

Cabang Anda berada di depan 'origin / mybranch' dengan 3 komit.

SETELAH PUSH

mybranch adalah 3 di depan cabang yang masih memiliki pesan penggabungan permintaan tarik terbuka ditambahkan ke riwayat komit Gabungkan cabang mybranch dari remote ke mybranch

Saya berasumsi ini mungkin yang dilakukan oleh dorongan paksa, dan saya belum memverifikasi.

Seperti yang dikatakan orang lain, hindari rebase jika Anda sudah memiliki permintaan tarik terbuka. Saya memberikan contoh ini sebagai sesuatu yang berhasil untuk saya.

zerocog
sumber
1

Ini bisa diperbaiki tanpa dorongan paksa dengan melakukan rebasing cabang target ke cabang lokal Anda saat ini, beralih ke cabang target Anda, lalu rebasing cabang lokal Anda ke target. Ini tidak menyimpang sejak komit yang mungkin hilang ditambahkan dan tidak perlu dibuat lagi. Contoh penjelasan lebih mudah:

  1. cabang utama berkembang
  2. Anda melakukan pembayaran fitur cabang baru / doing_stuff
  3. Seorang anggota tim mendorong komitmen baru untuk berkembang

Jika Anda BELUM memperbarui cabang pengembangan Anda, maka "git checkout develop" && "fitur git rebase / doing_stuff" akan bekerja dengan benar karena tidak ada komit yang ditambahkan sejak pembayaran Anda. Namun, jika Anda telah memeriksa pengembangan dan menarik komitmen baru, maka Anda akan melihat perbedaan ini jika Anda mencoba melakukan rebase karena komitmen baru terlihat. Perbaikan yang mudah tanpa memaksa memaksa (biasanya bukan ide yang baik dalam lingkungan tim) adalah dengan:

  1. fitur git checkout / doing_stuff
  2. git rebase berkembang
  3. git checkout develop
  4. fitur git rebase / doing_stuff

Rebase dari langkah 2 membawa komit yang hilang ke dalam fitur / doing_stuff jadi ketika langkah 4 muncul, itu adalah yang terbaru dan tidak perlu membuat komit baru untuk perubahan.

Ini adalah solusi yang saya tahu berfungsi karena saya baru saja mengalami ini dan melakukan langkah-langkah di atas untuk berhasil mendorong pengembangan tanpa memaksa. Saya bekerja dalam tim yang terdiri lebih dari 50 pengembang sehingga dilarang memaksa mendorong apa pun selain cabang pengujian saya sendiri, jadi saya harus menemukan resolusi.

Chris
sumber