Kapan saya harus menggunakan git pull --rebase?

806

Saya tahu beberapa orang yang menggunakan git pull --rebasesecara default dan yang lain bersikeras tidak pernah menggunakannya. Saya percaya saya mengerti perbedaan antara merger dan rebasing, tapi saya mencoba untuk menempatkan ini dalam konteks git pull. Apakah hanya tentang tidak ingin melihat banyak pesan gabungan melakukan, atau ada masalah lain?

Jason Baker
sumber
1
Sumber untuk orang yang menyarankan agar git pull --rebase? Rebase atau git rebase adalah aktivitas terpisah dari git pull --rebase!
przemo_li

Jawaban:

584

Anda harus menggunakan git pull --rebasekapan

  • perubahan Anda tidak layak cabang terpisah

Memang - mengapa tidak? Ini lebih jelas, dan tidak memaksakan pengelompokan logis pada komitmen Anda.


Ok, saya kira perlu beberapa klarifikasi. Di Git, seperti yang mungkin Anda ketahui, Anda didorong untuk bercabang dan bergabung. Cabang lokal Anda, tempat Anda menarik perubahan, dan cabang jarak jauh sebenarnya adalah cabang yang berbeda, dan git pullakan menggabungkannya. Ini masuk akal, karena Anda mendorong sangat jarang dan biasanya mengumpulkan sejumlah perubahan sebelum mereka merupakan fitur yang lengkap.

Namun, kadang-kadang - dengan alasan apa pun - Anda berpikir bahwa sebenarnya akan lebih baik jika keduanya - terpencil dan lokal - adalah satu cabang. Seperti di SVN. Di sinilah tempat git pull --rebasebermain. Anda tidak lagi bergabung - Anda benar-benar melakukan di atas cabang jarak jauh . Sebenarnya itu tentang apa.

Apakah itu berbahaya atau tidak, adalah pertanyaan apakah Anda memperlakukan cabang lokal dan terpencil sebagai satu hal yang tidak dapat dipisahkan. Terkadang masuk akal (ketika perubahan Anda kecil, atau jika Anda berada di awal perkembangan yang kuat, ketika perubahan penting dilakukan dengan komitmen kecil). Terkadang bukan (saat Anda biasanya membuat cabang lain, tetapi Anda terlalu malas untuk melakukannya). Tapi itu pertanyaan yang berbeda.

P Shved
sumber
17
Saya pikir ini berguna ketika Anda bekerja di cabang yang sama, tetapi Anda dapat mengubah workstation Anda. Saya cenderung melakukan dan mendorong perubahan saya dari satu workstation lalu menarik rebase yang lain, dan terus bekerja di cabang yang sama.
Pablo Pazos
11
Ini adalah praktik terbaik yang berguna untuk mengatur Git untuk secara otomatis rebase saat menarik dengan git config --global pull.rebase preserve (pertahankan mengatakan selain memungkinkan rebasing, untuk mencoba mempertahankan penggabungan jika Anda telah membuat secara lokal).
Colin D Bennett
2
Saya tidak setuju bahwa Anda harus menggunakan pull --rebase hanya ketika bekerja pada satu cabang. Anda harus menggunakannya setiap saat, kecuali tidak mungkin karena keadaan lain.
Tomáš Fejfar
@ P Shved ... 'Namun, kadang-kadang - dengan alasan apa pun - Anda berpikir bahwa sebenarnya akan lebih baik jika keduanya - terpencil dan lokal - adalah satu cabang' ... bisakah ini dilakukan? Pengertian saya adalah bahwa di lingkungan lokal, saya dapat memiliki cabang dan cermin cabang jarak jauh sebagai asal / master. Bisakah Anda memberikan masukan di sini?
Mandroid
736

Saya ingin memberikan perspektif yang berbeda tentang apa arti sebenarnya "git pull --rebase", karena kadang-kadang sepertinya hilang.

Jika Anda pernah menggunakan Subversion (atau CVS), Anda mungkin terbiasa dengan perilaku "pembaruan svn". Jika Anda memiliki perubahan untuk dikomit dan komit gagal karena perubahan telah dibuat hulu, Anda "memperbarui". Subversi dihasilkan dengan menggabungkan perubahan hulu dengan milik Anda, yang berpotensi menimbulkan konflik.

