Mevcut, bilinmeyen tamamlama iletileri nasıl değiştirilir?


7664

Bir taahhüt mesajına yanlış olanı yazdım.

Mesajı nasıl değiştirebilirim? Taahhüt henüz itilmedi.


868
Gitmek için biraz yeni olanlar için: Laurie'nin henüz itilmemiş olma konusundaki görüşü önemlidir. Yeniden basmak gibi, bu da tarihi değiştiriyor. Birisi orijinal ve yeniden yazılan geçmiş arasında repodan klonladı / çıkardıysa, yeniden yazma işleminden sonra (bu dal için) çekemez.
Pat Notz

Yanıtlar:


16129

En son taahhüt mesajını değiştirme

git commit --amend

düzenleyicinizi açarak en son işlemin işlem mesajını değiştirmenize olanak tanır. Ayrıca, taahhüt iletisini doğrudan komut satırında aşağıdakilerle ayarlayabilirsiniz:

git commit --amend -m "New commit message"

… Ancak bu, çok satırlı kesinleştirme mesajlarını veya küçük düzeltmeleri girmeyi daha zor hale getirebilir.

Eğer herhangi bir çalışma kopyası değişiklikleri gerektirmeyen emin olun sahnelenen bu yapmadan önce veya onlar da işlenen alacak. ( Değişik olmayan değişiklikler taahhüt edilmez.)

Daha önce uzak dalınıza aktardığınız bir taahhüt mesajını değiştirme

Taahhütünüzü zaten uzak şubenize ittiyseniz, - taahhütlerinizi yerel olarak değiştirdikten sonra (yukarıda açıklandığı gibi) - ayrıca taahhüdü şununla zorlamaya zorlamanız gerekir :

git push <remote> <branch> --force
# Or
git push <remote> <branch> -f

Uyarı: zorla itme, uzak dalın üzerine yerel dalınızın durumunu yazar . Uzak şubede yerel şubenizde olmayan taahhütler varsa , bu taahhütleri kaybedersiniz.

Uyarı: Daha önce başkalarıyla paylaştığınız taahhütleri değiştirme konusunda dikkatli olun. Değişikliklerin yapılması, esasen farklı SHA ID'leri için onları yeniden yazar ; bu, diğer kişilerin yeniden yazdığınız eski taahhüdün kopyalarına sahip olması durumunda bir sorun oluşturur. Eski taahhüdün bir kopyasına sahip olan herkesin çalışmalarını, bazen zor olabilen yeni yeniden yazılmış taahhüdünüzle senkronize etmesi gerekir, bu nedenle paylaşılan taahhüt geçmişini yeniden yazmaya çalışırken başkalarıyla koordinasyon yaptığınızdan emin olun veya yalnızca paylaşılan taahhütleri yeniden yazmaktan kaçının tamamen.


Etkileşimli bir rebase gerçekleştirin

Başka bir seçenek etkileşimli rebase kullanmaktır. Bu, en son mesaj olmasa bile güncellemek istediğiniz mesajları düzenlemenize olanak tanır.

Git squash yapmak için şu adımları izleyin:

// n is the number of commits up to the last commit you want to be able to edit
git rebase -i HEAD~n

Taahhütlerinizi ezdiğinizde - e/rmesajı düzenlemek için seçeneğini belirleyin:

Resim açıklamasını buraya girin

Etkileşimli rebase hakkında önemli not

Eğer kullandığınız zaman git rebase -i HEAD~nolabilir fazla n kaydedilmesini daha. Git, son taahhütlerde yer alan tüm taahhütleri "toplayacak" ve bu aralık arasında bir yerde birleşme varsa, tüm taahhütleri de göreceksiniz, böylece sonuç n + olacaktır.

İyi bahşiş:

Bunu tek bir daldan daha fazlası için yapmanız gerekiyorsa ve içeriği değiştirirken çakışmalarla karşılaşabiliyorsanız, git rerereGit'in bu çakışmaları sizin için otomatik olarak çözmesine izin verin.


belgeleme


257
Ancak bu git commit --amendkadar güçlü değil git rebase -i.
Jeffrey Jose

76
@jeffjose, Kesinlikle olmak zorunda değil. Ayrıca, git commit --amend(a?) Master taahhüdünü düzeltebilir.
strager

116
Zaten itilmiş ettiyseniz, sadece tekrar itmek zorlamak:git push -f origin branchname
Hughes

177
@hughes git push -fbaşkaları aynı depoyu kullanıyorsa biraz tehlikeli değil mi?
Armand

91
İşlem mesajının tamamını yeniden yazmak istemiyorsanız, adresine gidin git commit --amend -c HEAD. Bu, eski tamamlama mesajınızla önceden doldurulmuş düzenleyiciyi açacaktır, böylece değiştirebilirsiniz.
Sam

2506
git commit --amend -m "your new message"

7
Git commit --amend -m "Yeni ileti" yaptım, ancak Github'a basmak "Tekrar basmadan önce uzaktan değişiklikleri birleştir" i oluşturdu. Çekme işleminden sonra --amend ve tekrar itin, yeni mesaj görünmez. Bunun yerine "github.com:" mymypopo şubesini birleştir ":
Dave Everitt

8
@DaveEveritt, düzeltmeyi denemeden önce büyük olasılıkla taahhüdünüzü yukarı doğru ittiniz.
Thorbjørn Ravn Andersen

