Apa perbedaan antara 'git merge' dan 'git rebase'?

499

Apa perbedaan antara git mergedan git rebase?

Daniel Peñalba
sumber
14
sejak jawaban saya dihapus, kunjungi tautan ini untuk mendapatkan jawaban yang tepat untuk pertanyaan ini: git-scm.com/book/en/Git-Branching-Rebasing#The-Basic-Rebase
HiB
6
Omong-omong saya akan menambahkan situs ini. Yang perlu Anda ketahui tentang git belajar dengan bermain: pcottle.github.io/learnGitBranching
Rollyng
Baca ini dulu: git-scm.com/book/en/v2/… Lalu: git-scm.com/book/en/v2/Git-Branching-Rebasing Anda akan sangat mengerti.
Liber

Jawaban:

867

Misalkan awalnya ada 3 komit, A, B, C:

ABC

Kemudian pengembang Dan membuat komit D, dan pengembang Ed membuat komit E:

ABCDE

Jelas, konflik ini harus diselesaikan entah bagaimana. Untuk ini, ada 2 cara:

MERGE :

ABCDEM

Keduanya berkomitmen Ddan Emasih ada di sini, tetapi kami membuat gabungan komit Myang mewarisi perubahan dari keduanya Ddan E. Namun, ini menciptakan bentuk berlian , yang menurut banyak orang sangat membingungkan.

REBASE :

ABCDER

Kami membuat komit R, yang isi file aktualnya identik dengan gabungan komit di Matas. Tapi, kita menyingkirkan komit E, seperti tidak pernah ada (dilambangkan dengan titik - titik hilang). Karena penghapusan ini, Eharus lokal untuk pengembang Ed dan seharusnya tidak pernah didorong ke repositori lain. Keuntungan rebase adalah bentuk berlian dihindari, dan sejarah tetap garis lurus yang bagus - kebanyakan pengembang menyukainya!

mvp
sumber
53
Ilustrasi yang bagus. Namun, saya tidak sepenuhnya setuju dengan nada positif bahwa rebase ditangani. Dalam konflik gabungan dan rebase dapat terjadi yang membutuhkan resolusi manual. Dan seperti biasa ketika programmer terlibat ada kemungkinan kesalahan alias bug. Jika kesalahan gabungan terjadi, seluruh tim atau komunitas dapat melihat gabungan dan memverifikasi apakah bug diperkenalkan di sana. Sejarah rebase tetap dalam 1 repo pengembang dan bahkan di sana hanya terbatas seumur hidup di reflog. Mungkin terlihat lebih bagus, tetapi tidak ada orang lain yang bisa melihat dengan mudah apa yang salah.
Uwe Geuder
"Namun, ini menciptakan bentuk berlian, yang menurut banyak orang sangat membingungkan." Um ... bisakah Anda menjelaskan?
Greg Maletic
@GregMaletic: Bentuk berlian adalah sejarah non-linear. Saya tidak tahu tentang Anda, tetapi saya tidak suka hal-hal yang tidak linier secara umum. Yang mengatakan, Anda dipersilakan untuk menggunakan penggabungan dengan berlian jika Anda benar-benar menyukainya - tidak ada yang memaksa Anda.
mvp
1
Walaupun jawaban ini sangat membantu, akan lebih baik jika Anda menambahkan perintah git yang sebenarnya dengan file foo.txt sederhana untuk mereproduksi secara lokal. Seperti kata pengguna terakhir, tidak jelas siapa yang melakukan rebase.
Vortex
1
@ferrel: Saya tidak berpikir Anda mendapatkannya dengan benar. git mergetidak interleave melakukan (tetapi mungkin muncul demikian dengan melihat git log). Alih-alih, git mergejaga agar sejarah perkembangan oleh Dan dan Ed tetap utuh, seperti yang terlihat dari masing-masing sudut pandang sekaligus. git rebasemembuatnya tampak seperti Dan yang mengerjakannya lebih dulu, dan Ed mengikutinya. Dalam kedua kasus (gabungan dan rebase), pohon file yang dihasilkan benar-benar identik.
mvp
158

