Git'te daha eski (son olmayan) bir işleme değiştirilen dosya nasıl eklenir


461

Son bir saat içinde birkaç şeyi değiştirdim ve bunları adım adım taahhüt ettim, ancak birkaç dakika önce değiştirilen bir dosyayı eklemeyi unuttuğumu fark ettim.

Günlük şöyle görünür:

    GIT TidyUpRequests u:1 d:0> git log 
    commit fc6734b6351f6c36a587dba6dbd9d5efa30c09ce 
    Author: David Klein <> 
    Date:   Tue Apr 27 09:43:55 2010 +0200

        The Main program now tests both Webservices at once

    commit 8a2c6014c2b035e37aebd310a6393a1ecb39f463 
    Author: David Klein <>
    Date:   Tue Apr 27 09:43:27 2010 +0200

        ISBNDBQueryHandler now uses the XPath functions from XPath.fs too

    commit 06a504e277fd98d97eed4dad22dfa5933d81451f 
    Author: David Klein <> 
    Date:   Tue Apr 27 09:30:34 2010 +0200

        AmazonQueryHandler now uses the XPath Helper functions defined in XPath.fs

    commit a0865e28be35a3011d0b6091819ec32922dd2dd8 <--- changed file should go here
    Author: David Klein <> 
    Date:   Tue Apr 27 09:29:53 2010 +0200

        Factored out some common XPath Operations

Herhangi bir fikir?


Yanıtlar:


694

Kullanın git rebase. özellikle:

  1. git stashEklemek istediğiniz değişiklikleri saklamak için kullanın .
  2. Kullanın git rebase -i HEAD~10(veya görmek istediğiniz birçok taahhüt geri gelir).
  3. Satırın başlangıcındaki a0865...kelimeyi değiştirerek söz konusu taahhüdü ( ) düzenlemek için işaretleyin . Taahhütleri sileceği için diğer satırları da silmeyin. [^ Vimnote]pickedit
  4. Rebase dosyasını kaydedin, git kabuğa geri döner ve bu işlemi düzeltmenizi bekler.
  5. Kullanarak saklamak pop git stash pop
  6. İle dosyanızı ekleyin git add <file>.
  7. Taahhüdünü değiştirin git commit --amend --no-edit.
  8. Bir Do git rebase --continueyenisiyle karşı kaydedilmesini geri kalanını yeniden hangi.
  9. Düzenleme için birden fazla taahhütte bulunduysanız 2. adımdan itibaren tekrarlayın.

[^ vimnote]: Kullanıyorsanız , düzenlemek vimiçin Inserttuşa basmanız ve ardından dosyayı kaydetmek için Escyazmanız :wq, düzenleyiciden çıkmanız ve değişiklikleri uygulamanız gerekir. Alternatif olarak, kullanıcı dostu bir git komut editörü ile yapılandırabilirsinizgit config --global core.editor "nano" .


23
Düzenlemeye eklemek istediğiniz dizginsiz değişiklikleriniz varsa ne olur? Eğer onları saklarsam, yapamazdım git add.
Sam

15
Sam sadece söz konusu taahhütte iken değişiklikleri kaldırabilirsiniz, iyi çalışır.
omnikron

17
Not: Taahhüdü işaretlediğinizde edit, dosyada listelenen diğer taahhütleri SİLMEYİN. Bunu yaparsanız, taahhütler silinir ve geri almak için bu adımları izlemeniz gerekir.
David Tuite

2
@DavidTuite ne dedi ile ilgili, git üzerinde bir şeyler yaparken benim alışkanlık nasıl ortaya çıkacağından emin değilim ben şeyler berbat durumda zaman çizelgesinin mevcut durumunu kaydetmek için bir "branchname-ref" şube oluşturmaktır. İşimi bitirdiğimde silerim.
Raphael

1
6. adımda,. (dot) komutunu girin. Doğru komut:git add .
Tom

324

Taahhüt eski mesajını işlemek değiştirmeden "düzeltme" Kime eski, küçük bir değişiklik ile taahhüt, nerede OLDCOMMITgibi bir şey 091b73a:

git add <my fixed files>
git commit --fixup=OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^

Yeniden git commit --squash=OLDCOMMITbaşlatma sırasında eski tamamlama mesajını düzenlemek için de kullanabilirsiniz .


  • git rebase --interactiverebase yönerge sırasını onaylamak (veya düzenlemek) için bir metin düzenleyici ( yapılandırılabilir ) getirir . Dosyada rebase talimatı değişiklikleri için bilgi var ; Sadece kaydedip çıkın (editör içinde rebase devam etmek).:wqvim
  • --autosquash--fixup=OLDCOMMITtaahhütleri otomatik olarak istenen sıraya koyacaktır . Bunun --autosquashyalnızca --interactiveseçenek kullanıldığında geçerli olduğunu unutmayın .
  • Bu ^, daha OLDCOMMIT^önce taahhüt için bir referans olduğu anlamına gelir OLDCOMMIT.