Apa yang baru saja dilakukan Subversion, pada dasarnya adalah "pull --rebase". Tindakan merumuskan ulang perubahan lokal Anda menjadi relatif terhadap versi yang lebih baru adalah bagian "rebasing". Jika Anda telah melakukan "svn diff" sebelum upaya komit yang gagal, dan membandingkan diff yang dihasilkan dengan output dari "svn diff" sesudahnya, perbedaan antara kedua diff adalah apa yang dilakukan operasi rebasing.

Perbedaan utama antara Git dan Subversion dalam kasus ini adalah bahwa dalam Subversion, perubahan "Anda" hanya ada sebagai perubahan yang tidak dikomit dalam copy pekerjaan Anda, sementara di Git Anda memiliki komitmen aktual secara lokal. Dengan kata lain, di Git Anda telah memotong sejarah; sejarah Anda dan sejarah hulu telah menyimpang, tetapi Anda memiliki leluhur yang sama.

Menurut pendapat saya, dalam kasus normal memiliki cabang lokal Anda hanya mencerminkan cabang hulu dan melakukan pengembangan terus-menerus di atasnya, hal yang benar untuk dilakukan adalah selalu "--rase", karena itulah yang sebenarnya Anda lakukan secara semantik . Anda dan yang lainnya sedang meretas pada sejarah linier yang dimaksudkan dari sebuah cabang. Fakta bahwa orang lain kebetulan mendorong sedikit sebelum upaya yang Anda coba tidak relevan, dan tampaknya tidak produktif untuk setiap kecelakaan waktu seperti itu untuk menghasilkan penggabungan dalam sejarah.

Jika Anda benar-benar merasakan perlunya sesuatu untuk menjadi cabang untuk alasan apa pun, itu adalah keprihatinan yang berbeda menurut saya. Tetapi kecuali jika Anda memiliki keinginan spesifik dan aktif untuk mewakili perubahan Anda dalam bentuk penggabungan, perilaku default seharusnya, menurut pendapat saya, adalah "git pull --rebase".

Harap pertimbangkan orang lain yang perlu mengamati dan memahami sejarah proyek Anda. Apakah Anda ingin sejarah penuh dengan ratusan gabungan di semua tempat, atau Anda ingin hanya beberapa gabungan terpilih yang mewakili gabungan nyata dari upaya pengembangan yang berbeda secara disengaja?

scode
sumber
18
@ MarsceloCantos Untuk lebih jelasnya, saya tidak mengatakan bahwa git (alat) harusnya default untuk rebase. Itu akan berbahaya karena rebase pada dasarnya menghancurkan sejarah. Saya mengatakan bahwa dalam hal alur kerja, ketika Anda tidak berniat untuk bercabang dan hanya meretas beberapa cabang yang orang lain juga kerjakan, "git pull --rebase" harus menjadi perilaku default pengguna.
scode
1
Apakah Anda mengatakan bahwa seharusnya tidak git config --global branch.autosetupmerge always?
Marcelo Cantos
9
@MarceloCantos Tidak, saya tidak;) Secara pribadi saya akan meninggalkan autosetupmerge sebagai default true (jika saya menggabungkan kembali dan keempat antara cabang selain remote <-> lokal, saya ingin itu menjadi eksplisit). Saya hanya mengatakan bahwa sebagai manusia, saya selalu menggunakan "git pull --rebase" sebagai bagian dari alur kerja normal "ambil terbaru di cabang master", karena saya tidak pernah ingin membuat komit gabungan kecuali jika saya secara eksplisit bercabang.
scode
9
+1 @ kode. Setelah berjam-jam yang menyakitkan bergulat dengan pertanyaan rebase / penggabungan, akhirnya inilah jawaban yang tepat.
AgileYogi
10
Jawaban ini hanyalah upaya untuk mengadaptasi pengguna sistem kontrol versi yang tidak terdistribusi ke Git alih-alih memberi mereka kesempatan untuk memahami manfaat dari memiliki cabang yang tepat.
Alexey Zimarev
211