12
@Kyralessa doğru değil. Bash'da, işi bitirene kadar alıntıyı kapatarak çok satırlı kesinleştirme mesajlarını kolayca oluşturabilirsiniz (tırnak işaretleri içindeki her satırın sonunda geri dönerek).
ocaklar

32
İki yıl önce yazılmış bir cevabın ana fikrine çok benzeyen bir cevabın nasıl göründüğünü ve aynı zamanda kabul edilen cevabın çok fazla oy aldığını anlamıyorum. Garip. (yanıtı ile yanlış bir şey olsa)
mutlu kodlayıcı

7
@AmalMurali, iyi. Demek istediğim, sorunun popülerliği ya da cevabın yararlılığı hakkında o kadar da önemli değildi. Ancak bu özel cevap en eski cevap değildir ve kabul edilen cevap hakkında daha fazla bilgi sunmaz. Kabul edilen cevabın bir bölümünün bir kopyası gibi görünüyor. Demek istediğim buydu. ŞEREFE!
mutlu kodlayıcı

2376

Düzeltmek istediğiniz taahhüt en son işlem değilse:

  1. git rebase --interactive $parent_of_flawed_commit

    Birkaç kusurlu taahhüdü düzeltmek istiyorsanız, en eski olanın ebeveynini geçin.

  2. Bir editör gelecektir, verdiğinizden bu yana tüm taahhütlerin bir listesi.

    1. Değişim pickiçin reword(veya Git eski sürümleri, üzerine edit) Eğer düzeltme istediğiniz herhangi kaydedilmesini önünde.
    2. Kaydettikten sonra Git listelenen taahhütleri tekrar oynatır.

  3. Yeniden yazmak istediğiniz her taahhüt için Git sizi düzenleyicinize geri götürür . Düzenlemek istediğiniz her taahhüt için Git sizi kabuğa bırakır. Kabuğun içindeyseniz:

    1. Taahhüdü istediğiniz şekilde değiştirin.
    2. git commit --amend
    3. git rebase --continue

Bu dizinin çoğu, gittiğinizde çeşitli komutların çıktısıyla size açıklanacaktır. Bu çok kolay; ezberlemenize gerek yok - sadece git rebase --interactivene kadar zaman önce olursa olsun taahhütleri düzeltmenize izin verdiğini unutmayın .


Zaten itmiş olduğunuz taahhütleri değiştirmek istemeyeceğinizi unutmayın. Ya da belki yaparsınız, ancak bu durumda taahhütlerinizi yerine getirmiş ve üstlerine iş yapmış olabilecek herkesle iletişim kurmak için büyük özen göstermeniz gerekecektir. Birisi yayınlanan bir şubeye yeniden erişim veya sıfırlama yaptıktan sonra nasıl kurtarırım / yeniden senkronize edebilirim?


39
İlk taahhüdün (ebeveynleri olmayan) mesajı değiştirilebilir mi?
13ren

27
Bu, diğer cevaplardan birinde belirtilmiştir, ancak burada bir not yazacağım. Git 1.6.6 yana kullanabilirsiniz rewordyerine pickgünlük mesajı düzenlemek için.
MitMaro

89
Bu arada, $parent_of_flawed_commiteşdeğerdir $flawed_commit^.
Peeja

67
Daha önce yukarı doğru itmişseniz, bunu ASLA asla yapmayın (veya genel olarak yeniden pazarlayın)!
Daniel Rinser

20
Kusurlu taahhütten sonra birleşme varsa -p( --preserve-merges) kullanın .
ahven

778

Önceki taahhüdü değiştirmek için, istediğiniz değişiklikleri yapın ve bu değişiklikleri hazırlayın ve ardından çalıştırın

git commit --amend

Bu, metin düzenleyicinizde yeni gönderme mesajınızı temsil eden bir dosya açar. Eski tamamlama mesajınızdaki metinle doldurulur. Teslim mesajını istediğiniz gibi değiştirin, ardından dosyayı kaydedin ve bitirmek için düzenleyicinizden çıkın.

Önceki taahhüdü değiştirmek ve aynı günlük iletisini korumak için,

git commit --amend -C HEAD

Önceki taahhüdü tamamen kaldırarak düzeltmek için çalıştırın

git reset --hard HEAD^

Birden fazla tamamlama mesajını düzenlemek istiyorsanız, çalıştırın

git rebase -i HEAD~commit_count

( Commit_count değerini , düzenlemek istediğiniz taahhüt sayısı ile değiştirin.) Bu komut düzenleyicinizi başlatır. İlk komutu (değiştirmek istediğiniz) "seçim" yerine "düzenle" olarak işaretleyin, ardından düzenleyicinizi kaydedin ve çıkın. Taahhüt etmek istediğiniz değişikliği yapın ve ardından çalıştırın

git commit --amend
git rebase --continue

Not: Ayrıca açılan düzenleyiciden "İstediğiniz değişikliği yapın" git commit --amend


18
git rebase -i HEAD~commit_countayrıca seçtiğiniz birçok taahhüdün taahhüt mesajlarını değiştirmenize izin verir. Seçilen işlemleri "al" yerine "geri sar" olarak işaretlemeniz yeterlidir.
Joe

2
Ya yeniden pazarlamak istemezseniz? Sadece eski bir mesajı mı değiştirmek istiyorsun?
SuperUberDuper

3
git reset --hardtaahhüt edilmeyen değişiklikleri yok eder. Yerine lütfen --hardile --soft.
eel ghEEz

