Git merge --squash nasıl kullanılır?


1209

Uzak bir Git sunucum var, burada gerçekleştirmek istediğim senaryo:

  • Her hata / özellik için farklı bir Git dalı oluşturuyorum

  • Bu Git şubesindeki resmi olmayan Git mesajlarıyla kodumu yapmaya devam ediyorum

  • En üst depoda, resmi Git mesajı ile bir hata için bir taahhütte bulunmak zorundayız

Peki tüm şubelerim için tek bir taahhüt alabilmeleri için şubemi uzak şubeyle nasıl birleştirebilirim (bunun için taahhüt mesajı bile vermek istiyorum)?


1
Seni tamamen anladığımdan emin değilim, ama bir "ahtapot birleşmesi" isteyebilirsiniz.
MatrixFrog

27
Genelde git rebase -i komutlarını tek bir işlemde daraltmak ve işlem mesajını yeniden yazmak için kullanıyorum. Sonra membaya gönderiyorum.
Edward Falk

17
git merge --squashhepsini tek seferde komut satırında yapar ve umarım çalışır. git rebase -ibir editör getirir ve rebase ince ayar yapmanıza izin verir. Daha yavaş, ama ne yaptığınızı görebilirsiniz. Ayrıca, bir yorumda ele almak için biraz fazla dahil olan rebase ve merge arasında fark vardır.
Edward Falk

4
tüm bu cevaplar ile sorun yerel olarak ana dalda olması ve merge --squash komutunu çalıştırmak zorunda olduğunu ... Birleştirme --squash ana dal değil özellik dalından çalıştırmak istiyorum .. böylece işim bittiğinde, özellik dalını uzaktan kumandaya itebilir ve bir PR gönderebilirim, bu mümkün mü?
Alexander Mills

2
@AlexanderMills, sadece ikinci bir özellik dalına ihtiyacınız olduğunu düşünüyorum (ana daldan klonlanmış). Eskisinden merge --squashyenisine doğru olanı yapın ve sonra yeni dalı master'a birleştirin. Eski dal artık kullanılmıyor.
Gyromite

Yanıtlar:


1999

Hata düzeltme bölümünüzün çağrıldığını bugfixve birleştirmek istediğinizi varsayalım master:

git checkout master
git merge --squash bugfix
git commit

Bu, tüm taahhütleri bugfixşubeden alacak , 1 taahhütte ezecek ve şubenizle birleştirecektir master.


Açıklama :

git checkout master

Şubenize geçer master.

git merge --squash bugfix

Tüm taahhütleri bugfixşubeden alır ve mevcut şubenizle birleştirir.

git commit

Birleştirilen değişikliklerden tek bir taahhüt oluşturur.

-mParametreyi atlamak, taahhüdünüzü tamamlamadan önce ezilmiş taahhütlerinizden gelen her mesajı içeren bir taslak taahhüt mesajını değiştirmenizi sağlar.


222
Eski tamamlama mesajlarına referans tutmak istiyorsanız git commit( -mparam olmadan ) yazabilirsiniz ve ezdiğiniz tüm tamamlama mesajlarını içeren hazırlanmış bir tamamlama mesajını değiştirebilirsiniz.
Alex

12
Daha git commit --amend -m '...'sonra yaparak aynı şeyi başarabilirsiniz .
Janusz Lenar

19
Birleştirme çakışmalarının olması ve bu çakışmaların giderilmesi durumunda, git commitezdiğiniz tüm taahhüt mesajlarını içeren yararlı taahhüt mesajı artık gösterilmez. Bu durumda deneyin git commit --file .git/SQUASH_MSG( stackoverflow.com/a/11230783/923560 aracılığıyla ).
Abdull

23
Unutmayın varsayılan özniteliği tarafından Squasher için hareketin iradesini ezmek . Orijinal yazarı tutmak için, açıkça şöyle belirtmeniz gerekir:git commit -a --author="Author" --message="Issue title #id"
gaborous

5
git merge --squashetkisi başka bir dalı birleştirmekle aynı olan geçerli dalın üstünde tek bir işlem oluşturmanıza olanak tanır. Ancak birleştirme kaydı oluşturmaz, yani sonuç olarak çekme isteğinizde değişiklik olmaz, ancak birleştirilmiş olarak işaretlenmez! Bu yüzden, sadece yapılacak dalı silmek zorunda kalacaksınız.
am0wa