Saya sangat suka kutipan ini dari 10 Hal yang saya benci tentang git (ini memberikan penjelasan singkat untuk rebase dalam contoh kedua):

3. Dokumentasi jelek

Halaman manual adalah "Mahakuasa besar" 1 . Mereka menggambarkan perintah dari sudut pandang seorang ilmuwan komputer, bukan pengguna. Inti masalah:

git-push – Update remote refs along with associated objects

Berikut deskripsi untuk manusia:

git-push – Upload changes from your local repository into a remote repository

Perbarui, contoh lain: (terima kasih cgd)

git-rebase – Forward-port local commits to the updated upstream head

Terjemahan:

git-rebase – Sequentially regenerate a series of commits so they can be 
             applied directly to the head node

Dan kemudian kita miliki

git-merge - Join two or more development histories together

yang merupakan deskripsi yang bagus.


1. uncensored dalam aslinya

mvw
sumber
Masalahnya bukan bahasa atau apakah pengguna adalah ilmuwan komputer atau tidak. Sementara menulis ulang dengan cara lain membantu memperjelas tujuan (mis. Apa yang terjadi), namun gagal menjelaskan caranya (bagaimana hal itu terjadi). Git membutuhkan pemahaman cara untuk memahami tujuan. Justru memahami cara yang membuat Git begitu sulit. Sebagai alat, sesuatu yang digunakan untuk menyederhanakan atau mengurangi upaya yang diperlukan dalam tugas, Git gagal total. Sedihnya, terlalu banyak dev yang gagal menyadarinya.
ATL_DEV
128

Secara pribadi saya tidak menemukan teknik diagram standar yang sangat membantu - panah sepertinya selalu menunjukkan cara yang salah bagi saya. (Mereka umumnya menunjuk ke "induk" dari setiap komit, yang akhirnya menjadi mundur dalam waktu, yang aneh).

Untuk menjelaskannya dengan kata-kata:

  • Ketika Anda rebase cabang Anda ke cabang mereka, Anda memberitahu Git untuk membuatnya terlihat seolah-olah Anda memeriksa cabang mereka dengan bersih, lalu lakukan semua pekerjaan Anda mulai dari sana. Itu membuat paket perubahan yang bersih dan sederhana secara konseptual yang dapat ditinjau seseorang. Anda dapat mengulangi proses ini lagi ketika ada perubahan baru di cabang mereka, dan Anda akan selalu berakhir dengan satu set perubahan bersih "di ujung" cabang mereka.
  • Ketika Anda menggabungkan cabang mereka ke cabang Anda, Anda mengikat dua sejarah cabang bersama pada saat ini. Jika Anda melakukan ini lagi nanti dengan lebih banyak perubahan, Anda mulai membuat utas sejarah yang saling terkait: beberapa perubahan mereka, beberapa perubahan saya, beberapa perubahan mereka. Beberapa orang menemukan ini berantakan atau tidak diinginkan.

Untuk alasan yang saya tidak mengerti, alat GUI untuk Git tidak pernah melakukan banyak upaya untuk menyajikan gabungan sejarah lebih bersih, mengabstraksi gabungan individu. Jadi jika Anda ingin "riwayat bersih", Anda harus menggunakan rebase.

Saya ingat pernah membaca posting blog dari programmer yang hanya menggunakan rebase dan yang lain yang tidak pernah menggunakan rebase.

Contoh

Saya akan mencoba menjelaskan ini dengan contoh kata-kata saja. Katakanlah orang lain di proyek Anda bekerja pada antarmuka pengguna, dan Anda sedang menulis dokumentasi. Tanpa rebase, riwayat Anda mungkin terlihat seperti:

