'Git merge' ve 'git rebase' arasındaki fark nedir?


499

Arasındaki fark nedir git mergeve git rebase?


14
cevabım silindiğinden, bu soru için doğru cevabı almak için bu bağlantıyı ziyaret edin: git-scm.com/book/en/Git-Branching-Rebasing#The-Basic-Rebase
HiB

6
Bu arada bu siteyi ekleyeceğim. Git hakkında bilmeniz gereken her şey oynayarak öğrenmek: pcottle.github.io/learnGitBranching
Rollyng

Önce bunu okuyun: git-scm.com/book/en/v2/… Sonra: git-scm.com/book/en/v2/Git-Branching-Rebasing Gerçekten anlayacaksınız.
Liber

Yanıtlar:


867

Varsayalım başlangıçta 3 kaydedilmesini vardı A, B, C:

ABC

Sonra geliştirici Dan taahhüt oluşturdu Dve geliştirici Ed taahhüt oluşturdu E:

ABCDE

Açıkçası, bu çatışma bir şekilde çözülmelidir. Bunun için 2 yol vardır:

BİRLEŞTİR :

ABCDEM

Hem taahhütte Dhem Ede hala buradayız, ama Mher ikisinden Dve değişiklikleri değiştiren birleştirme taahhüdü yaratıyoruz E. Bununla birlikte, bu , birçok insanın çok kafa karıştırıcı bulduğu elmas şekli oluşturur .

REBASE :

ABCDER

Biz taahhüt oluşturmak Rgerçek dosya içeriğini birleştirme taahhüt özdeş olan Myukarıda. Ancak, Ehiç var olmamış gibi (noktalarla gösterilir - yok olan çizgi) taahhütten kurtuluruz . Bu yok etme nedeniyle, Egeliştirici Ed için yerel olmalı ve hiçbir zaman başka bir depoya itilmemelidir. Rebase'in avantajı, elmas şeklinden kaçınılması ve tarihin güzel düz çizgide kalmasıdır - çoğu geliştirici bunu sever!


53
Güzel çizimler. Ancak, rebase'in ele alındığı olumlu tona tam olarak katılmıyorum. Manuel birleştirme gerektiren hem birleştirme hem de yeniden yapılandırma çakışmaları oluşabilir. Ve her zaman olduğu gibi, programcılar dahil olduğunda hatalar gibi ihmal edilemez bir hata şansı vardır. Birleştirme hatası oluşursa, tüm ekip veya topluluk birleştirme işlemini görebilir ve orada bir hata olup olmadığını doğrulayabilir. Rebase'in tarihi 1 geliştiricinin deposunda kalıyor ve orada bile reflogda sadece sınırlı bir ömrü var. Daha güzel görünebilir, ancak kimse neyin yanlış gittiğini kolayca göremez.
Uwe Geuder

> "Ancak bu, birçok insanın kafa karıştırıcı bulduğu elmas şekli oluşturur." Um ... biraz detaylandırabilir misin?
Greg Maletic

@GregMaletic: Elmas şekli doğrusal olmayan bir tarihtir. Seni tanımıyorum ama genel olarak doğrusal olmayan şeyleri sevmiyorum. Bununla birlikte, gerçekten tercih ederseniz elmaslarla birleştirme kullanabilirsiniz. Kimse sizi zorlamıyor.
mvp

1
Bu yanıt son derece yararlı olsa da, yerel olarak çoğaltmak için basit foo.txt dosyalarıyla gerçek git komutlarını eklerseniz daha iyi olurdu. Son kullanıcının dediği gibi, kimin rebase yaptığı belli değil.
Vortex

1
@pferrel: Doğru anladığınızı sanmıyorum. git mergetaahhütler arasına eklemez (ancak bakarak görünebilir git log). Bunun yerine, git mergeher iki bakış açısından da görüldüğü gibi, Dan ve Ed'in her iki geliştirme geçmişini olduğu gibi koruyor. git rebaseDan'ın önce üzerinde çalıştığı gibi görünmesini sağladı ve Ed onu takip etti. Her iki durumda da (birleştirme ve yeniden oluşturma), gerçek sonuç dosya ağacı kesinlikle aynıdır.
mvp

158

Git hakkında nefret ettiğim 10 şeyden bu alıntıyı gerçekten seviyorum (ikinci örneğinde rebase için kısa bir açıklama yapıyor):

3. Crappy belgeleri

Man sayfaları bir yüce "seni lanet" 1 . Komutları, bir kullanıcı değil, bir bilgisayar bilimcisinin bakış açısından tarif ederler. Konuşma konusu olan mesele:

git-push – Update remote refs along with associated objects

İşte insanlar için bir açıklama:

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

Güncelleme, başka bir örnek: (teşekkürler cgd)

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

Tercüme:

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

Ve sonra

git-merge - Join two or more development histories together

ki bu iyi bir tanım.


1. orijinal sansürsüz


Sorun dil değil veya kullanıcının bir bilgisayar bilimcisi olup olmadığı değildir. Başka bir şekilde yeniden sarmak, uçları açıklığa kavuşturmaya yardımcı olurken (yani, ne olur), araçları açıklamakta (nasıl olur). Git, amaçları anlamak için araçların anlaşılmasını gerektirir. Git'i bu kadar zorlaştıran araçları tam olarak anlamak. Bir araç olarak görevde gereken çabayı basitleştirmek veya azaltmak için kullanılan bir şey olan Git korkunç bir şekilde başarısız oluyor. Ne yazık ki, çok fazla geliştirici bunu gerçekleştiremiyor.
ATL_DEV

