Git pull ve git pull --rebase arasındaki fark


311

Git'i bir ara geri kullanmaya başladım ve karışıklıkları tam olarak anlamıyorum. Buradaki temel sorum, a git pullve arasındaki farkı bulmaktır git pull --rebase, çünkü --rebaseseçeneği eklemek çok farklı bir şey yapmıyor gibi görünüyor: sadece bir çekiyor.

Lütfen farkı anlamada bana yardım et.




Yanıtlar:


326

git pull= git fetch+ git mergeyukarı yönlü şubeyi izlemeye karşı

git pull --rebase= git fetch+ git rebaseyukarı yönlü şubeyi izlemeye karşı

Nasıl git mergeve git rebasefarklı olduğunu bilmek istiyorsanız, bunu okuyun .


12
Söylemenin git pull --rebaseaynı olduğunu git fetchve git rebasetemelde nasıl olduğunu belirtmek gerekir, ancak tam olarak anlamsal olarak eşdeğer değildir . Bazı farklılıklar var, bazıları burada açıklanıyor. gitolite.com/git-pull--rebase
w0rp

8
Scott Meyers'den bir cümle ödünç almak için buna "uygun yalan" diyorum. Ne olursa olsun açıklamak için iyi bir yoldur.
w0rp

Çok kısaca. Farkı anlayamıyorum. Ne hakkında bu kadar önemli fetch?
Yeşil

240

Bazen bağlı olduğumuz bir dalı yeniden bastıran / geri saran bir akış yukarı var. Bu büyük bir sorun olabilir - aşağı yönde olursak bizim için dağınık çatışmalara neden olur.

Sihir git pull --rebase

Normal bir git çekme, gevşek bir şekilde, böyle bir şeydir (tüm bu örneklerde origin adlı bir uzaktan kumanda ve foo adlı bir dal kullanacağız):

# assume current checked out branch is "foo"
git fetch origin
git merge origin/foo

İlk bakışta, bir git pull --rebase'in bunu yaptığını düşünebilirsiniz:

git fetch origin
git rebase origin/foo

Ancak, yukarı akış rebazı herhangi bir "ezme" içeriyorsa bu işe yaramayacaktır (yani, taahhütlerin yama kimliklerinin sadece sıraları değil, değiştiği anlamına gelir).

Yani git pull --rebase bundan biraz daha fazlasını yapmak zorunda. İşte ne yaptığına ve nasıl yapıldığına dair bir açıklama.

Diyelim ki başlangıç ​​noktanız bu:

a---b---c---d---e  (origin/foo) (also your local "foo")

Zaman geçiyor ve kendi "foo" nuzun üstüne bazı taahhütler verdiniz:

a---b---c---d---e---p---q---r (foo)

Bu arada, anti-sosyal öfke bir uyum içinde, memba bakıcısı sadece onun "foo" unu yeniden basmakla kalmadı, hatta bir veya iki squash kullandı. Taahhüt zinciri şimdi şöyle görünüyor:

a---b+c---d+e---f  (origin/foo)

Bu noktada bir git hareketi kaosa neden olur. Git getirisi bile; git rebase origin / foo bunu kesmez, çünkü bir tarafta "b" ve "c" ve diğerinde "b + c" taahhüt eder. (Ve benzer şekilde d, e ve d + e).

git pull --rebaseBu durumda, ne yapar:

git fetch origin
git rebase --onto origin/foo e foo

Bu size şunları sağlar:

 a---b+c---d+e---f---p'---q'---r' (foo)

Yine de çakışmalar yaşayabilirsiniz, ancak bunlar gerçek çatışmalar olacaktır (p / q / r ve a / b + c / d + e / f arasında) ve b / c'nin b + c, vb. İle çakışmasından kaynaklanan çatışmalar olmayacaktır.

Tarafından alınan cevap (ve biraz değiştirilmiş):
http://gitolite.com/git-pull--rebase