Yukarıdaki adımlar rebase talimat sırasını doğrulamak ve / veya değiştirmek için iyidir , ancak etkileşimli rebase metin düzenleyicisini atlamak / otomatikleştirmek de mümkündür:

Bkz. Git commit ve git rebase . Her zaman olduğu gibi, git geçmişini yeniden yazarken, yalnızca başkalarına henüz yayınlamadığınız (rastgele internet kullanıcıları ve oluşturma sunucuları dahil) düzeltme veya squash taahhütlerini kullanmalısınız.


18
Diğer seçeneklerden çok daha net ve bir cazibe gibi çalıştı
Chris Mitchelmore

5
@Jonah: Editör, tamamlama mesajını düzenlemek için açılmaz , ancak rebase adımlarını onaylar (veya düzenler) . Önlenemez; --autosquashyalnızca --interactiveseçenek kullanıldığında geçerlidir .
Joel Purra

5
Bu çözümü kullanarak git VIM göstermek sıkışmış. Benim sorunum, VIM'in nasıl kullanılacağını bilmiyorum. Bundan nasıl çıkarım, bu şeyi nasıl kontrol edebilirim, bu çok kafa karıştırıcı.
Neon Warge

2
@NeonWarge: seçilen düzenleyici, örneğin kullanılarak yapılandırılabilir git config --global core.editor "pico". Orada sisteminizin varsayılan editör değiştirmek yapılandırmak Git ve / veya birkaç başka yollar değerine vb.
Joel Purra

2
bir satır güzel takma ad burada
idanp

61

git 1.7 ile kullanmanın gerçekten kolay bir yolu var git rebase:

dosyalarınızı hazırlayın:

git add $files

"kırık" taahhüdünüzü yeni bir taahhüt oluşturun ve yeniden kullanın taahhüt mesajı

git commit -c master~4

fixup!konu satırının başına (veya squash!kesinliği (iletiyi) düzenlemek istiyorsanız):

fixup! Factored out some common XPath Operations

git rebase -i --autosquashtaahhüdünüzü düzeltmek için kullanın


2
+1. Yeni düzeltme yönergesinin güzel kullanımı (1.7+): stackoverflow.com/questions/2302736/trimming-git-checkins/…
VonC

@knittl Benim eski bir taahhüt (itti değil) başka bir dosya eklemek için yöntem deniyordu ama basma aldığımda You asked me to rebase without telling me which branch you want to rebase against, and 'branch.master.merge've sonra kullanırsanız git rebase -i --autosquashben sadece bir noopkonu satırı alıyorum , taahhüt kendi üzerine. Ne yaptığımı biliyor musun?
oschrenk

7
@oschrenk: Rebase yapmak istediğiniz bir taahhüt vermeniz gerekiyor, örneğingit rebase -i --autosquash HEAD~10
knittl

1
İyi cevap ama aynı zamanda yeniden pazarlanacak bir taahhüt eklemem gerekiyordu. Güncellemek eğer harika olurdu.
Paul Odeon

@PaulOdeon: Sorunu anlamıyorum. Ne yapmaya çalışıyorsunuz ve nerede sorun yaşıyorsunuz?
knittl

8

Bir deneyebilirsiniz rebase --interactivedeğiştirme oturumu senin eski işlemek (sağlanan zaten itmek vermedi başka repoya bu teslimleri).

Bazen b.2'de düzeltilen şey. düzelttiği mükemmel olmayan bir komuta değiştirilemez, çünkü bu taahhüt bir yama serisine derinlemesine gömülür .
Etkileşimli rebase tam olarak budur: bol miktarda "a" ve "b" den sonra, taahhütleri yeniden düzenleyerek ve düzenleyerek ve çoklu taahhütleri bir araya getirerek kullanın.

Olduğu gibi tutmak istediğiniz son işlemle başlayın:

git rebase -i <after-this-commit>

Mevcut şubenizdeki tüm taahhütlerle (birleştirme taahhütlerini göz ardı ederek) verilen bir taahhütten sonra bir editör çalıştırılacaktır.
Bu listedeki taahhütleri kalbinizin içeriğine göre yeniden sıralayabilir ve kaldırabilirsiniz. Liste aşağı yukarı böyle görünüyor:

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

Oneline açıklamaları sadece sizin zevkiniz içindir; git rebase onlara bakmayacak, ancak taahhüt adlarına (bu örnekte "deadbee" ve "fa1afe1") bakacak, bu nedenle adları silmeyin veya düzenlemeyin.

"Pick" komutunu "edit" komutuyla değiştirerek, git rebase'in söz konusu komutu uyguladıktan sonra durmasını söyleyebilir, böylece dosyaları ve / veya taahhüt mesajını düzenleyebilir, taahhüdü değiştirebilir ve yeniden baslamaya devam edebilirsiniz .

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.