1
Anlaşıldı, git reset --hardtamamen meşru bir komut, ancak soru göz önüne alındığında yanıltıcı. --hardTeslim mesajında ​​bir yazım hatası yaptıysanız değil, atmak istediğiniz değişiklikleri yaparsanız kullanın !
Soren Bjornstad

398

Daha önce de belirtildiği gibi, git commit --amendson taahhüdün üzerine yazmanın yolu. Bir not: dosyaların üzerine de yazmak isterseniz , komut

git commit -a --amend -m "My new commit message"

4
Her şeyi eklemek istemiyorsanız eğer, öncelikle yapabilirsiniz git add file.exttam o sıradagit commit --amend
MalcolmOcean

358

Bunun için de kullanabilirsiniz git filter-branch.

git filter-branch -f --msg-filter "sed 's/errror/error/'" $flawed_commit..HEAD

Önemsiz bir şey kadar kolay değil git commit --amend, ancak hatalı taahhüt mesajınızdan sonra zaten bazı birleşmeleriniz varsa özellikle yararlıdır.

Bunun, her işlemHEAD ve kusurlu işlem arasında yeniden yazmayı deneyeceğini unutmayın, bu yüzden msg-filterkomutunuzu çok akıllıca seçmelisiniz ;-)


4
Normal ifade hiçbir şey bulamazsa bunun taahhüdü değiştirmeyen bir sürümü var mı?
sjakubowski

3
AFAIK filtre dalı --msg-filter her durumda yeni taahhütler üretecektir. Ancak, sed'in başarılı olup olmadığını msg-filter içinde kontrol edebilir ve ağacınızı ref / orijinal değerine sıfırlamak için filtre dalı işlemi sona erdiğinde bu bilgileri kullanabilirsiniz.
Mark

4
@DavidHogue Bu yalnızca filtre dalı yöntemi kullanıldığında geçerlidir. Etkileşimli rebase'i kullanırsanız, değiştirilmiş bir kesinleştirmeyi izleyen kesinleştirme kimliği değişmez.
Mark

6
@ Mark Evet, yaparlar. Taahhüt kimlikleri önceki taahhütlere bağlıdır. Değişmezlerse git işe yaramazdı.
Miles Rout