Mungkin cara terbaik untuk menjelaskannya adalah dengan contoh:

  1. Alice menciptakan cabang topik A, dan bekerja di sana
  2. Bob membuat cabang topik B yang tidak terkait, dan bekerja di sana
  3. Alice melakukannya git checkout master && git pull. Master sudah terkini.
  4. Bob melakukannya git checkout master && git pull. Master sudah terkini.
  5. Alice melakukannya git merge topic-branch-A
  6. Bob melakukannya git merge topic-branch-B
  7. Bob melakukannya git push origin mastersebelum Alice
  8. Alice melakukannya git push origin master, yang ditolak karena itu bukan penggabungan maju cepat.
  9. Alice melihat log asal / master, dan melihat bahwa komit tidak terkait dengan miliknya.
  10. Alice melakukannya git pull --rebase origin master
  11. Komitmen gabungan Alice tidak dilepaskan, komit Bob ditarik, dan komit Alice diterapkan setelah komit Bob.
  12. Alice melakukannya git push origin master, dan semua orang senang mereka tidak harus membaca komit gabungan yang tidak berguna ketika mereka melihat log di masa depan.

Perhatikan bahwa cabang spesifik yang digabungkan menjadi tidak relevan dengan contoh. Master dalam contoh ini bisa dengan mudah menjadi cabang rilis atau cabang dev. Poin kuncinya adalah bahwa Alice & Bob secara bersamaan menggabungkan cabang lokal mereka ke cabang terpencil bersama.

Polling Cody
sumber
2
Bagus. Saya cenderung eksplisit dan git co master && git pull; git checkout topic-branch-A; git rebase master; git checkout master; git merge topic-branch-A; git push origin masterdan mengulangi jika dorongan orang lain untuk menguasai terjadi sebelum saya. Meskipun saya bisa melihat keuntungan ringkas dalam resep Anda.
HankCa
Penjelasan bagus @Cody Poll
Rajanikanta Pradhan
148

Saya pikir Anda harus menggunakan git pull --rebaseketika berkolaborasi dengan orang lain di cabang yang sama. Anda berada di pekerjaan Anda → komit → pekerjaan → komit siklus, dan ketika Anda memutuskan untuk mendorong pekerjaan Anda dorongan Anda ditolak, karena ada pekerjaan paralel di cabang yang sama. Pada titik ini saya selalu melakukan pull --rebase. Saya tidak menggunakan squash (untuk meratakan komit), tapi saya rebase untuk menghindari komit gabungan tambahan.

Ketika pengetahuan Git Anda meningkat, Anda mendapati diri Anda lebih melihat sejarah daripada dengan sistem kontrol versi lain yang saya gunakan. Jika Anda memiliki banyak komitmen gabungan, mudah kehilangan fokus dari gambaran besar yang terjadi dalam sejarah Anda.

Ini sebenarnya satu-satunya saat saya melakukan rebasing (*), dan sisa alur kerja saya berbasis penggabungan. Tetapi selama komuter Anda yang paling sering melakukan ini, sejarah pada akhirnya terlihat jauh lebih baik.

(*) Saat mengajar kursus Git, saya meminta seorang siswa untuk menangkap saya dalam hal ini, karena saya juga menganjurkan cabang fitur rebasing dalam keadaan tertentu. Dan dia telah membaca jawaban ini;) Rebasing semacam itu juga mungkin, tetapi selalu harus sesuai dengan sistem yang telah diatur sebelumnya / disepakati, dan dengan demikian tidak boleh "selalu" diterapkan. Dan pada saat itu saya biasanya tidak melakukan pull --rebasekeduanya, yang merupakan pertanyaan:)

krosenvold
sumber
2
tentunya orang dapat menulis skrip untuk menyembunyikan komit gabungan dari log
hasen
3
Penggabungan dapat mengandung diffs juga, yang berarti itu tidak sepenuhnya sepele
krosenvold
9
@ telah j Ya, tetapi ISI dari gabungan tersebut mungkin penting
krosenvold
Jawaban ini tidak jelas dan tidak sesuai dengan jawaban yang dipilih: apa yang Anda maksud dengan "cabang yang sama" sebenarnya? Ada beberapa poin bagus, yang tidak ada dalam jawaban yang dipilih.
iwein
1
Ketidakjelasan di sekitar "cabang" cukup disengaja, karena ada begitu banyak cara untuk menggunakan referensi; "jalur pekerjaan" hanyalah salah satu opsi.
krosenvold
49

Saya tidak berpikir ada alasan untuk tidak menggunakan pull --rebase- saya menambahkan kode ke Git secara khusus untuk memungkinkan git pullperintah saya untuk selalu rebase terhadap komitmen upstream.

