2014-11-17 18 views
31

Bir dizi işlemden geçmek ve her birinde bir kabuk komutu yapmak istiyorum. Eğer komut başarısız olursa, yürüyüşün durmasını istiyorum, aksi halde devam et. filter-branch numaralı telefonu inceledim, ancak komisyonları yeniden yazmak istemiyorum, sadece onları kontrol et. for-each-ref, harekete geçecek bir aralık belirtmenize izin vermiyor gibi görünüyor.Git Her bir işlem için kabuk komutunu çalıştır

Sorunum, bir sürü taahhüt oluşturduğum ve her bir işlemin oluşturulmasını sağlamak istediğimdi. Ben böyle bir şey yapmak istiyorum: Tabii bunu yapmanın bir shell script yazabilirsiniz

git foreach origin/master..master 'git submodule update && make clean && make' 

ama git yapmak için güzel bir yol olabilir bu tür bir şey gibi görünüyor.

+0

Python'u kullanmayı düşündünüz mü? Belki GitPython bir çözüm olabilir. Bu gönderiyi kontrol edin: http://stackoverflow.com/questions/1456269/python-git-module-experiences – kmundnic

+0

Orijinin/ustanın iyi olduğunu ve ustanın kötü olduğunu (veya tersini) biliyor musunuz, yoksa sadece test etmeye mi çalışıyorsunuz? Belirli bir yerde bir başarısızlık olduğunu bilmeden aralarında her şey var mı? –

+0

@CharlesDuffy, ikincisi. Bir çalışma noktasından başladım ve işe yarayan bir dizi değişiklik yaptım. Daha sonra, işten çıkarılmayan çalışma değişikliklerinin yığınından çok sayıda ince kıymetli taahhüt yaptım ve aradaki tüm taahhütlerin oluşturulabilir olmasını sağlamak istiyorum. – FazJaxton

cevap

38

ile kullanabilirsiniz.

git rebase -i --exec <build command> <first sha you want to test>~ 

nihai tarihinin taahhüt oluşturarak her satırdan sonra "exec" ekleyin --exec. bir veya daha fazla kabuk komutları olarak yorumlanacaktır.

Düzenleri yeniden düzenlemek ve düzenlemek genellikle test edilmemiş ara ürün olan adımları oluşturur. Tarih düzenlemenizin bir testi çalıştırarak ya da "exec" komutunu (kısayol "x") kullanarak tarihteki noktalarında en azından yeniden derlenerek herhangi bir şey yapamayacağını kontrol etmek isteyebilirsiniz.

Bir komut başarısız olduğunda (yani olmayan 0 durumundan çıkar) etkileşimli yeniden başlatma, sorunu düzeltmek için bir fırsat vermek üzere duracaktır.

+0

Git sürümü 1.7 ile sıkışmış durumdayım.10 --exec komut satırı seçeneğine sahip değil, bunun yerine her bir komut komutundan sonra "x make" kelimesini manuel olarak ekledim ve bir işlem yaptı. Teşekkürler. –

+0

Ayrıca, rebase'in aralığı birleştirme içeriyorsa, buna ek olarak '-p' &' --preserve-merges 'seçeneğine de ihtiyacınız olabilir. – Unapiedra

+0

Sonunda ne yararı var? –

16

Muhtemelen rev-list.

#!/usr/bin/env bash 
# test_commits.sh 

while read -r rev; do 
    git checkout "$rev" 
    if ! git submodule update && make clean && make; then 
     >&2 echo "Commit $rev failed" 
     exit 1 
    fi 
done < <(git rev-list "$1") 

Sonra Bir exec seçeneği ile interaktif rebase kullanabilirsiniz

./test_commits.sh origin/master..master 
+4

Dize bölme ve glob genişlemesini önlemek için daha fazla tırnak gerekiyor. '' $ 1 '',' $ $' ', vb.' Rev-rev-rev 'i okurken,-git rev-list' 'den gelen tüm çıktıları toplayıp, onları tekrarlamak daha fazla ön gecikme anlamına gelir; yap ...; Tüm akışı derlemek ve ön ayrıştırmaktan ziyade, içeriği okudukları haliyle okuyan <<(git "$ 1" git listesi). (Bu yaklaşım, açık nedenlerle, çok büyük revizyon listeleri ile daha fazla bellek verimli). –

+2

(Bu, kabuk en iyi uygulamaları etrafında geliştirme için bir yer olsa da, bu kesinlikle burada en iyi cevap, ve benim +1) dedi. –

+0

@CharlesDuffy - Bir listenin içeriğini okurken bu şekilde yayınlamanın yolunu hiç bilmiyordum - teşekkürler! –

1

xargs kullanarak havalı tek liner.

git rev-list @{upstream}..HEAD | xargs -n1 -I{} sh -c 'git checkout {} && git submodule update && make clean && make' 
+0

Geri gitmek istediğiniz yere bağlı olarak, daha önce bir çöp kutusu oluşturmak istemiyorsanız, '.git/logs/HEAD '' i yedeklemeniz iyi olur. – CDanU

İlgili konular