Soru Benim son X, Git'i kullanarak bir araya getirdi


Son X taahhütlerimi Git'i kullanarak tek bir taahhütte nasıl bir araya getirebilirim?


2322
2018-03-04 04:11


Menşei


Benzer soru: stackoverflow.com/questions/7275508/... - koppor
İlgili: Git - itmeden önce birden fazla işi birleştirmek.
@matt TortoiseGit sizin aracınız. Arka planda tüm adımları otomatik olarak çağıran tek bir işlev "Birleştirmeyi birleştir" işlevi sağlar. Ne yazık ki sadece Windows için kullanılabilir. Cevabımı aşağıya bakın. - Matthias M
@Thomas: İncelemelerin taahhüt edilen bir kod üzerinde gerçekleştirilmesi gerektiğinde lütfen "nasıl kullanacağınızı" açıklayınız ve gözden geçirme yorumlarına dayanarak güncellememiz ve tekrar işlemememiz gerekiyor, ancak gözden geçirme temelli kesinti yapmak istemiyor musunuz? - Jeff Learman
İlk şeye çarpmak için bunu gör - stackoverflow.com/questions/1657017/... - goelakash


Cevaplar:


kullanım git rebase -i <after-this-commit> ve "seç" i, ikinci ve sonraki işlemlerde "squash" veya "fixup" ile değiştirin. kullanım kılavuzu.

Bu örnekte, <after-this-commit> SHA1 karması veya geçerli dalın HEAD'sinden göreceli konumudur. Örneğin, kullanıcı geçmişte geçerli BIST'ten 5 taahhüt görmek istiyorsa komut şu şekilde olur: git rebase -i HEAD~5.


1268
2018-03-04 04:18



Bu, bence, bu soruya biraz daha iyi cevap veriyor stackoverflow.com/a/5201642/295797 - Roy Truelove
İle ne denmek istenmiştir <after-this-commit>? - jtheletter
<after-this-commit> X + 1 i.e., squash etmek istediğiniz en eski taahhüdün ebeveyni. - joozek
Bu cevabı kesin olarak anlamak için çok da gergin buldum. Bir örnek yardımcı olabilirdi. - Ian Ollmann
Bu arasındaki fark rebase -i yaklaşım ve reset --soft olduğu rebase -itaahhüt yazarını korumamı sağlar. reset --soft Beni tavsiye etmeme izin veriyor. Bazen, çeken isteklerin yazılmasını ve yazar bilgisini sürdürmem gerekiyor. Bazen kendi taahhütlerime yumuşak bir şekilde sıfırlamam gerekir. Her iki büyük cevap için de vardir. - zionyx


Bunu oldukça kolay bir şekilde yapabilirsiniz. git rebase veya git merge --squash. Bu örnekte, son 3 çalışmayı ezeceğiz.

Yeni taahhüt mesajını sıfırdan yazmak istiyorsanız, bu yeterlidir:

git reset --soft HEAD~3 &&
git commit

