Git rebase parametrelerini anlama ve ezberleme


12

Şimdiye kadar git'in en kafa karıştırıcı kısmı başka bir şubeye dayanıyor. Özellikle, kafa karıştırıcı olan komut satırı argümanlarıdır.

Bir dalın küçük bir parçasını diğerinin ucuna yeniden adlandırmak istediğimde, git rebase belgelerini gözden geçirmem gerekiyor ve 3 ana argümanın her birinin ne olması gerektiğini anlamak 5-10 dakika sürüyor.

git rebase <upstream> <branch> --onto <newbase>

Başka bir dalda herhangi bir tür yeniden taban verildiğinde, bu 3 parametrenin her birinin neye ayarlanması gerektiğini ezberlememe yardımcı olacak iyi bir kural nedir?

Git-rebase belgelerini tekrar tekrar ve tekrar tekrar ve tekrar (ve tekrar) gözden geçirdiğimi aklınızda bulundurun, ancak her zaman anlaşılması zor (sıkıcı bir bilimsel teknik inceleme veya benzeri bir şey gibi). Bu noktada, kavramama yardım etmek için başka insanları dahil etmem gerektiğini hissediyorum.

Amacım, bu temel parametrelerle ilgili belgeleri asla gözden geçirmem gerekmemesidir. Şimdiye kadar onları ezberleyemedim ve zaten bir ton onarım yaptım. Bu yüzden şu ana kadar diğer tüm komutları ve parametrelerini ezberleyebildiğim için alışılmadık bir durum, ancak geri dönemiyorum --onto.


Yaygın kullanım durumlarınız için bazı git diğer adları tanımlayabilir veya komutu çalıştırmadan önce parametrelerin her birinin ne anlama geldiğini hatırlatan bir sihirbaz komut dosyası kullanabilirsiniz.
Rory Hunter

4
Ah, bu akıl almaz, git komut seçeneklerinin saf zarafeti. Kullanması çok sezgisel. Her zaman gerçek bir zevk.
Mart'ta JensG

Yanıtlar:


10

Şimdilik --ontoatlayalım. upstreamve brancholdukça basit ve aslında bir çeşit taklitçidir checkoutve branch- ikinci argüman isteğe bağlıdır:

git branch <newbranch>
git branch <newbranch> <base>
git checkout -b <newbranch>
git checkout -b <newbranch> <base>
git rebase <upstream>
git rebase <upstream> <branch>

(Kenara, bu argümanların isimleri rebase, "yukarı" ve "dal" çok değil IMO tanımlayıcı Genellikle peachoftree gibi onları düşünüyorum. <start>Ve <end>ben bunları nasıl kullanacağınızı olan: git rebase <start> <end>)

İkinci dal atlandığında, sonuç ilk önce o dalı kontrol etmek ve daha sonra o dalı belirtmemiş gibi yapmakla aynıdır. Mevcut dalınızı branchdeğiştirmeyen istisna :

git checkout <base> && git branch <newbranch> && git checkout <previous_branch>
git checkout <base> && git checkout -b <newbranch>
git checkout <end>  && git rebase <start>

rebaseÇağrıldığında ne işe yaradığını anlamaya gelince , ilk olarak onu özel bir birleştirme türü olarak düşünerek başladım. Gerçekten değil, ama rebase'i ilk anlamaya başladığında yardımcı oldu. Tavus kuşunun örneğini ödünç almak için:

A--B--F--G master
    \
     C--D--E feature

Bunun bir git merge mastersonucu:

A--B--F-----G master
    \        \
     C--D--E--H feature

Bir iken git rebase master(dal üzerinde iken feature!) Bu sonuçları:

A--B--F--G master
          \
           C'--D'--E' feature

Her iki durumda da featureartık hem masterve hem de feature. Açık değilseniz feature, ikinci argüman kısayol olarak geçmek için kullanılabilir: git rebase master featureyukarıdakiyle aynı şeyi yapar.


Şimdi, özel için --onto. Bununla hatırlanması gereken önemli nokta, <start>belirtilmemişse varsayılan olarak ayarlanmasıdır. Yukarıda, --ontoözellikle belirtmişsem, bu aynı sonuç verir:

git rebase --onto master master
git rebase --onto master master feature

(Sadece --ontobelirtmeden kullanmıyorum <end>çünkü zihinsel ayrıştırma daha kolay, hatta bu ikisinin zaten aynı olduğunu düşünmüştüm feature.)

Neden --ontofaydalı olduğunu görmek için , farklı bir örnek. Diyelim ki featureaçıktım ve daha sonra düzeltmeye başladım - ancak yanlışlıkla featureyerine dallanmış bir hata fark ettim master:

A--B--F--G master
    \
     C--D--E feature
            \
             H--I bugfix

İstediğim şey, bu bugfixbağlılıkları artık bağımlı olmayacakları şekilde "taşımak" tır feature. Olduğu gibi, bu cevapta yukarıda gösterilen herhangi bir birleştirme veya yeniden pazarlama, üç featuretaahhüdü iki bugfixtaahhütle birlikte alacaktır .

Örneğin git rebase master bugfix, yanlış. Aralık <start>için <end>tüm kaydedilmesini dahil olur featureüstünde çalınır, master:

A--B--F--G master
    \     \
     \     C'--D'--E'--H'--I' bugfix
      \
       C--D--E feature

Ne gerçekten istediğiniz gelen kaydedilmesini aralığıdır featureiçin bugfixüstüne dinlemek üzere master. Bunun --ontoiçin - "başlangıç" dalından farklı bir "tekrar" hedefi belirlemek:

git rebase --onto master feature bugfix

A--B--F--G master
    \     \
     \     H'--I' bugfix
      \
       C--D--E feature

1

Sadece bir tazeleme, yeniden temellendirme esas olarak, iki dal birbirinden bağımsız olarak geliştiyse, taahhüt geçmişinizin doğrusal görünmesini istediğinizde içindir, temel olarak taahhüt tarihini yeniden yazar.

bunu yapmaktan hoşlandığım yol git rebase --onto <target branch> <start branch> <end branch>

<target branch>üzerine bastığınız dal nerede , <start branch>normalde <end branch>ayrıldığınız <end branch>dal ve yeniden bastığınız daldır.

ile başlarsan

A--B--F--G master
    \
     C--D--E feature

ve yap

git rebase --onto master master feature

Alacaksın

A--B--F--G master
          \
           C'--D'--E' feature

bilinmesi gereken bir başka iyi şey de, <target branch>varsayılan <start branch>olarak

git rebase --onto master feature

daha fazla yardıma ihtiyacınız olursa Gözyaşı olmadan Rebase rehberine göz atın


Sonucunuz yanıltıcı görünüyor. rebase masterşubenin kendisini değiştirmeden bırakmalıdır . Sadece gibi dallara 'özelliğini' get G--C'--D'--E'ederken masterhala durur G.
Frank

@Frank, bunu bütün doğrusal tarih olayını vurgulamak için yaptım ama şimdi yolun daha iyi olduğunu düşünüyorum. sabit.
peachoftree

1
Okuyucuların en genel durumu anlamalarına yardımcı olmak için nerede <target branch>ve <start branch>farklı olduklarını gösteren bir örnek gösterebilir misiniz ?
Rufflewind
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.