129

Sonunda bunu benim için temizleyen şey , şunları gösteren bir yorumdu :

git checkout main
git merge --squash feature

yapmakla eşdeğerdir:

git checkout feature
git diff main > feature.patch
git checkout main
patch -p1 < feature.patch
git add .

Bir özellik dalını 105 (!!) taahhütleri ile birleştirmek ve hepsini bir araya getirmek istediğimde, istemiyorum git rebase -i origin/masterçünkü ara taahhütlerin her biri için (ya da en azından git kendini bulamıyor). Kullanmak git merge --squashistediğim sonucu, tüm bir özellik dalını birleştirmek için tek bir taahhütte bulunmamı sağlıyor. Ve en fazla bir manuel çakışma çözümlemesi yapmam gerekiyor.


75
İlk önce özellik dalında git merge masterve ancak daha sonra git merge --squash featureana dalda birleştirme yapılmasını şiddetle öneririm .
dotancohen

8
@dotancohen Eski bir yorumu taradığım için üzgünüm :) git merge --squash featureAna daldan gerçekleştirmeden önce özellik dalında birleştirmeden ne kazanılır ?
bitsmack

57
Master'ı önce özellik dalıyla birleştirmek ve özellik dalınızdaki manuel düzeltmeleri ele almak istersiniz. Bu aynı zamanda testleri çalıştırmanıza ve özellik dalınızın düzgün çalıştığından emin olmanıza olanak tanır. Daha sonra, özellik dalınızın master ile otomatik olarak birleştirilebileceği garanti edilir.
Dan Kohn

4
@dankohn Yukarıdaki yorumunuzdaki açıklamayı cevabınıza eklemenizi tavsiye ederim.
guntbert

3
@bitsmack: önce ustayı bir araya getirirsiniz. Bu, özelliği master ile birleştirmeden önce özellik üzerindeki çakışmaları çözme fırsatı verir
Mike

97

Squash seçeneği ile birleştirmek istiyorsunuz. Bu, her seferinde bir dal yapmak istiyorsanız.

git merge --squash feature1

Tüm dalları tek taahhütlerle aynı anda birleştirmek istiyorsanız, önce etkileşimli olarak yeniden tabanleyin ve her özelliği ezin, ardından ahtapot birleştirin:

git checkout feature1
git rebase -i master

Bir taahhütte ezin ve diğer özellikler için tekrarlayın.

git checkout master
git merge feature1 feature2 feature3 ...

Bu son birleştirme bir "ahtapot birleştirme" dir çünkü aynı anda birçok dalı birleştirir.

Bu yardımcı olur umarım


3
Neden dayanıyorsun?
Umair A.

12
@UmairAshraf, şubenizde bir kabak yapma seçeneği sunan etkileşimli bir rebase.
andho

1
Yeniden inşası kötü bir fikirdir. Daha önce yayınlanan taahhütleri yeniden
pazarlamayın

1
@ Sebi2020 git merge --squash, önceden yayınlanan taahhütlerinizi interaktif bir rebaseden daha kötü bir şekilde yeniden tabanca eder. Etkileşimli bir yeniden pazarlama (özellik dalında) çok az olumsuz etki yapar veya hiç olumsuz etki yaratmaz.
xiix

1
@xiix Bu, yalnızca özellik dalıyla çalışan tek kişi sizseniz geçerlidir. Bu yapabileceğiniz bir varsayım değildir. Git- SCM'ye yeniden bastırma ile ilgili sayfaları okumanızı tavsiye ederim . " Deponuzun dışında var olan taahhütleri yeniden pazarlamayın ve insanlar bunlara dayalı çalışmalar yapabilirler. " tabi ki) bunu yapmamalısınız.
Sebi2020

23

Zaten varsa git merge bugfixüzerine main, birleştirme ile birine taahhüt kabak olabilir:

git reset --soft HEAD^1
git commit

git reset --soft HEAD^1en azından birleştirmenin hızlı ileri alınması durumunda, birleştirme işleminden önce yapılan son taahhüdü geri alıyor gibi görünüyor .
Jesper Matthiesen

@JesperMatthiesen bir hızlı ileri durumunda birleştirme taahhüdü alamazsınız, o zaman yaparsınız git reset --soft HEAD^<number-of-commits-to-squash>.
qwertzguy

