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 -iyaklaşım ile reset --softolan arasındaki fark rebase -i, taahhüt yazarını reset --softkorumama 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 rebaseveya 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 -italimat 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 -fama aksi takdirde çok güzeldi, teşekkürler.
git push --forcesonra kullanmam gerekiyor, böylece taahhüt gerekiyor
Bundan git merge --squashbiraz 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 statustemiz olup olmadığını kontrol edin ( git reset --hardaş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 --squashdaha ayrıntılı olarak seçeneğini.
Güncelleme: Bu yöntemin git reset --soft HEAD~12 && git commitChris 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 rebasemusunuz?
git merge --squashda 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 resetMü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 commitTaahhüt mesajı squash'a göre önceden doldurulur.
gitkolduğ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~Niç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 Ntaahhü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 --amendmanuel olarak değiştirebilirsiniz. (Veya takma adı zevkinize uyacak şekilde düzenleyin.)
git squash -m "New summary.", Notomatik 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~3komut çalıştırılırken belirlendi git rebase -i HEAD~3.
En son işlem,, HEADilk 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 fixupBu 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 squashveya fixupolmadığı 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 logveya gitkve (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) pickiç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!
picksatır 1'de bırakın . Satır 1'de squashveya fixupsatı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 LogCombine to one commitbağ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 picktaahhütlerden birini ve squashdiğ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
--continueve 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 nanobirleş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 pickiçin squashdaha ö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 nanoeditörü kaydedin ve kapatın . Kaydetmek için ctrl + otuş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 ubuntukabuk üzerinde git kullanımına dayanır . Farklı os ( Windowsveya Mac) kullanıyorsanız, yukarıdaki komutlar editör hariç aynıdır. Farklı bir editör alabilirsiniz.
git add <files>
--fixupseçeneği kullanarak taahhüt ve OLDCOMMITbu 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 rebasekomut, 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.
--amendkullanı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 --amendson değişiklikleri son değişiklikleri birleştirir cdababcdve 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-branchBir 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 commitdoğ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 -ibeni 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 --squashHalkla İ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.) rebaseDoğ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 mastergit checkout -b new-branchgit checkout -b new-branch-tempgit checkout new-branchgit merge --squash new-branch-temp // tüm değişiklikleri sahneye koyargit commit 'one message to rule them all'git pushBen 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 -iseçeneğini kullandığını , Mac ve Linux kullanıcılarının bu konuda iyi olması gerektiğini belirtti.)
git squash masterkontrol edildiğinde kullanırız . ne olacak çatışmayı gizleyecek miyiz?
Söz konusu "son" ile kastedilen belirsiz olabilir.
örneğin git log --graphaş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 --mixeddaha 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.