Saat menelusuri sejarah, tidak pernah menarik untuk mengetahui kapan orang yang bekerja pada fitur tersebut berhenti untuk menyinkronkan. Ini mungkin berguna untuk pria / wanita saat dia melakukannya, tapi itu untuk apa reflog. Itu hanya menambahkan suara untuk orang lain.

Dustin
sumber
2
"Ketika melihat sejarah, tidak pernah menarik untuk mengetahui kapan pria yang bekerja pada fitur itu berhenti untuk melakukan sinkronisasi." / tapi bukankah itu berarti komit menengah itu kemungkinan rusak dibangun?
eglasius
10
Ya, dan mereka juga bukan "seluruh negara". Itu sebabnya kami tidak menginginkannya. Saya ingin tahu apa yang dia inginkan, bukan bagaimana dia sampai di sana.
Dustin
4
Jika pull --rebaseharus selalu digunakan, mengapa tidak pullmelakukannya secara default?
straya
2
Saya khawatir Anda harus membentuk pendapat Anda sendiri. Saya punya beberapa hal dalam diri saya .gitconfiguntuk membuat beberapa opsi melakukan hal yang benar. Saya pikir git rebase melakukan hal yang salah secara default, seperti halnya git tag, dll ... Jika Anda tidak setuju, Anda tidak perlu membenarkan pendapat Anda.
Dustin
8
Tampaknya nasihat yang bagus jika Anda menarik dari "hulu", katakan dari master, dan jika cabang yang Anda tarik belum go public (belum). Jika Anda menarik di sisi lain dari cabang fitur ke masterdalamnya lebih seperti sebaliknya: tidak pernah ada alasan untuk menggunakannya --rebase, kan? Itu mungkin menjadi alasan mengapa itu tidak standar. Saya menemukan Rebases adalah bagaimana perubahan harus lulus dari puncak hierarki ke bawah dan penggabungan adalah bagaimana mereka mengalir kembali ke atas. derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebase
jolvi
38

Ingatlah:

  • pull = fetch + merge
  • tarik --rebase = ambil + rebase

Jadi, pilih cara yang Anda inginkan untuk menangani cabang Anda.

Anda sebaiknya tahu perbedaan antara penggabungan dan rebase :)

leohxj
sumber
9

Saya pikir itu bermuara pada preferensi pribadi.

Apakah Anda ingin menyembunyikan kesalahan konyol Anda sebelum mendorong perubahan Anda? Jika demikian, git pull --rebaseitu sempurna. Hal ini memungkinkan Anda untuk kemudian menekan komitmen Anda ke beberapa (atau satu) komitmen. Jika Anda memiliki penggabungan dalam riwayat Anda (tidak dicuri), itu tidak mudah untuk dilakukan git rebasenanti.

Saya pribadi tidak keberatan mempublikasikan semua kesalahan konyol saya, jadi saya cenderung bergabung bukan rebase.

Hasen
sumber
8
Catatan untuk siapa pun yang melihat pertanyaan ini: jawaban ini sama sekali tidak relevan dengan pertanyaan "kapan saya harus menggunakan git pull --rebase?"
therealklanni
3
@therealklanni Saya mengedit jawaban sehingga semakin jelas bagaimana relevan dengan pertanyaan (mudah-mudahan tanpa merusak maksud).
Paŭlo Ebermann
Berbagi work-log yang kotor dan tidak terstruktur bukanlah upaya yang jujur, itu hanya kemalasan. Anda membuang-buang waktu orang dengan membuat mereka mengejar Anda melalui lubang kelinci Anda untuk pengembangan dan debugging; beri mereka hasilnya, bukan ocehan.
krystah
8

git pull --rebasedapat menyembunyikan riwayat penulisan ulang dari kolaborator git push --force. Saya sarankan untuk menggunakan git pull --rebase hanya jika Anda tahu Anda lupa mendorong komit Anda sebelum orang lain melakukan hal yang sama.

Jika Anda tidak melakukan apa pun, tetapi ruang kerja Anda tidak bersih, tepat git stashsebelum git pull. Dengan cara ini Anda tidak akan menulis ulang riwayat Anda secara diam-diam (yang dapat secara diam-diam meninggalkan beberapa pekerjaan Anda).

Habax
sumber