Bu, aşağı akış birleşmesinden sonra her şeyi tek bir taahhütte ezmeme yardımcı oldu.
killjoy

18

Birleştirme newFeatureiçine dal masterözel bir ile taahhüt:

git merge --squash newFeature && git commit -m 'Your custom commit message';

Bunun yerine,

git merge --squash newFeature && git commit

newFeatureözelleştirebileceğiniz tüm şube taahhütlerini içerecek bir taahhüt mesajı alacaksınız .

Burada iyice açıklayacağım: https://youtu.be/FQNAIacelT4


10

Bu sorunun özellikle Github ile ilgili olmadığını biliyorum, ancak Github çok yaygın olarak kullanıldığından ve aradığım cevap bu olduğundan, burada paylaşacağım.

Github, depo için etkinleştirilen birleştirme seçeneklerine bağlı olarak squash birleştirmeleri gerçekleştirebilir.

Squash birleştirme etkinleştirilirse, "Birleştir" düğmesinin altındaki açılır menüde "Squash ve birleştirme" seçeneği görünmelidir.

"Squash and merge" Github özelliğinin ekran görüntüsü


GitHub, hesabınızla ilişkili varsayılan e-postayı kullanır. Birden fazla e-posta adresiniz varsa ve ikincil bir adres kullanmanız gerekiyorsa GH kullanıcı arayüzünü kullanamazsınız.
Luca Guidi

4

Özellik / görev1'de birden fazla taahhütte çalıştığınızı varsayalım.

  1. Proje şubenize gidin (project / my_project)

    git checkout project/my_project
    
  2. Yeni bir şube oluşturma (feature / task1_bugfix)

    git checkout -b feature/task1_bugfix
    
  3. İle Marge --squashseçeneği

    git merge --squash feature/task1
    
  4. Tek bir taahhüt oluşturun

    git commit -am "add single comments"
    
  5. Şubenizi itin

    git push --set-upstream origin feature/task1_bugfix
    

1

Git için

Yeni bir özellik oluşturun

Terminal / Shell üzerinden:

git checkout origin/feature/<featurename>
git merge --squash origin/feature/<featurename>

Bu işlemez, önce incelemenizi sağlar.

Ardından, bu yeni daldan özelliği taahhüt edin ve bitirin ve eskisini (dev yaptığınız) silin / yok sayın.


@Melebius Bir etiket veya önceki soru ise, "SourceTree" ye tek atıf cümlenizdedir: Artık mevcut değil.
Jordan Stefanelli

1
Bu cevabın orijinal sürümünde @JordanStefanelli SourceTree kullanılmıştır . Düzeltildiğini bildirdiğiniz için teşekkür ederiz!
Melebius

1

hata alırsanız: Birleştirilmemiş dosyalarınız olduğu için taahhütte bulunmak mümkün değildir.

git checkout master
git merge --squash bugfix
git add .
git commit -m "Message"

tüm Çakışma dosyalarını düzeltti

git add . 

ayrıca kullanabilirsin

git add [filename]

0

Yerel şubenizi itmeden önce ezmek için:

  1. daha önce teslim alınmış değilse üzerinde çalışmak için söz konusu şubeye göz atın.

  2. Saklamak istediğiniz en eski taahhüdün sha'sını bulun.

  3. Bu taahhütten yeni bir şube (tmp1) oluşturun / ödünç alın.

    git checkout -b tmp1 <sha1-of-commit>

  4. Orijinal dalı yeni bir ezme içine birleştirin.

    git merge --squash <original branch>

  5. Birleştirme tarafından oluşturulan değişiklikleri, bir özet taahhüt iletisi ile tamamlayın.

    git commit -m <msg>

  6. Ezmek istediğiniz orijinal şubeyi kontrol edin.

    git checkout <branch>

  7. Saklamak istediğiniz orijinal taahhüdüne sıfırlayın.

    git reset --soft <sha1>

  8. Bu dalı yeni tmp1 dalını temel alarak yeniden oluşturun.

    git rebase tmp1

  9. Hepsi bu - şimdi her şeyin yolunda olduğundan emin olduktan sonra geçici tmp1 dalını silin.


0

Bu işlemi kolaylaştırmak için oluşturduğum aracı kullanabilirsiniz: git-squash . Örneğin, ana daldan ayrılmış olan daldaki tüm taahhütleri ezmek için şunu yazın:

git squash master
git push --force
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.