Git'te commit'leri ezmek ne anlama geliyor?


117

Git'te Squashing ne anlama geliyor? Github'da taahhütleri nasıl ezebilirim?

Git'te yeniyim ve coala-analyzer'da yeni gelen bir hataya atanmayı talep ettim. Hatayı düzelttim ve şimdi taahhütlerimi ezmem istendi. Nasıl yaparım?


Hey @Lakshman en yüksek oyu alan cevabı kabul etmekten çekinmeyin. Sorunuzu doğru bir şekilde yanıtlıyor.
Mostafiz Rahman

Yanıtlar:


180

Git'i, çalışma dizininizin (dizinlerinizin) anlık görüntülerinin gelişmiş bir veritabanı olarak düşünebilirsiniz.

Git'in çok güzel bir özelliği, işlemlerin tarihini yeniden yazma yeteneğidir.
Bunu yapmanın temel nedeni, bu tür geçmişin çoğunun yalnızca onu oluşturan geliştirici için geçerli olmasıdır, bu nedenle paylaşılan bir depoya gönderilmeden önce basitleştirilmesi veya daha güzel hale getirilmesi gerekir.

Bir commit'i ezmek , deyimsel bir bakış açısından, söz konusu commit'de getirilen değişiklikleri, iki (veya daha fazla) yerine tek bir commit ile sonuçlanacak şekilde üstüne taşımak anlamına gelir.
Bu işlemi birden çok kez tekrarlarsanız, n commit'yi tek bir işleme indirgeyebilirsiniz .

Görsel olarak, işinize Start etiketli commit'de başladıysanız , bunu istersiniz

Git ezmeyi gerçekleştirir

Yeni işlemenin biraz daha koyu bir mavi tonuna sahip olduğunu fark edebilirsiniz. Bu kasıtlı.

Git ezilmesini bir ile elde edilir Rebase adı verilen özel bir formu, etkileşimli Rebase .
Bir dizi taahhüdü bir B şubesine yeniden bağladığınızda basitleştirerek , orijinal ataları yerine B'den başlayarak, bu taahhütler tarafından getirilen tüm değişiklikleri yapıldıkları gibi uygularsınız .

Görsel bir ipucu

görüntü açıklamasını buraya girin

Yine mavinin farklı tonlarına dikkat edin.

Etkileşimli bir geri ödeme, taahhütlerin nasıl yeniden ödeneceğini seçmenize izin verir. Bu komutu çalıştırırsanız:

 git rebase -i branch

Yeniden ihraç edilecek taahhütleri listeleyen bir dosya elde edersiniz

 pick ae3...
 pick ef6...
 pick 1e0...
 pick 341...

Ben kaydedilmesini adını vermedi, ancak bu dört olanları gelen kaydedilmesini olması amaçlanmıştır Başlat için Başkanı

Bu listenin güzel yanı , düzenlenebilir olmasıdır .
Kaydetmeleri atlayabilir veya ezebilirsiniz .
Tek yapmanız gereken ilk kelimeyi ezmek için değiştirmek .

 pick ae3...
 squash ef6...
 squash 1e0...
 squash 341...

Düzenleyiciyi kapatırsanız ve birleştirme çakışması bulunmazsa, şu geçmişle sonuçlanırsınız:

görüntü açıklamasını buraya girin

Sizin durumunuzda, başka bir şubeye değil, daha ziyade önceki bir taahhüde yeniden bağlamak istemezsiniz.
Geçmişi ilk örnekte gösterildiği gibi dönüştürmek için, aşağıdaki gibi bir şey çalıştırmalısınız.

git rebase -i HEAD~4

Birincisi dışındaki tüm işlemlerin ezilmesi için "komutları" değiştirin ve ardından düzenleyicinizi kapatın.


Geçmişi değiştirmeyle ilgili not

Git'te, işlemeler asla düzenlenmez. Budanabilir, erişilemez hale getirilebilir, klonlanabilir ancak değiştirilemez.
Yeniden baz aldığınızda, aslında yeni taahhütler oluşturuyorsunuz.
Eskilere artık herhangi bir referans tarafından ulaşılamaz, bu nedenle tarihte gösterilmemiştir, ancak hala oradalar!

Aslında bir geri ödeme için aldığınız şey bu:

görüntü açıklamasını buraya girin

Onları zaten bir yere ittiyseniz, tarihi yeniden yazmak aslında bir dal oluşturacaktır!


Güzel - orijinal commit yorumlarına ne oluyor - tek bir büyük commit yorumunda birleştiriliyorlar mı yoksa kayboluyorlar mı?
Paul R

Kimden man git rebase: Katlanmış kaydetme için önerilen kaydetme mesajı, ilk işlemenin ve "squash" komutuna sahip olanların tamamlanma mesajlarının birleştirilmesidir
Margaret Bloom

1
Bu, yeniden adlandırma hakkında gördüğüm en iyi açıklama, teşekkür ederim.
Kerry Jones

İlk resminizdeki ezme hakkında: HEAD'in ezmeden önce (açık mavi) ve sonra (koyu mavi) farklı bir çalışma dizinine sahip olduğu bir örnek oluşturabilir misiniz? Squashing'i denediğim tüm örneklerde, START ve HEAD arasındaki üç işlemi silmiş gibi görünüyordu.
real_panda