Yeni taahhüt mesajını mevcut taahhüt mesajlarının birleşimiyle düzenlemeye başlamak istiyorsanız (yani, bir seçim / squash / squash /… / squash'a benzer git rebase -i talimat listesi ile başlayacak), o zaman bu mesajları çıkarmanız ve git commit:

git reset --soft HEAD~3 && 
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"

Bu metotların her ikisi de son üç işi, aynı şekilde tek bir yeni taahhüt haline getirmektedir. Yumuşak sıfırlama, KAFA'yı, squash istemediğiniz son taahhüdüne yeniden işaret eder. Ne indeks ne de çalışan ağaç, yumuşak sıfırlama ile dokunduğunuzda, yeni taahhütünüz için endeksi istenen durumda bırakabilirsiniz (diğer bir deyişle, "atmak üzere olduğunuz" işlemlerin tüm değişikliklerine zaten sahiptir).


2603
2018-03-05 04:19



Ha! Bu yöntemi beğendim. Sorunun ruhuna kapanan odur. Bu çok voodoo gerektiren bir üzücü. Bunun gibi bir şey, temel komutlardan birine eklenmelidir. belki git rebase --squash-recent, ya da git commit --amend-many. - Adrian Ratnapala
@ A-B-B: Şubenizde "upstream" seti varsa, o zaman kullanabilirsiniz branch@{upstream} (ya da sadece @{upstream} Mevcut şube için; her iki durumda da, son kısım kısaltılmış olabilir @{u}; görmek gitrevisions). Bu farklı olabilir sizin “En son itme taahhüdü” (örneğin, bir başkası, en son itme gücünüzün üzerine inşa edilmiş bir şeyi ittiyse ve sonra onu getirdiyseniz), ancak istediğiniz şeylere yakın gibi görünebilir. - Chris Johnsen
Bu kinda-sorta benden push -f ama aksi halde güzeldi, teşekkürler. - 2rs2ts
@ 2rs2ts git push -f sesi tehlikeli. Sadece yerel taahhütleri ezmeye dikkat edin. Asla dokunma taahhütlerine dokunmayın! - Matthias M
Başka bir yerde tüm etkileşimli rebase önerilerinden farklı olarak, her bir işlem için el ile yazım / düzeltme yazmayı gerektirmeyen bir çözüm sunduğunuz için teşekkür ederiz. - Antimony


Kullanabilirsiniz git merge --squash Bunun için biraz daha zarif olan git rebase -i. Üstadın üzerindeyseniz ve son 12 taahhüdün bir tanesini karalamak istediğinizi varsayalım.

UYARI: Önce işinizi yaptığınızdan emin olun - bunu kontrol edin git status temiz (beri git reset --hard aşamalı ve talihsiz değişiklikleri atacak)

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

belgeleri git merge Tanımlar --squash daha ayrıntılı seçenek.


Güncelleştirme: Bu yöntemin daha basit olması için tek gerçek avantaj git reset --soft HEAD~12 && git commit Chris Johnsen tarafından önerilen onun cevabı İleti mesajının, ezdiğiniz her mesajla önceden doldurulmuş olması.


575
2018-03-04 06:10



Bunun daha “zarif” olduğunu söylüyorsunuz. git rebase -iama neden olmasın. Bunu geçici olarak -1ing ettim çünkü bana göre tam tersi doğru ve bu bir hack; zorlamak için gerekenden daha fazla komut yapmıyor musunuz git merge şeylerden birini yaparak git rebase özellikle için tasarlanmıştır? - Mark Amery
@Mark Amery: Bunun daha zarif olduğunu söylediğim çeşitli sebepler var. Örneğin, bir editörün gereksiz yere yumurtlanması ve ardından "yapılacaklar" dosyasındaki bir dizgiyi arama ve değiştirme içermez. kullanma git merge --squash bir betikte kullanmak daha kolaydır. Aslında, mantık, "etkileşim" git rebase -i bunun için hiç. - Mark Longair
Bir başka avantajı git merge --squash özellikle yerel bir şubeden geliyorsanız, yeniden oluşturma işlemine kıyasla hamle / silme / yeniden adlandırmalar karşısında birleştirme çakışmaları üretme olasılığı daha azdır. (feragatname: sadece bir deneyime dayanarak, bu genel durumda doğru değilse beni düzeltin!) - Cheezmeister
Sabit sıfırlar söz konusu olduğunda her zaman çok isteksizim - yerine geçici bir etiket kullanmalıyım HEAD@{1} sadece güvenli tarafta olmak, ör. iş akışınız bir elektrik kesintisi vb. ile bir saat kesintiye uğradığında - Tobias Kienzler
@B T: Taahhüdünü yok ettin mi? :( Bunun ne demek istediğinden emin değilim. Yaptığın her şey, git'in refleksinden kolayca geri dönebileceksin. İşi kabul etmemiş olsaydın, ama dosyalar sahnelediyse, yine de onların içeriği geri, bu daha fazla iş olacak olmasına rağmen. Eğer işiniz bile sahnelenmemişse, korkarım ki bu yapılabilir; Bu yüzden cevap ön tarafa şöyle diyor: "İlk önce git durumunun temiz olduğunu kontrol edin (çünkü git sıfır - - aşamalı ve aşamalı değişiklikler atılacak)". - Mark Longair


Kaçınmak tavsiye ederim git reset Mümkün olduğunda - özellikle Git-acemi için. Tabana dayalı bir süreci otomatikleştirmeniz gerekmedikçe numara işlerin daha az egzotik bir yolu var ...

  1. İşe koyulmuş işleri bir çalışma şubesine koyun (eğer değilse) - bunun için gitk'i kullanın
  2. Hedef şubeye göz atın (ör. 'Ana')
  3. git merge --squash (working branch name)
  4. git commit

Gönderme mesajı, squash'a göre önceden doldurulur.


136
2018-03-14 23:24



Bu en güvenli yöntemdir: sıfırlama sert / sert (!!) veya reflog kullanılmaz! - TeChn4K
Genişlediyseniz harika olur (1). - Adam
@Adam: Temel olarak, bu GUI arayüzünü kullanmanız anlamına gelir. gitk ezdiğiniz kod satırını etiketlemek ve ayrıca üzerine basılacağı tabanı etiketlemek için. Normal durumda, bu etiketlerin ikisi zaten mevcut olacaktır, bu nedenle adım (1) atlanabilir. - nobar
Bu yöntemin, çalışma dalını tam olarak birleştirildiğini işaretlemediğini unutmayın, bu nedenle kaldırmak, zorla silinmeyi gerektirir. :( - Kyrstellaine
(1) için buldum git branch your-feature && git reset --hard HEAD~N en uygun yol. Bununla birlikte, bu cevap tekrar önlemek için çalıştı, git sıfırlama içerir. - eis


Dayalı Chris Johnsen'in cevabı,

Bash'tan küresel 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

... Son olarak otomatik olarak bir araya geliyor N taahhüt eder.

Not: Ortaya çıkan taahhüt mesajı sırayla tüm ezilmiş taahhütlerin bir kombinasyonudur. Eğer mutsuz iseniz, her zaman git commit --amendmanuel olarak değiştirmek için (Veya, takma adlarınıza uygun şekilde diğer adı düzenleyin.)


97
2018-02-19 19:21



İlginç, ama çok fazla taahhütlerimin benim için otomatik olarak girilmesinden daha açıklayıcı bir özet olarak, ezilmiş taahhüt mesajını kendim yazmayı tercih ederim. Yani tercih ederim git squash -m "New summary." ve sahip N işlenmemiş taahhüt sayısı olarak otomatik olarak belirlenir. - A-B-B
@ A-B-B, Bu ayrı bir soru gibi geliyor. (OP'nin sorduğu şeyin tam olarak olduğunu sanmıyorum; git squash iş akışımda buna hiç ihtiyaç duymadım.) - EthanB
Bu oldukça tatlı. Şahsen, ezilmiş beraberliklerin ilkinden gelen taahhüt mesajını kullanan bir versiyonu istiyorum. Boşluk tweaks gibi şeyler için iyi olurdu. - funroll
@funroll Anlaştık. Sadece son kayıt msg bırakarak benim için süper yaygın bir ihtiyaçtır. Bunu tasarlayabilmeliyiz ... - Steve Clay
@ A-B-B kullanabilirsiniz git commit --amend Mesajı daha da değiştirmek için, bu diğer ad, taahhüt mesajında ​​ne olması gerektiği konusunda iyi bir başlangıç ​​yapmanızı sağlar. - dashesy


TortoiseGit kullanırsanız, işlevini yapabilirsiniz Combine to one commit:

  1. TortoiseGit bağlam menüsünü aç
  2. seçmek Show Log
  3. İlgili gönderileri günlük görünümünde işaretle
  4. seçmek Combine to one commit içerik menüsünden

Combine commits

Bu işlev tüm gerekli tek git adımları otomatik olarak yürütür. Talihsizce sadece Windows için kullanılabilir.


46
2017-11-06 12:51



Bildiğim kadarıyla, bu birleşme taahhütleri için işe yaramayacaktır. - Thorkil Holm-Jacobsen
Başkaları tarafından yorumlanmamasına rağmen, bu, HEAD'de olmayan işlemler için bile geçerlidir. Mesela, ihtiyacım olan şey, itiraf etmeden önce daha akılcı bir açıklamada yaptığım bazı WIP taahhütlerini ezmek oldu. Güzelce çalıştı. Tabii ki hala umarım bunu komutlarla nasıl yapacağımı öğrenebilirim. - Charles Roberto Canato


Sayesinde Bu kullanışlı blog yazısı Son 3 işi ezmek için bu komutu kullanabileceğinizi buldum:

git rebase -i HEAD~3

Bu, izleme bilgisi / uzaktan repo olmadan yerel bir şubede bulunduğunda bile kullanışlıdır.

Komut, daha sonra yeniden sıralamak, squash, reword, vb.


46
2018-05-17 06:19





Dayalı Bu makale Usecase için bu yöntemi daha kolay buldum.

Benim 'dev' şubem, 96 taahhüt tarafından 'origin / dev' idi. (Bu nedenle bu taahhütler, henüz bir başkasına itilmemiştir).

Değişikliği zorlamadan önce bu taahhütleri tek tek ele almak istedim. Şubeyi 'origin / dev' durumuna sıfırlamayı tercih ediyorum (bu, 96 tali işlemden tüm değişiklikleri değiştirecek) ve değişiklikleri bir defada yerine getirecektir:

git reset origin/dev
git add --all
git commit -m 'my commit message'

29
2018-05-22 00:41



Tam ihtiyacım olan şey. Squash aşağı benim özellik dalından taahhüt eder ve sonra benim usta taahhüt taahhüt kiraz git. - David Victor
Bu, önceki taahhütleri ezmez! - Igor Ganapolsky
Bunu biraz daha detaylandırır mısınız @igorGanapolsky? - trudolf
@trudolf Bu gerçekten ezilmiyor (squashing için bireysel taahhütler toplanıyor). Bu, tüm değişikliklerinizi bir defada yerine getiriyor. - Igor Ganapolsky
evet, bu nedenle tüm taahhütlerinizi tek bir tanesine göre siler. Tebrikler! - trudolf


Bunu yapmak için aşağıdaki git komutunu kullanabilirsiniz.

 git rebase -i HEAD~n

n (= 4 burada) son işlemin sayısıdır. Sonra aşağıdaki seçenekleri yakaladın,

pick 01d1124 Message....
pick 6340aaa Message....
pick ebfd367 Message....
pick 30e0ccb Message....

Körük gibi güncellensin,

p 01d1124 Message....
s 6340aaa Message....
s ebfd367 Message....
s 30e0ccb Message....

Ayrıntılar için bağlantı

İyi şanslar!!


24
2018-04-06 05:26





1) Kısa hash işlemlerini tanımlayın

# git log --pretty=oneline --abbrev-commit
abcd1234 Update to Fix for issue B
cdababcd Fix issue B
deab3412 Fix issue A
....

2) Son iki taahhüdünü (birleştirme) birleştirmek istiyorsanız

# git rebase -i deab3412 

3) Bu bir açılır nano birleştirmek için editör. Ve aşağıdakine benziyor

....
pick cdababcd Fix issue B
pick abcd1234 Update to Fix for issue B
....

4) kelimeyi yeniden adlandırın pick için squash daha önce mevcut olan abcd1234. Yeniden adlandırıldıktan sonra aşağıdaki gibi olmalıdır.

....
pick cdababcd Fix issue B
squash abcd1234 Update to Fix for issue B
....

5) Şimdi kaydedin ve kapatın nano editör. Basın ctrl + o ve bas Enter kaydetmek. Ve sonra basın ctrl + x editörden çıkmak için

6) Sonra nano gerekirse güncellemeleri güncellemek için editör tekrar açılır.

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 repoya bas. Eklemek için not + şube isminden önce imzala.

# git push origin +master

Not: Bu, git'i kullanmaya dayanmaktadır ubuntu kabuk. Farklı os kullanıyorsanızWindows veya Mac) Yukarıdaki komutlar editör hariç aynıdır. Farklı editörler alabilirsiniz.


22
2018-01-10 14:19



Bunun için teşekkürler, en iyi rehber! - Jeremie Ges
Sadece son iki taahhüdünü güncellediğimde bile, son taahhüdün 6'lık son taahhüdüne sıfırlanmam, nedenini bilmiyorum - Carlos Liu