Write tutorial
Merge remote-tracking branch 'origin/master' into fixdocs
Bigger buttons
Drop down list
Extend README
Merge remote-tracking branch 'origin/master' into fixdocs
Make window larger
Fix a mistake in howto.md

Yaitu, gabungan dan UI berkomitmen di tengah-tengah komitmen dokumentasi Anda.

Jika Anda mengubah kode menjadi master alih-alih menggabungkannya, itu akan terlihat seperti ini:

Write tutorial
Extend README
Fix a mistake in howto.md
Bigger buttons
Drop down list
Make window larger

Semua komit Anda ada di atas (terbaru), diikuti oleh mastercabang lainnya.

( Penafian: Saya penulis posting "10 hal yang saya benci tentang Git" sebagaimana dimaksud dalam jawaban lain )

Steve Bennett
sumber
42

Walaupun jawaban yang diterima dan paling banyak dipilih sangat bagus, saya juga menemukan bahwa mencoba menjelaskan perbedaan hanya dengan kata-kata:

menggabungkan

  • “Oke, kita punya dua kondisi repositori yang berbeda. Mari kita gabungkan keduanya. Dua orang tua, satu anak yang dihasilkan. "

rebase

  • “Berikan perubahan cabang utama (apa pun namanya) ke cabang fitur saya. Lakukan dengan berpura-pura pekerjaan fitur saya dimulai nanti, bahkan pada keadaan cabang utama saat ini. ”
  • "Tulis ulang sejarah perubahan saya untuk mencerminkan hal itu." (perlu mendorong-paksa mereka, karena biasanya versi adalah tentang tidak merusak riwayat yang diberikan)
  • “Kemungkinan — jika perubahan yang saya lakukan tidak ada hubungannya dengan pekerjaan saya — sejarah sebenarnya tidak akan banyak berubah, jika saya melihat komitmen saya berbeda-beda (Anda mungkin juga memikirkan 'tambalan')."

Ringkasan: Bila memungkinkan, rebase hampir selalu lebih baik. Membuat re-integrasi ke cabang utama lebih mudah.

Karena? ➝ fitur pekerjaan Anda dapat disajikan sebagai satu 'file tambalan' besar (alias beda) sehubungan dengan cabang utama, tidak harus 'menjelaskan' banyak orang tua: Setidaknya dua, berasal dari satu penggabungan, tetapi kemungkinan lebih banyak, jika ada ada beberapa penggabungan. Tidak seperti penggabungan, beberapa rebases tidak bertambah. (plus besar lainnya)

Frank Nocke
sumber
18

Git rebase lebih dekat dengan gabungan. Perbedaan dalam rebase adalah:

  • komit lokal dihapus sementara dari cabang.
  • jalankan tarikan git
  • masukkan lagi semua komitmen lokal Anda.

Jadi itu berarti semua komit lokal Anda dipindahkan ke akhir, setelah semua komit jarak jauh. Jika Anda memiliki konflik gabungan, Anda harus menyelesaikannya juga.

Willem Franco
sumber
7

Agar mudah dimengerti bisa melihat sosok saya.

Rebase akan mengubah komit hash, sehingga jika Anda ingin menghindari banyak konflik, cukup gunakan rebase ketika cabang itu selesai / selengkap stabil.

masukkan deskripsi gambar di sini

Nhan Cao
sumber
0

Saya menemukan satu artikel yang sangat menarik tentang git rebase vs merge , berpikir untuk membagikannya di sini

  • Jika Anda ingin melihat riwayat yang sama seperti yang terjadi, Anda harus menggunakan gabungan. Menggabungkan menyimpan sejarah sedangkan rebase menulis ulangnya.
  • Penggabungan menambahkan komitmen baru ke riwayat Anda
  • Rebasing lebih baik untuk merampingkan riwayat yang kompleks, Anda dapat mengubah riwayat komit dengan rebase interaktif.
nagendra547
sumber