@actual_panda Takip ettiğimden emin değilim. HEAD, bir commit için bir ref. Mağaza deltalarını kaydeder. Çalışma dizini bir bütün olarak deponun bir özelliğidir, hangi commit'i teslim aldığınıza bağlıdır. Genel olarak, iki referans (HEAD ve START gibi) kontrol edildiğinde her zaman iki farklı çalışma dizini verir. Aynı dalda squash'ı yeniden başlatırsanız, etki ara taahhütleri "gevşetmek" olur, ancak gerçekte git, tüm deltalarla yeni bir tane yaptı. git diffne olduğunu göstermenize yardımcı olabilir.
Margaret Bloom

22

Rebase komutu, --interactive(veya -i) modunda bazı harika seçeneklere sahiptir ve en yaygın kullanılanlardan biri, commit'leri ezme yeteneğidir. Bunun yaptığı şey, daha küçük taahhütler almak ve bunları daha büyük olanlarla birleştirmektir; bu, günün işini tamamlıyorsanız veya değişikliklerinizi farklı şekilde paketlemek istiyorsanız yararlı olabilir. Bunu nasıl kolayca yapabileceğinizi gözden geçireceğiz.

Bir uyarı: Bunu yalnızca harici bir havuza aktarılmamış kayıtlarda yapın. Başkaları, sileceğiniz taahhütleri temel alırsa, birçok çatışma ortaya çıkabilir. Başkalarıyla paylaşılmışsa geçmişinizi yeniden yazmayın.

Diyelim ki birkaç küçük işlem yaptınız ve bunlardan daha büyük bir taahhütte bulunmak istiyorsunuz. Depomuzun geçmişi şu anda şuna benziyor:

görüntü açıklamasını buraya girin

Son 4 kaydetme, bir araya getirilselerdi çok daha mutlu olurdu, öyleyse bunu etkileşimli yeniden bağlama yoluyla yapalım:

$ git rebase -i HEAD~4

pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.

# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

Yani, burada birkaç şey oldu. Her şeyden önce Git'e HEAD'in HEAD ~ 4 ile olduğu son dört kaydı kullanarak yeniden taban oluşturmak istediğimi söyledim. Git şimdi beni içinde yukarıdaki metin ve yapılabilecekler hakkında küçük bir açıklama bulunan bir editöre koydu. Bu ekrandan kullanabileceğiniz birçok seçeneğiniz var, ancak şu anda her şeyi tek bir işlemde sıkıştıracağız. Öyleyse, dosyanın ilk dört satırını bununla değiştirmek hile yapacak:

pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.

Temel olarak bu, Git'e dört commit'i listedeki ilk commit ile birleştirmesini söyler. Bu yapıldıktan ve kaydedildikten sonra, aşağıdakileri içeren başka bir düzenleyici açılır:

# This is a combination of 4 commits.
# The first commit's message is:
Adding license

# This is the 2nd commit message:

Moving license into its own file

# This is the 3rd commit message:

Jekyll has become self-aware.

# This is the 4th commit message:

Changed the tagline in the binary, too.

    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    # Explicit paths specified without -i nor -o; assuming --only paths...
    # Not currently on any branch.
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #   new file:   LICENSE
    #   modified:   README.textile
    #   modified:   Rakefile
    #   modified:   bin/jekyll
    #

Çok fazla kaydetmeyi birleştirdiğimiz için Git, yeni işlemenin mesajını sürecin geri kalanına göre değiştirmenize izin verir. Mesajı uygun gördüğünüz gibi düzenleyin, ardından kaydedin ve çıkın. Bu tamamlandıktan sonra, kaydetmeleriniz başarıyla ezildi!

Created commit 0fc4eea: Creating license file, and making jekyll self-aware.
 4 files changed, 27 insertions(+), 30 deletions(-)
  create mode 100644 LICENSE
    Successfully rebased and updated refs/heads/master.

Ve tarihe tekrar bakarsak ... görüntü açıklamasını buraya girin

Yani, bu şimdiye kadar nispeten acısız oldu. Yeniden temelleme sırasında çatışmalarla karşılaşırsanız, genellikle çözülmesi oldukça kolaydır ve Git, mümkün olduğunca size yol gösterir. Bunun temelleri, söz konusu çatışmayı git add, dosyayı düzeltmek ve ardından git rebase --continuesüreci sürdürmektir. Elbette, git rebase --aborteğer isterseniz, bir yapmak sizi önceki haline geri getirecektir. Eğer herhangi bir nedenle yeniden ödemede bir taahhüdü kaybettiyseniz, geri almak için reflog'u kullanabilirsiniz.

Detaylar bu linkte bulunabilir .


3
Teşekkür ederim! Herhangi birinin VIM'den benim kadar rahatsız olması durumunda ... Düzenlemek için eylemlere girdiğiniz noktaya geldiğinizde, düzenleme moduna girmek için 'i'ye basın. Değişiklikleri tamamladığınızda, escape'e basın ve ": wq" yazın ve sizi ileriye taşıyacaktır. (Mac)
Farasi78

Bunun ne zaman yapılacağına dair uyarı ve bağlam için +1. Kişisel deneyimime göre, bir özellik dalında tek başınıza çalışıyorsanız ve "güncellenmiş benioku", "kimsenin umursamadığı bir şey yaptı" gibi tonlarca önemsiz işleminiz varsa ve şubeyi birleştirmeye hazırsanız iyi olur. tüm bunları tek bir işlemde sıkıştırın. Hiç kimse "kimsenin umursamadığı bir şey yaptığına" geri dönmek istemeyecek ve bu taahhüt tarihini kirletiyor
Adam Hughes

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.