9
Bu en iyi cevap. a---b+c---d+e---f---p'---q'---r' (foo)Rebase hash değerlerini değiştirdiği için nihai sonucu değiştirmek isteyebilirsiniz .
Bastien

22
Bu yanıt gitolite.com/git-pull--rebase adresinden aynen kopyalandı ve yapıştırıldı ve bu sayfadaki lisans başına atıf içermelidir.
Wildcard

Bu harika bir açıklama. Ama taahhütte bulunduğum bir durumum vardı Ave kabul edilen memba repolarına bir PR gönderdim. Sonra git pull --rebasememba repo karşı yaptığım zaman A', çekti memba repo üstünde yeni bir taahhüt alamadım . Aslında hiç yoktu A'. Bu Asisteme birleştirildiği için mi? Yoksa, yukarı akış ile yeniden temel alınan sürümüm arasında hiçbir fark olmadığı için mi?
CMCDragonkai

Şu anda Git öğreticisinden geçiyorum ve daha fazla anlamak için bu yanıtı kullanıyordum git pull --rebase. Ancak bu varsayımsal durumda beni şaşırtan bir şey, yukarı akım sürdürücüsünün yerel geliştiricinin depolarına çekilmiş olan proje geçmişini değiştirmesidir. Bu genel olarak kötü bir uygulama değil mi? Taahhütleri yeniden yazmak / tarihi yeniden yazmak istiyorsa, bu tür çatışmalardan kaçınmak için merkezi depoya entegre edilmeden önce yapılmalıdır.
bmcentee148

44

Yerel şubede iki taahhüdünüz olduğunu varsayalım:

      D---E master
     /
A---B---C---F origin/master

"Git pull" den sonra:

      D--------E  
     /          \
A---B---C---F----G   master, origin/master

"Git pull --rebase" den sonra, birleştirme noktası G olmayacaktır. D ve E'nin farklı taahhütler haline geldiğine dikkat edin:

A---B---C---F---D'---E'   master, origin/master

1
A --- B --- C --- D '--- E' - F değil mi?
prgmrDev

5
@prgmrDev D ve E neden F'den önce eklenir?
Jon

1
Tam olarak ne git rebaseyapıyor? Ama bahsediyoruz git pull --rebase. Ve bunlar farklı şeyler.
Yeşil

10

En basit çarpışma olmaması durumunda

  • rebase ile: Uzak BAŞ ontop yerel kaydedilmesini rebases ve yok değil bir birleştirme / birleştirme taahhüt oluşturmak
  • olmadan / normal: birleştirir ve bir birleştirme taahhüdü oluşturur

Ayrıca bakınız:

man git-pull

Daha kesin olarak, git pull verilen parametreler ile git fetch komutunu çalıştırır ve alınan dal kafalarını geçerli dalda birleştirmek için git merge komutunu çağırır. --Rebase ile git merge yerine git rebase komutunu çalıştırır.

Ayrıca bakınız:
git pull --rebase'i ne zaman kullanmalıyım?
http://git-scm.com/book/en/Git-Branching-Rebasing


3
Ve çarpışma durumunda?
Rndm

1
El ile ve sonra bunları çözmek için sorulan alacak - rebase devam: git sdd modified-file; git rebase --continueya birleştirme: git add modified-file; git commit;nereye modified-fileyerel dosya manuel / mergetool modifiye
drahnr

Bu kadar özel olan ne fetch? Neden iki rebaseakış yarattılar ? 1) git rebaseve 2) git pull --rebase?
Yeşil

7

Bunun için Birleştirme ve Rebase arasındaki farkı anlamak önemlidir.

Temyizler, değişikliklerin hiyerarşinin üstünden aşağıya nasıl geçmesi gerektiğidir ve birleştirmeler de nasıl geri akarlar.

Ayrıntılar için - http://www.derekgourlay.com/archives/428


Cevabınızın, yukarıdaki cevapların geri kalanında açık olmayan çok daha basit bir açıklama sunduğunu düşünüyorum. Teşekkürler.
Aaron C
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.