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.