128

Şahsen standart diyagramlama tekniğini çok yararlı bulmuyorum - oklar her zaman benim için yanlış yolu gösteriyor gibi görünüyor. (Genellikle her bir taahhüdün "ebeveyni" ne işaret ederler, bu da zaman içinde geriye doğru gider, bu da gariptir).

Bunu kelimelerle açıklamak için:

  • Ne zaman rebase onların şube üzerine şube, daha sonra oradan başlayarak tüm çalışma yaptı, sen temiz bir şekilde kendi şube teslim sanki görünmesi için Git söyle. Bu, birisinin gözden geçirebileceği temiz, kavramsal olarak basit bir değişiklik paketi yapar. Şubelerinde yeni değişiklikler olduğunda bu işlemi tekrarlayabilirsiniz ve her zaman şubelerinin "ucunda" temiz bir değişiklik kümesiyle karşılaşırsınız.
  • Ne zaman birleştirme şubenize içine kendi dalı, bu noktada bir araya iki şube geçmişlerini kravat. Bunu daha sonra daha fazla değişiklikle yaparsanız, aralıklı geçmişlerden oluşan bir iş parçacığı oluşturmaya başlarsınız: değişikliklerinden bazıları, bazı değişikliklerim, bazı değişiklikler. Bazı insanlar bunu dağınık veya istenmeyen buluyor.

Anlamadığım nedenlerden dolayı, Git için GUI araçları hiçbir zaman birleştirme geçmişlerini daha temiz bir şekilde sunma ve bireysel birleştirmeleri soyutlama çabası göstermedi. Yani "temiz bir tarih" istiyorsanız, rebase kullanmanız gerekir.

Sadece rebase kullanan programcıların ve asla rebase kullanmayan diğer programların blog yazılarını okuduğumu hatırlıyorum .

Misal

Bunu açık sözlü bir örnekle açıklamaya çalışacağım. Diyelim ki projenizdeki diğer kullanıcılar kullanıcı arayüzü üzerinde çalışıyor ve siz de doküman yazıyorsunuz. Rebase olmadan, geçmişiniz şöyle görünebilir:

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

Yani, birleştirme ve kullanıcı arayüzü belgelerinizin ortasında taahhüt eder.

Kodunuzu birleştirmek yerine master'a yeniden basarsanız, şöyle görünür:

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

Tüm taahhütleriniz en üstte (en yeni), ardından da masterşubenin geri kalanında .

( Feragatname: Başka bir cevapta atıfta bulunulan "Git hakkında nefret ettiğim 10 şey" yazısının yazarıyım )


42

Kabul edilen ve en çok oylanan cevap harika olsa da, farkı sadece kelimelerle açıklamaya çalışırken de yararlı buluyorum:

birleştirmek

  • “Tamam, depomuzun iki farklı gelişmiş durumu var. Onları bir araya getirelim. İki ebeveyn, bir çocuk doğurdu. ”

rebase

  • “Ana dalın (adı ne olursa olsun) değişikliklerini özellik şubeme ver. Bunu, daha sonra, ana şubenin şu anki durumu üzerinde başladığım özellik işlerim gibi yaparak yapın. ”
  • “Değişikliklerimin geçmişini bunu yansıtacak şekilde yeniden yaz.” (normalde sürüm olduğu için ihtiyacı tüm yaklaşık onları zorla-itmek değil verilen tarihin tahrif)
  • “Muhtemelen —Kattığım değişikliklerin işimle pek ilgisi yoksa - tarihim aslında çok fazla değişmeyecek, eğer taahhütlerime göre fark farklıysa ('yamalar' da düşünebilirsiniz).”

özet: Mümkün olduğunda, rebase neredeyse her zaman daha iyidir. Ana şubeye yeniden entegrasyonu kolaylaştırmak.

Çünkü? ➝ Özelliğinizin iş olarak sunulabilir biri birden veliler 'açıklamak' zorunda kalmayacakları, ana dal açısından büyük 'yama dosyası' (aka fark): Bir birleştirme gelen en az ikisini, ancak büyük olasılıkla çok daha fazla, eğer orada çeşitli birleşmelerdi. Birleştirmeden farklı olarak, birden fazla yeniden basma toplanmaz. (başka bir büyük artı)


18

Git rebase birleşmeye daha yakın. Rebase'deki fark:

  • yerel taahhütler şubeden geçici olarak çıkarılır.
  • git çekmeyi çalıştır
  • tüm yerel taahhütlerinizi tekrar ekleyin.

Bu, tüm uzaktan işlemlerin ardından tüm yerel işlemlerinizin sonuna taşındığı anlamına gelir. Birleştirme çatışmanız varsa, bunu da çözmeniz gerekir.


7

Kolay anlamak için benim rakamı görebilirsiniz.

Rebase taahhüt karma değerini değiştirecek, böylece çok fazla çakışmadan kaçınmak istiyorsanız, o şube istikrarlı olarak tamamlandığında / tamamlandığında rebase kullanın.

resim açıklamasını buraya girin


0

Git rebase vs merge hakkında gerçekten ilginç bir makale buldum , burada paylaşmayı düşündüm

  • Tarihi tamamen olduğu gibi görmek istiyorsanız, birleştirme kullanmalısınız. Birleştirme tarihi korur, rebase ise yeniden yazar.
  • Birleştirme, geçmişinize yeni bir bağlılık katar
  • Yeniden pazarlama karmaşık bir geçmişi kolaylaştırmak için daha iyidir, taahhüt geçmişini etkileşimli yeniden düzenleyerek değiştirebilirsiniz.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.