Git'i kullanarak son X taahhüdümü nasıl tek bir taahhütte ezebilirim?
Git'i kullanarak son X taahhüdümü nasıl tek bir taahhütte ezebilirim?
Yanıtlar:
git rebase -i <after-this-commit>
İkinci ve sonraki işlemlerde "toplama" işlevini kullanın ve kılavuzda açıklandığı gibi "squash" veya "fixup" ile değiştirin .
Bu örnekte, <after-this-commit>
SHA1 karması veya taahhütlerin rebase komutu için analiz edildiği geçerli dalın HEAD'ından göreli konumdur. Örneğin, kullanıcı geçmişte mevcut HEAD'den 5 taahhüt görüntülemek isterse komuttur git rebase -i HEAD~5
.
<after-this-commit>
?
<after-this-commit>
X + 1 taahhüdü, yani ezmek istediğiniz en eski taahhüdün ebeveyni.
rebase -i
yaklaşım ile reset --soft
olan arasındaki fark rebase -i
, taahhüt yazarını reset --soft
korumama izin verirken , tavsiye etmeme izin verir. Bazen çekme bilgilerinin taahhütlerini ezmek zorundayım, ancak yazar bilgilerini koruyorum. Bazen kendi taahhütlerimde yumuşak ayarları sıfırlamam gerekir. Her iki harika yanıta da oy verin.
Bunu, git rebase
veya olmadan oldukça kolay bir şekilde yapabilirsiniz git merge --squash
. Bu örnekte, son 3 taahhüdü ezeceğiz.
Yeni taahhüt mesajını sıfırdan yazmak istiyorsanız, bu yeterli:
git reset --soft HEAD~3 &&
git commit
Yeni tamamlama mesajını mevcut tamamlama mesajlarının bir araya getirilmesiyle düzenlemeye başlamak istiyorsanız (örneğin, bir pick / squash / squash /… / squash git rebase -i
talimat listesinin size başlayacağı şeye benzer ), bu mesajları çıkarmanız ve geçmeniz gerekir onları git commit
:
git reset --soft HEAD~3 &&
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"
Bu yöntemlerin her ikisi de son üç taahhüdü aynı şekilde yeni bir taahhütte ezmektedir. Yumuşak sıfırlama sadece HEAD'ı ezmek istemediğiniz son işleme yönlendirir. Ne indekse ne de çalışma ağacına yumuşak sıfırlama dokunulmaz, bu da indeksi yeni taahhüdünüz için istenen durumda bırakır (yani “atmak” üzere taahhütlerin tüm değişikliklerine zaten sahiptir).
git rebase --squash-recent
, hatta git commit --amend-many
.
branch@{upstream}
(veya yalnızca @{upstream}
geçerli dal için kullanabilirsiniz ; her iki durumda da, son bölüm kısaltılabilir @{u}
; bkz. Gitrevisions ). Bu farklılık da “işlemek itilmiş son” (örneğin başkasının en son itme üstünde inşa edilmiş ve sonra da o getirilen o şey itilirse), ama yakın istediğinize olabilir gibi görünüyor.
push -f
ama aksi takdirde çok güzeldi, teşekkürler.
git push --force
sonra kullanmam gerekiyor, böylece taahhüt gerekiyor
Bundan git merge --squash
biraz daha zarif olan bunun için kullanabilirsiniz git rebase -i
. Usta olduğunuzu ve son 12 taahhüdü bir araya getirmek istediğinizi varsayalım.
UYARI: Öncelikle işinizi yaptığınızdan emin olun — git status
temiz olup olmadığını kontrol edin ( git reset --hard
aşamalı ve düzenlenmemiş değişiklikleri atacağından)
Sonra:
# Reset the current branch to the commit just before the last 12:
git reset --hard HEAD~12
# HEAD@{1} is where the branch was just before the previous command.
# This command sets the state of the index to be as it would just
# after a merge from that commit:
git merge --squash HEAD@{1}
# Commit those squashed changes. The commit message will be helpfully
# prepopulated with the commit messages of all the squashed commits:
git commit
Belgelerigit merge
açıklar --squash
daha ayrıntılı olarak seçeneğini.
Güncelleme: Bu yöntemin git reset --soft HEAD~12 && git commit
Chris Johnsen tarafından cevabında önerilen daha basit olan tek avantajı, ezdiğiniz her taahhüt mesajıyla önceden doldurulmuş taahhüt mesajını almanızdır.
git rebase -i
, ama bunun bir sebebi yok. Geçici olarak bunu -1'e çevirdi çünkü bana öyle geliyor ki tam tersi doğru ve bu bir hack; sadece özel olarak tasarlanmış git merge
şeylerden birini yapmaya zorlamak için gerekenden daha fazla komut yerine getirmiyor git rebase
musunuz?
git merge --squash
da bir komut dosyası kullanmak daha kolaydır. Esasen, bunun mantığı, bunun için "etkileşime" hiç ihtiyaç duymamanızdı git rebase -i
.
git merge --squash
, özellikle yerel bir şubeden birleşiyorsanız, yeniden baslamaya kıyasla hamle / silme / yeniden adlandırma karşısında birleştirme çakışmaları üretme olasılığının düşük olmasıdır. (tekzip: sadece bir deneyime dayanarak, bu genel durumda doğru değilse beni düzeltin!)
HEAD@{1}
sadece güvenli tarafta olmak yerine geçici bir etiket kullanırdım, örneğin iş akışınız bir elektrik kesintisi vb. Tarafından bir saat boyunca kesildiğinde
git reset
Mümkün olduğunca kaçınmanızı öneririm - özellikle Git acemiler için. Bir dizi taahhüde dayalı bir süreci gerçekten otomatikleştirmeniz gerekmedikçe , daha az egzotik bir yol var ...
git merge --squash (working branch name)
git commit
Taahhüt mesajı squash'a göre önceden doldurulur.
gitk
olduğunuz kod satırını etiketlemek ve ayrıca üzerinde ezileceği tabanı etiketlemek için GUI arayüzünü kullanmak anlamına gelir . Normal durumda, bu etiketlerin her ikisi de zaten mevcut olacaktır, bu nedenle (1) adımı atlanabilir.
git branch your-feature && git reset --hard HEAD~N
için en uygun yolu buldum . Bununla birlikte, bu cevabı önlemeye çalışan git reset'i tekrar içerir.
Chris Johnsen'ın cevabına dayanarak ,
Bash'tan global bir "squash" takma adı ekleyin: (veya Windows'ta Git Bash)
git config --global alias.squash '!f(){ git reset --soft HEAD~${1} && git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"; };f'
... veya Windows 'Komut İstemi'ni kullanarak:
git config --global alias.squash "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
Sizin ~/.gitconfig
şimdi bu takma adı içermelidir:
[alias]
squash = "!f(){ git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; };f"
Kullanımı:
git squash N
... Bu son N
taahhütleri otomatik olarak bir araya getiriyor .
Not: Ortaya çıkan taahhüt mesajı, tüm ezilmiş taahhütlerin sırasıyla bir kombinasyonudur. Bundan memnun değilseniz, her zaman git commit --amend
manuel olarak değiştirebilirsiniz. (Veya takma adı zevkinize uyacak şekilde düzenleyin.)
git squash -m "New summary."
, N
otomatik olarak unpushed taahhütlerinin sayısını belirlemeyi tercih ederim .
git commit --amend
, iletiyi daha fazla değiştirmek için kullanabilirsiniz , ancak bu takma ad, yürütme iletisinde ne olması gerektiği konusunda iyi bir başlangıç yapmanızı sağlar.
Bu kullanışlı blog yazısı sayesinde , son 3 taahhüdü ezmek için bu komutu kullanabileceğinizi buldum:
git rebase -i HEAD~3
Bu, izleme bilgisi / uzaktan repo içermeyen yerel bir şubede olduğunuzda bile çalıştığı için kullanışlıdır.
Komut, etkileşimli rebase düzenleyicisini açacak ve daha sonra normal şekilde yeniden sıralamanıza, ezmenize, yeniden sarmanıza vb.
Etkileşimli rebase düzenleyicisini kullanarak:
Etkileşimli rebase editörü son üç taahhüdü gösterir. Bu kısıtlama, HEAD~3
komut çalıştırılırken belirlendi git rebase -i HEAD~3
.
En son işlem,, HEAD
ilk satır 1'de görüntülenir. A ile başlayan satırlar #
yorumlar / belgelerdir.
Görüntülenen belgeler oldukça açıktır. Herhangi bir satırda komutu istediğiniz komuttan değiştirebilirsiniz pick
.
Komutu kullanmayı tercih ederim fixup
Bu yukarıdaki satırdaki komut satırındaki değişiklikleri "ezdiği" mesajını attığı .
1. satırdaki taahhüt, HEAD
çoğu durumda bunu olarak bırakırsınız pick
. Sen kullanamaz squash
veya fixup
olmadığı için başka içine işlemek ezmek için taahhüt.
Taahhütlerin sırasını da değiştirebilirsiniz. Bu, kronolojik olarak bitişik olmayan komutları ezmenizi veya düzeltmenizi sağlar.
Günlük pratik bir örnek
Son zamanlarda yeni bir özellik taahhüt ettim. O zamandan beri, iki hata düzeltmesi yaptım. Ama şimdi taahhüt ettiğim yeni özellikte bir hata (ya da sadece bir yazım hatası) keşfettim. Ne kadar can sıkıcı! Taahhüt tarihimi kirleten yeni bir taahhüt istemiyorum!
Yaptığım ilk şey hatayı düzeltmek ve yorumla yeni bir taahhütte bulunmaktır squash this into my new feature!
.
Sonra çalıştırmak git log
veya gitk
ve (bu durumda yeni özelliğin SHA taahhüt almak 1ff9460
).
Sonra, etkileşimli rebase editörünü getiriyorum git rebase -i 1ff9460~
. ~
Tamamlamak sonra SHA editörü işlemek olduğunu eklemeyi editörü söyler.
Sonra, ben düzeltmeyi (içeren taahhüt hareket fe7f1e0
özelliği işlemek ve değişim altından kadar) pick
için fixup
.
Düzenleyiciyi kapatırken, düzeltme özellik taahhüdüne dahil edilecek ve taahhüt geçmişim güzel ve temiz görünecek!
Tüm taahhütler yerel olduğunda iyi çalışır, ancak uzaktan kumandaya zaten itilmiş olan herhangi bir taahhüdü değiştirmeye çalışırsanız, aynı şubeyi kontrol eden diğer geliştiriciler için gerçekten sorunlara neden olabilirsiniz!
pick
satır 1'de bırakın . Satır 1'de squash
veya fixup
satırda kesinleştirme seçeneğini belirlerseniz git, "hata: önceki işlem olmadan 'düzeltilemez' 'mesajını gösterir. Sonra size düzeltme seçeneği verecektir: "Bunu 'git rebase --edit-todo' ile düzeltebilir ve sonra 'git rebase --continue' komutunu çalıştırabilirsiniz." ya da sadece iptal edip baştan başlayabilirsiniz: "Ya da 'git rebase --abort' ile rebase'i iptal edebilirsiniz.".
TortoiseGit kullanıyorsanız, işlevi yapabilirsiniz Combine to one commit
:
Show Log
Combine to one commit
bağlam menüsündenBu işlev tüm gerekli tek git adımlarını otomatik olarak yürütür. Ne yazık ki sadece Windows için kullanılabilir.
Bunu yapmak için aşağıdaki git komutunu kullanabilirsiniz.
git rebase -i HEAD~n
n (= 4 burada) son işlem sayısıdır. Sonra aşağıdaki seçeneklere sahipsiniz,
pick 01d1124 Message....
pick 6340aaa Message....
pick ebfd367 Message....
pick 30e0ccb Message....
Aşağıdaki pick
taahhütlerden birini ve squash
diğerlerini de en son sürümüne güncelleyin ,
p 01d1124 Message....
s 6340aaa Message....
s ebfd367 Message....
s 30e0ccb Message....
Detaylar için tıklayın Bağlantı
Bu makaleye dayanarak bu yöntemi kullanıcı tabanım için daha kolay buldum.
'Dev' şubem 96 komisyon tarafından 'origin / dev' in önünde yer aldı (bu yüzden bu komisyonlar henüz uzaktan kumandaya gönderilmedi).
Değişimi zorlamadan önce bu taahhütleri ezberlemek istedim. Şube 'orijin / dev' durumuna sıfırlamayı tercih ediyorum (bu, 96 taahhütten tüm değişiklikleri bırakacak) ve daha sonra değişiklikleri bir kerede gerçekleştirecek:
git reset origin/dev
git add --all
git commit -m 'my commit message'
Şubede taahhütleri birleştirmek istediğinizde çalıştırın:
git rebase -i HEAD~(n number of commits back to review)
misal:
git rebase -i HEAD~1
Bu, metin düzenleyicisini açacaktır ve bu taahhütlerin bir araya getirilmesini istiyorsanız, her bir taahhüdün önündeki 'seçim'i' squash 'ile değiştirmeniz gerekir. Belgelerden:
Örneğin, tüm taahhütleri bir araya getirmek istiyorsanız, 'seçim' yaptığınız ilk taahhüttür ve gelecekteki tüm (ilkin altına yerleştirilen) 'squash' olarak ayarlanmalıdır. Vim kullanıyorsanız , düzenleyiciyi kaydedip çıkmak için : x ekle modunda kullanın.
Sonra davanın devamı için:
git rebase --continue
İşlem geçmişinizi yeniden yazmanın bu ve diğer yolları hakkında daha fazla bilgi için bu yararlı gönderiye bakın
--continue
ve vim'in ne yaptığını da açıklayın :x
.
Anomies cevabı iyi, ama bu konuda güvensiz hissettim, bu yüzden birkaç ekran görüntüsü eklemeye karar verdim.
Nerede olduğunuzu görün git log
. En önemlisi, öncelikle taahhüt karmasını taahhüt bulmak yok kabak istiyorum. Yani sadece:
Yürütme git rebase -i [your hash]
benim durumumda,:
$ git rebase -i 2d23ea524936e612fae1ac63c95b705db44d937d
Benim durumumda, taahhütte ilk kez olan her şeyi ezmek istiyorum. Sıralama ilkinden sonuncuya kadar, tam olarak olduğu gibi git log
. Benim durumumda istiyorum:
Yalnızca bir taahhüt seçtiyseniz ve geri kalanını ezdiyseniz, bir taahhüt mesajını ayarlayabilirsiniz:
Bu kadar. Bunu ( :wq
) kaydettikten sonra işiniz bitti. Şuna bir bakgit log
.
git log
1) Taahhüt kısa karmasını tanımlayın
# git log --pretty=oneline --abbrev-commit
abcd1234 Update to Fix for issue B
cdababcd Fix issue B
deab3412 Fix issue A
....
Burada bile git log --oneline
kısa karma elde etmek için kullanılabilir.
2) Son iki işi ezmek (birleştirmek) istiyorsanız
# git rebase -i deab3412
3) Bu nano
birleştirme için bir editör açar . Ve aşağıdaki gibi görünüyor
....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....
4) kelimesi yeniden adlandır pick
için squash
daha önce mevcut olan abcd1234
. Yeniden adlandırdıktan sonra aşağıdaki gibi olmalıdır.
....
pick cdababcd Fix issue B
squash abcd1234 Update to Fix for issue B
....
5) Şimdi nano
editörü kaydedin ve kapatın . Kaydetmek için ctrl + o
tuşuna basın Enter
. Ve sonractrl + x
editörden çıkmak için .
6) Sonra nano
editör yorumları güncellemek için tekrar açılır, gerekirse güncelleyin.
7) Şimdi başarıyla ezildi, günlükleri kontrol ederek doğrulayabilirsiniz.
# git log --pretty=oneline --abbrev-commit
1122abcd Fix issue B
deab3412 Fix issue A
....
8) Şimdi repo yapmak için bastırın. +
Şube adından önce işaret eklemek için not edin. Bu, zorla itme anlamına gelir.
# git push origin +master
Not: Bu ubuntu
kabuk üzerinde git kullanımına dayanır . Farklı os ( Windows
veya Mac
) kullanıyorsanız, yukarıdaki komutlar editör hariç aynıdır. Farklı bir editör alabilirsiniz.
git add <files>
--fixup
seçeneği kullanarak taahhüt ve OLDCOMMIT
bu taahhüdü birleştirmek (squash) gerekir.git commit --fixup=OLDCOMMIT
Şimdi bu, HEAD'ın üstünde yeni bir taahhüt yaratıyor fixup1 <OLDCOMMIT_MSG>
.
OLDCOMMIT
.git rebase --interactive --autosquash OLDCOMMIT^
İşte ^
önceki taahhüt anlamına gelir OLDCOMMIT
. Bu rebase
komut, bir editörde (vim veya nano) etkileşimli pencereyi açar, sadece kaydetmekten ve herhangi bir şey yapmamıza gerek yoktur. Çünkü buna geçilen seçenek otomatik olarak son taahhüdü eski taahhüdün yanına taşır ve işlemifixup
(squash'a eşdeğer). Sonra rebase devam eder ve biter.
--amend
kullanılabilir git-commit
. # git log --pretty=oneline --abbrev-commit
cdababcd Fix issue B
deab3412 Fix issue A
....
# git add <files> # New changes
# git commit --amend
# git log --pretty=oneline --abbrev-commit
1d4ab2e1 Fix issue B
deab3412 Fix issue A
....
Burada --amend
son değişiklikleri son değişiklikleri birleştirir cdababcd
ve yeni taahhüt kimliği oluşturur1d4ab2e1
Son 10 taahhüdü 1 tek taahhütte ezmek için:
git reset --soft HEAD~10 && git commit -m "squashed commit"
Ayrıca uzak dalı ezilmiş komutla güncellemek istiyorsanız:
git push -f
feature-branch
Bir Altın Deposundan ( golden_repo_name
) klonlanmış uzak bir dalda (denir ), işte taahhütlerinizi bir araya getirme tekniği:
Altın Repoyu Satın Alın
git checkout golden_repo_name
Aşağıdaki gibi yeni bir dal (altın repo) oluşturun
git checkout -b dev-branch
Zaten sahip olduğunuz yerel şubenizle kabak birleştirin
git merge --squash feature-branch
Değişikliklerinizi yapın (bu, dev-şubesine giren tek taahhüt olacaktır)
git commit -m "My feature complete"
Şubeyi yerel deponuza aktarın
git push origin dev-branch
Gerçekten uygun olan ne olabilir:
Üstünde ezmek istediğiniz taahhüt karmasını bulun, diyelim d43e15
.
Şimdi kullanın
git reset d43e15
git commit -am 'new commit name'
Bu süper kudretli kludgy, ama bir tür havalı şekilde, bu yüzden sadece halkaya atacağım:
GIT_EDITOR='f() { if [ "$(basename $1)" = "git-rebase-todo" ]; then sed -i "2,\$s/pick/squash/" $1; else vim $1; fi }; f' git rebase -i foo~5 foo
Çeviri: git için yeni bir "editör" sağlayın, eğer düzenlenecek dosya adı git-rebase-todo
(etkileşimli rebase istemi) ilk "seçim" dışındaki her şeyi "squash" olarak değiştirir ve aksi takdirde vim'i doğurur. ezilmiş taahhüt mesajını düzenlemek için vim alırsınız. (Ve açıkçası şube foo'unda son beş taahhüdü eziyordum, ancak istediğiniz gibi değiştirebilirsiniz.)
Muhtemelen Mark Longair'in önerdiğini yapardım .
Her bir taahhüdü tek bir taahhütte ezmek istiyorsanız (örneğin, bir projeyi ilk kez halka açarken) deneyin:
git checkout --orphan <new-branch>
git commit
Bunu yapmanın en kolay yolunun, yeni bir daldan master yapmak ve özellik dalının bir birleşimini yapmaktır.
git checkout master
git checkout -b feature_branch_squashed
git merge --squash feature_branch
Sonra tüm değişiklikleri yapmaya hazırsınız.
Şu anda ezmek istediğiniz dalda olduğunuz göz önüne alındığında, her zaman çalışan basit bir astar, usta kaynaklandığı daldır ve en son taahhüt, kullanmak istediğiniz taahhüt mesajını ve yazarı içerir:
git reset --soft $(git merge-base HEAD master) && git commit --reuse-message=HEAD@{1}
örneğin, son 3 taahhüdü bir şubede (uzak depo) tek bir işlemde ezmek istiyorsanız, örneğin: https://bitbucket.org
Yaptığım şey
(MASTER)
Fleetwood Mac Fritz
║ ║
Add Danny Lindsey Stevie
Kirwan Buckingham Nicks
║ ╚═══╦══════╝
Add Christine ║
Perfect Buckingham
║ Nicks
LA1974══════════╝
║
║
Bill <══════ YOU ARE EDITING HERE
Clinton (CHECKED OUT, CURRENT WORKING DIRECTORY)
Https://github.com/fleetwood-mac/band-history deposunun bu çok kısaltılmış tarihinde , Bill Clinton taahhüdünü orijinal ( MASTER
) Fleetwood Mac taahhüdüne birleştirmek için bir çekme isteği açtınız.
Bir çekme isteği açtınız ve GitHub'da şunu görüyorsunuz:
Dört işlem:
Hiç kimsenin depo tarihinin tamamını okumayı umursamayacağını düşünerek. (Aslında bir depo var, yukarıdaki bağlantıyı tıklayın!) Bu taahhütleri ezmeye karar verdiniz. Yani git ve kaç git reset --soft HEAD~4 && git commit
. O zaman sengit push --force
PR'nizi temizlemek için GitHub'a gidin.
Peki ne olacak? Fritz'den Bill Clinton'a giden tek bir taahhüt yaptın. Çünkü dün bu projenin Buckingham Nicks versiyonu üzerinde çalıştığını unuttun. Vegit log
GitHub'da gördüklerinizle eşleşmiyor.
git checkout
onlarıgit reset --soft
ogit commit
doğrudan o çözgü gelen etmek içingit rebase -i HEAD^^
^ 'nin sayısı X
(bu durumda, son iki komutu ezin)
Diğer mükemmel cevaplara ek olarak, git rebase -i
beni her zaman taahhüt emriyle nasıl karıştırdığını eklemek isterim - yeni olandan daha yaşlı veya tam tersi? Bu benim iş akışım:
git rebase -i HEAD~[N]
, burada N, en sonuncusundan başlayarak katılmak istediğim taahhütlerin sayısıdır . Yani git rebase -i HEAD~5
"son 5 taahhüdü yenisine sıkıştır" anlamına gelir;Peki böyle bir iş akışıyla ilgili soruya verilen cevap ne olacak?
merge --squash
Halkla İlişkiler sonrasında yapması daha kolay olurdu , ancak ekip bunun süreci yavaşlatacağını düşündü.)Bu sayfada böyle bir iş akışı görmedim. (Bu benim gözlerim olabilir.) rebase
Doğru anlarsam, çoklu birleştirme çoklu çatışma çözümlerini gerektirir . Bunu düşünmek bile istemiyorum!
Bu bizim için işe yarıyor gibi görünüyor.
git pull master
git checkout -b new-branch
git checkout -b new-branch-temp
git checkout new-branch
git merge --squash new-branch-temp
// tüm değişiklikleri sahneye koyargit commit 'one message to rule them all'
git push
Ben daha genel bir çözüm 'N' taahhüt belirtmek değil, yerine ezmek istediğiniz şube / commit-id belirtmek olduğunu bulmak. Bu, belirli bir taahhüde kadar olan taahhütleri saymaktan daha az hataya açıktır - sadece etiketi doğrudan belirtin veya gerçekten saymak istiyorsanız HEAD ~ N'yi belirleyebilirsiniz.
İş akışımda bir şubeye başlıyorum ve bu daldaki ilk taahhüdüm hedefi özetliyor (yani, genellikle kamu deposuna özellik için 'son' mesaj olarak iteceğim şey). Bu yüzden bittiğinde, hepsi Yapmak istiyorum git squash master
ilk mesaja geri döndüm ve sonra itmeye hazırım.
Takma adı kullanıyorum:
squash = !EDITOR="\"_() { sed -n 's/^pick //p' \"\\$1\"; sed -i .tmp '2,\\$s/^pick/f/' \"\\$1\"; }; _\"" git rebase -i
Bu, tarihin ezilmeden önce dökülmesini sağlar - bu, geri dönmek isterseniz, eski bir taahhüt kimliğini konsoldan alarak kurtarma şansı verir. (Solaris kullanıcıları GNU sed -i
seçeneğini kullandığını , Mac ve Linux kullanıcılarının bu konuda iyi olması gerektiğini belirtti.)
git squash master
kontrol edildiğinde kullanırız . ne olacak çatışmayı gizleyecek miyiz?
Söz konusu "son" ile kastedilen belirsiz olabilir.
örneğin git log --graph
aşağıdakileri çıktılar (basitleştirilmiş):
* commit H0
|
* merge
|\
| * commit B0
| |
| * commit B1
| |
* | commit H1
| |
* | commit H2
|/
|
Sonra zamana göre son taahhütler H0, birleştirme, B0. Onları ezmek için birleştirilmiş şubenizi H1 taahhüdünde yeniden birleştirmeniz gerekecek.
Sorun, H0'ın H1 ve H2 içermesidir (ve genellikle birleştirmeden önce ve dallandıktan sonra daha fazla taahhütte bulunurken) B0 içermez. Bu yüzden en azından H0, birleştirme, H1, H2, B0'daki değişiklikleri yönetmelisiniz.
Rebase kullanmak mümkündür, ancak diğerlerinden daha farklı bir şekilde belirtilen cevaplarda:
rebase -i HEAD~2
Bu size seçim seçeneklerini gösterecektir (diğer cevaplarda belirtildiği gibi):
pick B1
pick B0
pick H0
H0 yerine pick yerine squash koyun:
pick B1
pick B0
s H0
Kaydet ve çık sonra rebase H1 sonra sırayla taahhüt uygular. Bu, sizden tekrar çatışmaları çözmenizi isteyeceği anlamına gelir (HEAD başlangıçta H1 olacak ve daha sonra uygulandıkça taahhütleri biriktirecektir).
Rebase bittikten sonra ezilmiş H0 ve B0 için mesaj seçebilirsiniz:
* commit squashed H0 and B0
|
* commit B1
|
* commit H1
|
* commit H2
|
PS Sadece BO olarak sıfırlarsanız: (örneğin, bunu kullanarak reset --mixed
daha ayrıntılı olarak burada açıklanır https://stackoverflow.com/a/18690845/2405850 ):
git reset --mixed hash_of_commit_B0
git add .
git commit -m 'some commit message'
daha sonra H0, H1, H2'nin B0 değişikliklerine girersiniz (kaybetmek, dallanma ve birleştirme öncesi değişiklikler için tamamen taahhüt eder.