2
İhtiyacınız var $flawed_commit^..HEAD, değil $flawed_commit..HEAD. man sayfası tarafından belirtildiği gibi: « Komut yalnızca komut satırında belirtilen pozitif referansları yeniden yazar (örn. a..b'yi geçerseniz, yalnızca b yeniden yazılır). »
Ángel

319

Bu şekilde tercih ederim:

git commit --amend -c <commit ID>

Aksi takdirde, yeni bir taahhüt kimliği ile yeni bir taahhüt olacaktır.


7
Benim için, yukarıdaki komutunuzu kullanmak aslında yeni bir taahhüt kimliği ile yeni bir taahhüt artı varsayılan bir taahhüt mesajı olarak "birleştirme dalı" diyerek ekstra bir taahhüt oluşturur.
Ocak

46
Değişiklik her zaman yeni bir taahhüt kimliği ile yeni bir taahhüt oluşturur. Taahhüt kimliği, taahhüt mesajı ve yazılan / taahhüt edilen zaman damgaları dahil, taahhüt içeriğinin SHA karmasıdır. Bu, karma çarpışmalarını kısıtlayan, aynı kimliğe sahip iki işlemin tam olarak aynı içerik, geçmiş ve benzeri ile aynı taahhütte olmasını sağlayan Git'in bir özelliğidir.
Emil Lundberg

7
Emil ile aynı fikirde. Ayrıca, dokümanları okumak - tüm "-c" nin yaptığı, git'e yeni komutunuz için varsayılan / şablon olarak hangi komutun mesajını kullanacağını söylemek gibi görünüyor. , bu yüzden belirtmenize gerek yok.
Gal

2
-cBirkaç şeyler yapar. Varsayılan olarak eski mesajı kullanır, ancak yazarlık bilgilerini de (kişi ve zaman) kopyalar. -Cmesajı düzenlemenizi istememesi dışında aynı şeyi yapar.
Joseph K. Strauss

1
@SantanuDey gibi benim için işe yaramadı. Anladımfatal: Option -m cannot be combined with -c/-C/-F/--fixup.
Andrew Grimm

312

Git GUI aracını kullanıyorsanız, Son taahhüdü değiştir adlı bir düğme vardır . Bu düğmeyi tıklattığınızda son işlem dosyalarınızı ve mesajınızı görüntüler. Sadece bu mesajı düzenlerseniz yeni bir mesaj gönderebilirsiniz.

Veya bu komutu bir konsoldan / terminalden kullanın:

git commit -a --amend -m "My new commit message"

4
Bu cevap kelimenin tam anlamıyla bu daha eski olanla aynıdır . Başka bir cevap vermeden önce mevcut cevapları kontrol ettiniz mi?
Dan Dascalescu

284

Git yeniden basmayı kullanabilirsiniz . Örneğin, bbc643cd'yi yürütmek için geri değiştirmek isterseniz,

$ git rebase bbc643cd^ --interactive

Varsayılan düzenleyicide, taahhüdünü değiştirmek istediğiniz satırda 'seç' seçeneğini 'düzenlemek' olarak değiştirin. Değişikliklerinizi yapın ve ardından

$ git add <filepattern>

Şimdi kullanabilirsiniz

$ git commit --amend

taahhüdü değiştirmek ve bundan sonra

$ git rebase --continue

önceki başkanlık görevine geri dönmek.


1
Alınan değişikliklerin etkilendiğinden emin olmak git commit --amendistiyorsanız kullanabilirsiniz git showve yeni mesajı gösterecektir.
Steve Tauber

279
  1. Yalnızca son işleme iletinizi değiştirmek istiyorsanız, şunları yapın:

    git commit --amend
    

Bu sizi metin düzenleyicinize bırakacak ve son işleme mesajını değiştirmenize izin verecektir.

  1. Son üç tamamlama mesajını veya o ana kadar tamamlama mesajlarından herhangi birini değiştirmek istiyorsanız HEAD~3, git rebase -ikomutu sağlayın:

    git rebase -i HEAD~3
    

6
Bu erken cevap zaten kullanabileceğiniz söylüyor git commit --amendve aynı zamanda kullanabileceğiniz söylüyor git rebase -i HEAD~commit_count, hem bütün halinde fiş oldu 3için commit_count.

Aşağı indirildi. İnsanlar sadece mevcut cevapları okuma zahmetine girmiyor .
Dan Dascalescu

261

Eski bir tamamlama mesajını birden çok dalda değiştirmek zorunda kalırsanız (yani, hatalı mesajla ilgili iş ayırma işlemi birden çok dalda mevcut olabilir):

git filter-branch -f --msg-filter \
'sed "s/<old message>/<new message>/g"' -- --all

Git, yeniden yazmak ve geçici olarak eski referansları yedeklemek için geçici bir dizin oluşturur refs/original/.

  • -foperasyonun yürütülmesini zorlar. Geçici dizin zaten varsa veya altında kayıtlı referanslar varsa bu gereklidir refs/original. Durum böyle değilse, bu bayrağı bırakabilirsiniz.

  • -- filtre dalı seçeneklerini düzeltme seçeneklerinden ayırır.

  • --alltüm dalların ve etiketlerin yeniden yazıldığından emin olur .

Eski referanslarınızın yedeklenmesi nedeniyle, komutu yürütmeden önce kolayca duruma geri dönebilirsiniz.

Diyelim ki ustanızı kurtarmak ve şubeye erişmek istiyorsunuz old_master:

git checkout -b old_master refs/original/refs/heads/master

3
Bu cevap OP'nin sorusunu ele almıyor, çünkü sadece yeni yaptıkları bir taahhüdü düzeltmek istiyorlar. Düzenli olarak kullandığım git commit --amendbir yorum düzeltmek ya da ben unuttum dosyaları eklemek için git add, ama sadece şimdiye ı ettik önce git pushed. git filter-branchSürüm geçmişi ile tamamen karıştırmak istediğimde de kullanıyorum , ancak OP bunu istemiyor, bu yüzden bu cevap büyük bir sağlık uyarısına ihtiyaç duyuyor - bunu evde denemeyin, gözetleme!
kbro

226

kullanım

git commit --amend

Ayrıntılı olarak anlamak için mükemmel bir gönderi 4'tür . Git Geçmişini Yeniden Yazmak . Ayrıca ne zaman kullanılmayacağından bahsediyor git commit --amend.


2
Halka açık bir depoya yönlendirilmiş taahhüt mesajlarını düzeltmenin iyi bir yolu var mı? Şimdiye kadar, bir kez ittiğimde, taahhüt mesajı yazım hataları ve düşüncelerimin sonsuza kadar yaşamak zorunda olduğu sonucuna vardım.
stackunderflow

2
Tek kelimeyle, NOPE! İttiğiniz bir şeyi geri çekmenin İYİ yolu yoktur. Tüm geri çekmeler daha büyük veya daha az derecede KÖTÜdür. Kendi özel deponuzda bir dalda çalışma disiplini benimsemelisiniz, biraz eklerken, biraz test ederken, biraz ince ayar yaparken birden fazla taahhütte bulunmalısınız. Ardından tüm şubenizi tek bir taahhütte birleştirin, genel değişikliği açıklayan yeni bir taahhüt mesajı yazın, PROOFREAD ve itin.
kbro

1
Sadece bir özellik dalından geri dönerken tek bir taahhüt yapmak zorunda olmadığı barizdir. Birçok insanın yaptığı şey, hedef dalda (şeylerin temiz görünmesini sağlamak için) yeniden tembellikten sonra hızlı iletmeyi bastırma seçeneğiyle birleşmesidir. Yine de yukarı itmeden önce dikkatli olmanın ana noktasını kabul edin.
ShawnFumo

1
git commit --amendSize ait yazmadan önce cevap zaten (birkaç kez) verilmişti. Neden tekrar yayınladın? "Git Geçmişini Yeniden Yazmak" için bir bağlantı eklemek isterseniz, mevcut yanıtlardan birini düzenleyebilir veya yorum bırakmış olabilirsiniz.
Dan Dascalescu

199

değiştirmek

Burada birkaç seçeneğiniz var. Yapabilirsin

git commit --amend

son göreviniz olduğu sürece.

Etkileşimli rebase

Aksi takdirde, son taahhüdünüz değilse, etkileşimli bir rebase yapabilirsiniz,

git rebase -i [branched_from] [hash before commit]

Sonra interaktif rebase içine sadece bu taahhüt düzenlemek ekleyin. Geldiğinde, bir git commit --amendtamamlayın ve tamamlama mesajını değiştirin. Bu işlem noktasından önce geri almak isterseniz, bu işlemi de kullanabilir git reflogve silebilirsiniz. Sonra git committekrar yap.


191

Bu sizin son taahhüdünüzse, taahhüdü değiştirin :

git commit --amend -o -m "New commit message"

( Yalnızca gönderme mesajını değiştirdiğinizden emin olmak için -o( --only) bayrağını kullanarak)


Gömülü bir taahhütse, müthiş etkileşimli rebase'i kullanın :

git rebase -i @~9   # Show the last 9 commits in a text editor

İstediğiniz değişikliği işlemek bul pickiçin r( reword) ve kaydetmek ve yakın dosyası. Bitti!



Minyatür Vim öğreticisi (veya yalnızca 8 tuş vuruşuyla nasıl yeniden başlayacağınız 3jcwrEscZZ):

  • vimtutorZamanın varsa koş
  • hjkl hareket tuşlarına karşılık gelir
  • Tüm komutların önüne "aralık" eklenebilir, örn. 3jÜç satır aşağı gider
  • i ekleme moduna girmek için - yazdığınız metin dosyada görünecektir
  • Escveya Ctrlcekleme modundan çıkmak ve "normal" moda dönmek için
  • u geri almak
  • Ctrlr yeniden yapmak
  • dd, dw, dlSırasıyla bir çizgi, kelime veya harfi silmek için
  • cc, cw , clSırasıyla bir çizgi, kelime ya da harf değiştirmek (aynı ddi)
  • yy, yw , ylSırasıyla ( "yank") bir çizgi, kelime veya harf kopyalamak
  • p veya P sırayla veya mevcut konumdan önce yapıştırmak için
  • :wEnter bir dosyayı kaydetmek (yazmak)
  • :q!Enter kaydetmeden çıkmak
  • :wqEnter veya ZZ kaydetmek ve çıkmak

Metni çok düzenlerseniz , Dvorak klavye düzenine geçin, dokunma türünü öğrenin ve Vim öğrenin. Çabaya değer mi? Evet.



ProTip ™: Geçmişi yeniden yazan "tehlikeli" komutları denemekten korkmayın * - Git varsayılan olarak 90 gün boyunca taahhütlerinizi silmez; Bunları reflogda bulabilirsiniz:

$ git reset @~3   # Go back three commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* Gibi --hardve --forceolsa seçenekleri dikkat - veri atabilir. * Ayrıca, birlikte çalıştığınız dallarda geçmişi yeniden yazmayın.


3
Vim bölümü tamamen konu dışıdır ve kullanıcıları bir gizli düzenleyiciyi kullanmayı öğrenmek için zaman harcamaya teşvik etmek yerine, neden onlara varsayılan git düzenleyiciyi kullanıcı dostu bir şey olarak ayarlama gibi nano? Bir metin dosyasına yapılması gereken önemsiz değişikliklerden bahsediyoruz, "en iyi" metin editörü hakkında alev savaşı oluşturacak hardcore kodlamadan değil.
Dan Dascalescu

1
@DanDascalescu: Çünkü yukarıdaki talimatları kullanarak Vim'i öğrenmek nano kullanarak birkaç yeniden basma yapmaktan daha hızlı. Git'in bir metin düzenleyicisini açmasının ve yeniden bastırma için kendi arabiriminin değil, tüm nedeni Vim'in mevcut olması: hafiftir, çoğu sistemde varsayılan olarak yüklüdür ve kolaylıkla bir rebase gerçekleştirmek için yeterince öğrenmesi çok kolaydır: örneğin ddjjpZZbir taahhüt 2'yi aşağı taşır. Temel Vim bilgisi hakkında hiçbir sır yoktur; Vim ile nano'dan daha rahat olmak 10 dakika sürer.
Zaz

185

Git GUI'sini kullanıyorsanız, itilmemiş son taahhüdü değiştirebilirsiniz:

Commit/Amend Last Commit

168

Git GUI'yi olabildiğince çok kullanıyorum ve bu size son taahhüdü değiştirme seçeneği sunuyor:

Bu kutuyu işaretleyin

Ayrıca, git rebase -i origin/masterher zaman ustanın üstünde yaptığınız taahhütleri sunacak ve size değişiklik yapma, silme, yeniden sıralama veya ezme seçeneği sunan güzel bir mantra. İlk önce bu hash'ı ele geçirmeye gerek yok.


4
Örneğinizde görüntülediğiniz ekrana nasıl ulaşabilirim?
Marwan مروان

2
Windows Git Gui'nin sağ alt kısmı. 'Son Değişikliği Değiştir' geçişini seçmeniz yeterlidir; en son taahhüt bilgileriyle doldurulur.
wbdartarafından

138

Vay canına, bunu yapmanın birçok yolu var.

Bunu yapmanın başka bir yolu da son taahhüdü silmek, ancak işinizi kaybetmemek için değişikliklerini korumaktır. Daha sonra düzeltilmiş mesajla başka bir işlem yapabilirsiniz. Bu şöyle görünecektir:

git reset --soft HEAD~1
git commit -m 'New and corrected commit message'

Bir dosya eklemeyi veya bir değişiklik yapmayı unutursam bunu her zaman yaparım.

--softBunun yerine belirtmeyi unutmayın--hard , aksi takdirde bu taahhüdü tamamen kaybedersiniz.


5
Bu, git commit --amend2 adımlı bir işlem olması dışında tam olarak aynı şeyi yapar .
Joseph K. Strauss

3
@ JosephK.Strauss Taahhüdün değiştirilmesinin orijinal komite yazarı ve tarih bilgisini, yeni komite ve tarih bilgisini ayrı ayrı tuttuğuna inanıyorum. Bu yaklaşımın bunu yaptığından emin değilim.
everton

4
@EvertonAgner Doğru. --amendyazar bilgilerini tutacaktır, ancak soru yalnızca iletiyi değiştirmenizi ister.
Joseph K. Strauss

131

Eski mesajları düzenlemeye yardımcı olacak bir Windows / Mac GUI arayan herkes için (yani sadece en son mesaj değil), Sourcetree'yi tavsiye ederim . İzlenecek adımlar aşağıdadır.

Sourcetree etkileşimli rebase

Henüz uzaktan kumandaya itilmemiş olan taahhütler için:

  1. Geçerli tüm değişiklikleri yaptığınızdan veya sakladığınızdan emin olun (yani, "Dosya Durumu" sekmesinde listelenen dosya yoktur) - aksi takdirde çalışmaz.
  2. "Günlük / Geçmiş" sekmesinde, grafikte düzenlemek istediğiniz taahhütlerin altında bir bitişik çizgiye sahip girişi sağ tıklayın ve " < ... etkileşimli"
  3. Değiştirmek istediğiniz bir taahhüt mesajı için tüm satırı seçin ("Mesaj" sütununu tıklayın) .
  4. "Mesajı Düzenle" düğmesini tıklayın.
  5. Açılan iletişim kutusunda mesajı istediğiniz gibi düzenleyin ve ardından Tamam OK .
  6. Değiştirilecek başka taahhüt mesajları varsa 3-4 arasındaki adımları tekrarlayın.
  7. Tıklama OK: Yeniden inceleme başlayacak. Her şey yolundaysa, çıktı "Başarıyla tamamlandı" olarak sona erecektir. Not: bazen Unable to create 'project_path/.git/index.lock': File exists.aynı anda birden çok taahhüt iletileri değiştirmeye çalışırken bu başarısız gördüm . Sorunun tam olarak ne olduğundan veya Sourcetree'nin gelecekteki bir sürümünde düzeltilip düzeltilmeyeceğinden emin değilim, ancak bu gerçekleşirse bunların birer birer yeniden baslanmasını öneriyoruz (daha yavaş ama daha güvenilir görünüyor).

... Veya ... zaten itilmiş olan taahhütler için:

Yukarıdakine benzer olan, ancak dalı zorla itmek için komut satırından ( ) başka bir komutun çalıştırılmasını gerektiren bu yanıttaki adımları izleyin git push origin <branch> -f. Hepsini okumanızı ve gerekli önlemleri almanızı öneririm!


tüm cevaplar dışında - bu tüm git yeni başlayanlar için en uygun olan ^ ^ ^ (ücretsiz bir program SourceTree kullanın ve düzenlemek istediğinizden önce bir taahhütte "Rebase çocuk" uygulayın
5

127

Yalnızca en son taahhüdü düzenlemek istiyorsanız şunu kullanın:

git commit --amend

veya

git commit --amend -m 'one line message'

Ancak, art arda birkaç işlem düzenlemek istiyorsanız, bunun yerine yeniden basma özelliğini kullanmalısınız:

git rebase -i <hash of one commit before the wrong commit>

Git rebase düzenleme

Bir dosyaya, yukarıdaki gibi, şunu yazın edit/e diğer seçeneklerden birini veya kaydet ve çık'a basın.

Şimdi ilk yanlış işlemde olacaksın. Dosyalarda değişiklik yapın, bunlar sizin için otomatik olarak hazırlanır. tip

git commit --amend

Kaydedip çıkın ve yazın

git rebase --continue

tüm seçimleriniz bitene kadar bir sonraki seçime geçmek için.

Bu şeylerin, söz konusu taahhütten sonra tüm SHA karma değerlerini değiştirdiğini unutmayın.


2
git rebase -i <yanlış işlemden önce bir işlemin karması> benim için çalışıyor. Teşekkürler.
Viraths

127

Yalnızca son mesajı değiştirmek isterseniz kullanmanız gereken --onlybayrak veya kısayol -oile commit --amend:

git commit --amend -o -m "New commit message"

Bu, aşamalı şeylerle olan bağlılığınızı yanlışlıkla artırmamanızı sağlar. Tabii ki uygun bir $EDITORkonfigürasyona sahip olmak en iyisidir . Daha sonra -mseçeneği dışarıda bırakabilirsiniz, Git tamamlama mesajını eskisiyle doldurur. Bu şekilde kolayca düzenlenebilir.


1
"Üst" cevap soruyu cevaplamıyor. Sadece genel bir giriş yapar git commit --amend. Soru çok spesifikti, bu yüzden daha uzun! = Daha iyi. -oBayrağın kesin olarak belirtilmesi muhtemelen bilgilerin geri kalanına gömülecektir. Ben de şimdiden çok oy alan bir cevabı düzenlemekte rahat değilim.
David Ongaro

2
İnsanların bunu "doğru" cevap olarak kullanma konusunda gerçek bir tehlike olduğu için, en iyi cevabı düzenlemekte özgür olduğunuz söyleniyor. Aşamalı şeylerle olan taahhüdünüzü kolayca değiştirmek mümkün olabilir - bu bana oldu ve bunu zorladığınızda gerçekten sinir bozucu. Ama yine de, miktar doğruluk için bir garanti değildir. Ne cevap sayısı ne de oy sayısı.
David Ongaro

1
Şimdiye kadar en üstteki cevabın "yanlış" olduğunu ve "soruyu cevaplamadığını" söyleyemem. Kesinlikle işe yarar ve soruyu cevaplar, sadece değiştirmeye çalıştığınızda aşamalı değişikliklerin olmadığından emin olmanız gerekir. Ama insanları bu konuda uyarmak zorunda olduğunuzu anlıyorum. Zamanım olursa daha sonra düzenleyeceğim.

1
Adil olmak gerekirse: git 1.3.0'dan beri olan --onlyseçenek --amendmevcut olsa da 1.7.11.3'te ( ea2d4ed35902ce15959965ab86d80527731a177c ) düzeltilinceye kadar doğru çalışmadı . Yani 2008 yılında doğru cevabı geri muhtemelen böyle bir şey olurdu: git stash; git commit --amend; git stash pop.
David Ongaro

103

Son yanlış işlem mesajınızı tek bir satırdaki yeni işlem mesajıyla güncelleyin:

git commit --amend -m "your new commit message"

Veya Git sıfırlamayı aşağıdaki gibi deneyin:

# You can reset your head to n number of commit
# NOT a good idea for changing last commit message,
# but you can get an idea to split commit into multiple commits
git reset --soft HEAD^

# It will reset you last commit. Now, you
# can re-commit it with new commit message.

İşlemleri daha küçük işlemlere ayırmak için sıfırlama özelliğini kullanma

git reset bir taahhüdü birden fazla taahhütte kırmanıza yardımcı olabilir:

# Reset your head. I am resetting to last commits:
git reset --soft HEAD^
# (You can reset multiple commit by doing HEAD~2(no. of commits)

# Now, reset your head for splitting it to multiple commits
git reset HEAD

# Add and commit your files separately to make multiple commits: e.g
git add app/
git commit -m "add all files in app directory"

git add config/
git commit -m "add all files in config directory"

Burada son taahhüdünüzü iki taahhütte başarıyla kırdınız.


3
Tek yapmanız gereken son taahhüdünüzün mesajını düzenlemekse, bu amaçla yumuşak bir sıfırlama kullanmak aşırı öldürmedir . Sadece git commit --amend, en çok oy alan cevapta nasıl söylediği gibi kullanın . Ayrıca, bu ilk yanıttagit reset --soft HEAD^ yazılım sıfırlamasıyla aynı şekilde çalışır , çünkü her ikisi de ilk üst öğeye geri döner.

3
Ben sadece git resetbir taahhüt mesajı birden fazla taahhüt mesajları bölmek için bir fikir vermek için çözüm eklemek için zahmet . Çünkü kullanmaya başladığımda bu problemle karşılaştım git. Bazen, bu gerçekten yardımcı olabilir. :)
przbadu

87

Bu soruda çok fazla cevap var, ancak hiçbiri Vim kullanarak eski taahhüt mesajlarının nasıl değiştirileceğini süper ayrıntılı olarak açıklamıyor . Bunu kendim yapmaya çalışıyordum, bu yüzden bunu özellikle Vim'de deneyimi olmayan insanlar için nasıl yaptığımı ayrıntılı olarak yazacağım!

Sunucuya aktardığım en son beş taahhüdümü değiştirmek istedim. Bu oldukça 'tehlikelidir' çünkü bir başkası bundan çekilirse, taahhüt mesajlarını değiştirerek işleri karıştırabilirsiniz. Ancak, kendi küçük dalınız üzerinde çalışırken ve hiç kimsenin onu çekmediğinden emin olduğunuzda, bunu şu şekilde değiştirebilirsiniz:

Diyelim ki en son beş taahhüdünüzü değiştirmek istiyorsunuz ve bunu terminalde yazıyorsunuz:

git rebase -i HEAD~5

* Burada 5, değiştirmek istediğiniz işlem mesajı sayısıdır (bu nedenle, 10. işlemin son işlemeyi değiştirmek istiyorsanız, 10 yazarsınız).

Bu komut sizi Vim'e götürecek ve işlem geçmişinizi 'düzenleyebilirsiniz'. Son beş işleminizi en üstte şu şekilde göreceksiniz:

pick <commit hash> commit message

Bunun yerine pickyazmanız gerekiyor reword. Bunu yazarak Vim'de yapabilirsiniz i. Bu, ekleme moduna geçmenizi sağlar. ( Altta INSERT kelimesi ile ekleme modunda olduğunuzu görüyorsunuz .) Değiştirmek istediğiniz taahhütler için, rewordyerine şunu yazınpick .

Ardından bu ekranı kaydetmeniz ve çıkmanız gerekir. Bunu önce Escdüğmesine basarak 'komut kipine' girerek yaparsınız (alttaki INSERT kelimesi kaybolmuşsa komut kipinde olduğunuzu kontrol edebilirsiniz ). Sonra yazarak bir komut yazabilirsiniz :. Kaydetme ve çıkma komutu wq. Yani :wqyazdığınızda doğru yoldasınız demektir.

Sonra Vim, yeniden yazmak istediğiniz her taahhüt mesajının üzerinden geçecektir ve burada taahhüt mesajlarını değiştirebilirsiniz. Bunu ekleme moduna girerek, tamamlama mesajını değiştirerek, komut moduna girerek kaydedip çıkın. Bunu beş kez yapın ve Vim'iniz bitti!

Daha sonra, yanlış taahhütlerinizi zaten ittiyseniz, git push --forcebunların üzerine yazmanız gerekir . Bunun git push --forceoldukça tehlikeli bir şey olduğunu unutmayın , bu yüzden yanlış taahhütlerinizi ittiğinizden kimsenin sunucudan çekilmediğinden emin olun!

Şimdi tamamlama mesajlarınızı değiştirdiniz!

(Gördüğünüz gibi, Vim'de deneyimli değilim, bu yüzden ne olduğunu açıklamak için yanlış 'lingo' kullanırsam, beni düzeltmekten çekinmeyin!)


4
<nitpick>Stack Overflow'da "konu" yoktur, çünkü bu bir tartışma forumu değildir, yalnızca "sorular", "cevaplar" ve "gönderiler" vardır. </nitpick>. Ayrıca, Vim'in tüm sürümleri aynı değildir, hepsi ekleme modunda karakterleri silmenize izin vermez (bir şekilde mantıklı, değil mi?). Vim'deki karakterleri her zaman silmek istiyorsanız Xve xbunu yapacaksanız ( ximlecin önündeki karakterleri çok az siler, Xarkasından silinir). Hata yaparsanız, ugeri almak için tekrar tekrar kullanabilirsiniz . Son olarak, etkileşimli rebase editörü riçin kısayol reword.

1
Vim'deki bir kelimeyi değiştirmek için cwbaşında yazılır (soru vim ile ilgili olmasa da, katılıyorum).
Yaroslav Nikitenko

Bu iğrençliği kullanmanıza gerek yok . Sen edebilirsiniz senin git editörü ayarlamak şey aklı başında ve kullanıcı dostu, benzerine nanoveya Midnight Komutanın mcedit.
Dan Dascalescu

79

Sen kullanabilirsiniz git-Rebase-reword

Herhangi bir taahhüdü (sadece son değil) aynı şekilde düzenlemek için tasarlanmıştır commit --amend

$ git rebase-reword <commit-or-refname>

Bu bir taahhüt değiştirmek için etkileşimli rebase eyleminden sonra adlandırılır: "geri sarma". Bu gönderiye bakın ve insan- bölüm etkileşimli modu-

Örnekler:

$ git rebase-reword b68f560
$ git rebase-reword HEAD^

6
Bunun için harici bir programın yüklenmesi gerekir. Bence, yerleşik araçları ve takma adları daha etkili kullanmayı öğrenmek daha iyi olurdu. : Ben yazarsınız g c; g rb -i @~9, yeni ben istediğiniz yere taahhüt değişiklik taşıyın (işlemek ve Rebase) commitiçin f( fixup) ve kaydedin. Bundan daha hızlı bir şey istiyorsanız, takma ad olabilir git commit --fixup=<commit>; git rebase -i --autosquash <commit>^
Zaz

79

Ben takma adlar eklemiş recive recmiçin recommit (amend)o. Şimdi git recmveya ile yapabilirim git recm -m:

$ vim ~/.gitconfig

[alias]

    ......
    cm = commit
    reci = commit --amend
    recm = commit --amend
    ......

57

İçinde bir yazım hatası olan bir taahhütte bulunduğumu fark ettim. Geri almak için aşağıdakileri yaptım:

git commit --amend -m "T-1000, advanced prototype"
git push --force

Uyarı: Değişikliklerinizi zorla zorlamak, uzak dalın yerel şubeniz üzerine yazılmasına neden olur. Saklamak istediğiniz hiçbir şeyin üzerine yazmayacağınızdan emin olun. Ayrıca, başka bir kişi sizinle şubeyi paylaşırsa, değiştirilmiş (yeniden yazılmış) bir taahhüdü zorlama konusunda dikkatli olun, çünkü az önce yazdığınız taahhüdün eski kopyasına sahiplerse kendi tarihlerini yeniden yazmaları gerekir.


7
Git'te hiçbir şey "üzerine yazılmaz". Bu durumda, şube işaretçisi yeni taahhüdünüze ayarlanır ve ona hiçbir referans kalmazsa eski taahhüt eski olur ve birkaç hafta sonra temizlenebilir. (O zamana kadar diğerleri hala bulabilir ve referans verebilir, örneğin reflog'a bakarak).
David Ongaro

51

Aşağıdakileri kullanmayı seviyorum:

  1. git status
  2. git add --all
  3. git commit -am "message goes here about the change"
  4. git pull <origin master>
  5. git push <origin master>

46

Kodu uzak şubenize ( GitHub / Bitbucket ) göndermediyseniz, komut satırındaki yürütme iletisini aşağıdaki gibi değiştirebilirsiniz.

 git commit --amend -m "Your new message"

Belirli bir dal üzerinde çalışıyorsanız bunu yapın:

git commit --amend -m "BRANCH-NAME: new message"

Kodu zaten yanlış mesajla ittiyseniz ve mesajı değiştirirken dikkatli olmanız gerekir. Yani, taahhüt mesajını değiştirip tekrar göndermeyi denedikten sonra, sorun yaşarsınız. Düzgünleştirmek için aşağıdaki adımları izleyin.

Lütfen yapmadan önce tüm cevabımı okuyun.

git commit --amend -m "BRANCH-NAME : your new message"

git push -f origin BRANCH-NAME                # Not a best practice. Read below why?

Önemli not: Force Push'u doğrudan kullandığınızda, diğer geliştiricilerin aynı dalda çalıştığı kod sorunlarıyla karşılaşabilirsiniz. Bu nedenle, bu çatışmalardan kaçınmak için, zorlamayı zorlamadan önce kodu şubenizden almanız gerekir :

 git commit --amend -m "BRANCH-NAME : your new message"
 git pull origin BRANCH-NAME
 git push -f origin BRANCH-NAME

Bu, önceden iletilmişse, tamamlama mesajını değiştirirken en iyi uygulamadır.

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.