Git Stash'ı iş akışı olarak antipattern kullanıyor musunuz?


25

Geçenlerde ben ve ekibimin Git'i nasıl kullandığını ve iş akışımızın nasıl çalıştığını inceledim. Şu anda iyi işleyen bir özellik dalı iş akışı kullanıyoruz.

Ayrıca ekibimizdeki bazı kişilerin git stash'a dayanan iş akışı kullandığını gördüm . İş akışı şöyle bir şeye gider:

  • Ana dalda çalışmak (gibi master)
  • Gittiğiniz gibi taahhütte bulunun
  • Değişiklik yapmanız veya dallarınızı değiştirmeniz gerekirse
  • Güncellemeniz bittiğinde, değişiklikleri depodan çıkarın.

Bu iş akışının bir özellik dalı iş akışı yerine kullanıldığından bahsetmeliyim . Bir dal almak ve üzerinde çalışmak yerine, buradaki geliştiriciler yalnızca tek bir dalda çalışır ve uygun gördükleri şekilde yığını kaldır / çıkar.

Aslında bunun harika bir iş akışı olduğunu düşünmüyorum ve dallanma, bu şekilde git stash kullanmaktan daha uygun olacaktır. Git stash'ın değerini acil durum operasyonu olarak görebiliyorum, ancak günlük, düzenli bir iş akışında kullanmamak için.

Git stash'ı düzenli olarak kullanmak anti-pattern olarak kabul edilir mi? Eğer öyleyse, ortaya çıkabilecek bazı özel problemler nelerdir? Eğer değilse, faydaları nelerdir?


2
İş arkadaşlarınıza iş akışıyla ilgili herhangi bir sorun yaşayıp yaşamadıklarını sormayı deneyebilirsiniz. Onlar olmasaydı o zaman zararlı olarak düşünmezdim.
AlexFoxGill

@AlexG Bu geçerli bir nokta. Buradaki soruyu sordum, insanların bulduğu "gotchas" olup olmadığını görmek için.
joshin4colours

3
Eğer doğru anlarsam ... If you need to get changes or switch branches, push your uncommitted changes onto the stash- tam olarak bunun için saklıyorsun.

3
@MichaelT Yerel şubem herşeye izin veriyor. Kayıtsız şartsız.
maaartinus

2
Şablonum: -> git stash kullanmayın -> özellik branşlarını kullanın -> devam etmekte olan çalışmayı 'wip' mesajı ile kaydedin. -> anlamlı işlemek biri haline fakat için wip en ezmeye dalında interaktif Rebase sizin yerel, unpushed sadece değişiklikleri. -> uzaktan kumandaya itme -> Git iş akışınıza uygun olarak ana birleştirme (ve itme).
Michael Durrant

Yanıtlar:


31

Gönderen Git SCM Kitabı :

Çoğunlukla, projenizin bir parçası üzerinde çalışırken, işler dağınık bir durumdadır ve dalları bir parça için başka bir şey üzerinde değiştirmek istersiniz. Sorun şu ki, daha sonra bu noktaya geri dönebilmeniz için yarı bitmiş bir iş yapmak istemiyorsunuz. Bu sorunun cevabı git stash komutudur.

Stashing, çalışma dizininizin kirli durumunu alır - yani, değiştirilmiş izlenen dosyalarınız ve aşamalı değişiklikleriniz - ve istediğiniz zaman yeniden uygulayabileceğiniz tamamlanmamış değişikliklerin bir yığına kaydeder.

Bu açıklama göz önüne alındığında, bunun bir Anti Patern olduğunu söyleyebilirim. Git Stash'ın aşırı basitleştirilmiş bir açıklaması, kaynak kontrolünün "Kes ve Yapıştır" olduğudur. Bir sürü değiştirilmiş dosyayı alıp, Git'in normal dallanma iş akışının dışındaki bir tutma kaleminde "saklayın" ve sonra bu değişiklikleri daha sonraki bir tarihte farklı bir dalda tekrar uygulayın.

Biraz daha geriye gitmek, ustalığa bağlılık buradaki anti paterndir . Dalları kullanın. Onlar bunun için tasarlandı.

Bu gerçekten aşağı kaynar:

Duvara bir vida çakabilirsiniz ve bir resmi tutar, ancak bir tornavida kullanarak yapmanız gereken şeydir. Tornavida tam yanınızda otururken çekiç kullanmayın.

"Bozuk" Kod Yazma Hakkında

Aşağıdaki düşünce olsa da, bu görüşe deneyimden geldim.

Erken taahhüt ve sık sık taahhüt etmek. İstediğiniz kadar bozuk kod verin. Yerel bir işlem geçmişinizi bir şeyleri keserken "puan kazan" olarak görün. Mantıklı bir iş yaptıktan sonra bir taahhütte bulunun. Tabii her şeyi bozabilir, ama bu sürece yok gibi önemli değil itmek bu teslimleri. Bastırmadan önce, taahhütlerini yeniden yap ve ez.

  1. Yeni şube oluştur
  2. Hack kesmek Hack kesmek
  3. Bozuk kod ver
  4. Kodu cilala ve çalıştır
  5. Çalışma kodu taahhüt
  6. Rebase ve Squash
  7. Ölçek
  8. Testler geçerken it

OP için, bu Linux kernal mesaj dizisi ilgi çekici olabilir, çünkü OP ekibinin bazı üyeleri Git'i benzer şekilde kullanıyor gibi görünüyor.

@RibaldEddie, bir yorumda şöyle dedi:

Öncelikle, bir stash "dallanma iş akışının" dışında değildir, çünkü kaputun altında bir stash başka bir daldır.

(birçok insanın gazabına maruz kalma riski altında)

Linus dedi ki:

"Git stash" ile, çok sayıda farklı statshed olayına sahip olabilirsiniz, ancak birbirlerini sıraya sokmazlar - sakladığınız rasgele bağımsız yamalardır, çünkü bir noktada sakıncalıdır.

@RibaldEddie'nin söylemeye çalıştığı şey, git stashbir özellik dalı iş akışında kullanabileceğinizdir - ve bu doğrudur. Bunun kullanımı git stashsorun değil. Master ve kullanma taahhüdünün birleşimidir git stash. Bu bir anti örüntüdür.

netleştirilmesi git rebase

@ RibaldEddie'nin yorumundan:

Yeniden düzenleme, kopya yapıştırma işlemine çok benzer , hatta taahhüt edilen geçmişi daha da kötüleştirir.

(Vurgu madeni)

Yerel taahhüt tarihçesi olduğu sürece taahhüt geçmişini değiştirmek kötü bir şey değildir . Yeniden iadenizi çoktan zorladığınızı kabul ederseniz, esasen şubenizi kullanan başka birini yetim edersiniz. Bu kötü.

Şimdi, bir gün boyunca birkaç taahhütte bulunduğunuzu varsayalım. Bazı taahhütler iyiydi. Bazıları ... çok iyi değil. git rebaseTaahhütlerinizi ezmekle birlikte verilen komut, yerel taahhüt geçmişinizi temizlemek için iyi bir yoldur. Bir şubede halka açık şubelerle birleşmek güzel, çünkü ekibinizin ortak şubelerinin taahhüt geçmişini temiz tutuyor. Yeniden düzenlemeden sonra, tekrar test etmek istersiniz, ancak testler geçerse, birkaç kirli olanlar yerine bir tane temiz işlem uygulayabilirsiniz.

Temiz taahhüt tarihinde bir başka ilginç Linux Çekirdeği ipliği var .

Yine, Linus'tan:

Temiz geçmiş istiyorum, ama bu gerçekten (a) temiz ve (b) tarih anlamına gelir.

İnsanlar özel ağaçlarını (kendi çalışmalarını) yeniden diriltebilir (ve muhtemelen etmelidir ). Bu bir temizlik . Ama asla başkalarının kodu yoktur. Bu bir "yok etme tarihi".

Yani tarihin kısmı oldukça kolaydır. Sadece bir ana kural ve bir de küçük açıklama var:

  • Asla ASLA başkalarının tarihini yok etmemelisin. Başkalarının yaptığı işleri taahhüt etmemelisin. Temel olarak, eğer sizin imzanız yoksa, sınırsız kalır: yeniden adlandıramazsınız, çünkü o sizin değil.

    Bunun gerçekten diğer halkların tarihi ile ilgili olduğuna dikkat edin, diğer halkların kuralları hakkında değil . Size e-postayla gönderilen bir düzeltme eki olarak bir şeyler gönderdiler ve siz "git am -s" ile uyguladınız, o zaman bu onların kodu, ama bu sizin tarihiniz.

    Bu yüzden, “git rebase” meselesinde çılgına dönebilirsin, şifreyi yazmasan bile, taahhüdün kendisi özel olduğu sürece.

  • Kural için küçük bir açıklama: Geçmişinizi bir kamu sitesinde yayınladıktan sonra, diğer insanlar onu kullanıyor olabilir ve bu yüzden artık artık özel geçmişiniz değil .

    Bu yüzden küçük açıklama, bunun yalnızca "sizin taahhüdünüz" ile ilgili olmadığı, aynı zamanda ağacınız için özel olduğu ve henüz onu dışarı atmadığınız ve açıklayamadığınız.

...

İlk kurallar oldukça açık ve kolay olmasına rağmen, şimdi "temiz" kısım biraz daha ince:

  • Kendi geçmişinizi okunabilir tutun

    Bazı insanlar bunu sadece kafasındaki işleri yaparak ve hata yapmadan yaparak yaparlar. ama bu çok nadirdir ve geri kalanımız için sorunlarımız üzerinde çalışırken "git rebase" vb. kullanırız.

    Yani "git rebase" yanlış değil. Ama sadece SİZİN ÖZEL ÖZEL git ağacınız ise doğru.

  • Saçmalıklarını açığa vurma.

    Bunun anlamı: Eğer hala "git rebase" aşamasındaysanız, dışarı itmeyin. Hazır değilse, etrafa yamalar gönderir ya da halka genel olarak anlatmadığınız özel git ağaçlarını kullanırsınız (tıpkı "yama serisi değiştirme" gibi).

(vurgu madeni)

Sonuç

Sonunda, OP bunu yapan bazı geliştiricilere sahiptir:

git checkout master
(edit files)
git commit -am "..."
(edit files)
git stash
git pull
git stash (pop|apply)

Burada iki problem mevcut:

  1. Geliştiriciler usta taahhüt ediyoruz. Bunu hemen kilitleyin. Gerçekten, bu en büyük problem.
  2. Geliştiriciler sürekli olarak git stashve git pullözellik dallarını kullanmaları gerektiğinde master'ı kullanıyorlar.

Kullanırken yanlış bir şey yok git stash- özellikle çekmeden önce - ama git stashbu şekilde kullanmak Git'te daha iyi iş akışları olduğunda anti-paterndir.

git stashKırmızı bir ringa balığı kullanmaları . Sorun bu değil. Master'a karar vermek problemdir.


4
Vay, bu doğru değil. Öncelikle, bir stash "dallanma iş akışının" dışında değildir, çünkü kaputun altında bir stash başka bir daldır. Kopyala yapıştır iş akışı olduğu fikri bir anlam ifade etmiyor. Yeniden düzenleme, kopya yapıştırma işlemine çok benzer, hatta taahhüt edilen geçmişi daha da kötüleştirir. Sonunda, iş akışınızı, devam eden işlerinizi meslektaşlarınızla paylaşmanız gerektiğinde, değişiklikleri zorladığınız anda parçalandığından tamamen işe yaramaz. Bunun altı oyu nasıl olduğu akıl almaz.
RibaldEddie

8
@RibaldEddie: Yerel işlem tarihi olduğu sürece, taahhüt tarihçesinin yeniden yapılandırılması ve yeniden yazılmasında yanlış bir şey yoktur. Bu taahhütleri zorladığınızda yorumunuz doğru olacaktır, ancak cevabımı yeniden okudum. Diyor ki: "İttirmeden önce, taahhütlerini yerine getir ve bastır." Bu tamamen sizin kontrolünüz altında olan yerel taahhüt tarihidir.
Greg Burghardt

1
@RibaldEddie: Cevabımı netleştirdim. Biraz temizlik yapması gerekiyordu.
Greg Burghardt

Kendi cevabımla biraz daha bağlam sağlayacağım.
RibaldEddie

Aşağıdaki cevabımı görün-- ustalığa bağlılık bir anti-kalıp olsa da, asıl sorun bu değil.
RibaldEddie

7

Şahsen ben sadece stashkısa, beklenmedik kesintiler için kullanıyorum, biri farklı bir dalda değişiklik yapmayı gerektiren bir soru soran biri gibi. Bunu yapıyorum çünkü daha önce zula almayı unutmuştum, sonra temiz bir şekilde uygulama yapmıyorlardı. Özellik dallarındaki düzenli taahhütler unutmak çok daha zor ve birleştirmek daha kolaydır, bu yüzden şimdi daha sonra git reset HEAD~1kesmek istemiyorsam kırılmış bir işlem yapma eğilimindeyim, daha sonra bir ya da yeniden ödeme yapma eğilimindeyim .

Ancak, dağıtılmış sürüm kontrolü ile ilgili en iyi şey, paylaşılan depolar standartları karşıladığı sürece insanlar tercih ettikleri iş akışını kendi depolarında kullanabilirler. İnsanların sadece bir stashiş akışı kullanmadıklarından emin olurdum, çünkü yeterli eğitim veya alternatifler konusunda bilinçleri yok, ama yine de bir iş akışı seçerlerse, en iyi sonucu bulursanız, bırakmış olurum.


1

Sanırım sorunuzun bir karşıtı olan kısmı, paylaşılan tek bir ana dalın kullanılması. Bununla birlikte, ana şubeye ek olarak bir geliştirme dalı eklerseniz ve ardından geliştirme branşında kendi bağlam anahtarlarınızla uğraşmak için stash kullanırsanız, bu bir anti-kalıp olmaz ve iş akışının bir kısmını çok yakından yansıtır. Etsy ve Facebook gibi organizasyonları tanımlar.

Söylendiğine göre, @Greg Burghardt'ın yukarıdaki cevabı, git-flow veya özellik dalı iş akışı için biraz fazla olumlu. Benzer bir stratejinin savunuculuğunu yapardım ama gereksiz bir karmaşıklık kattığını ve yanlış bir güvenlik hissi yarattığını fark ettikten sonra, artık yapmıyorum. Aynı zamanda, yıkılma gibi merkeziyetçi olmayan sürüm kontrol sistemleri günlerinden bir kaynak.

Birincisi Git, yıkılmanın aksine merkezi olmayan bir sürüm kontrol sistemi olduğundan, bir geliştiricinin yerel deposu, esasen kendi başına kodun dev bir dalıdır. Bir bireyin geliştirdiği şeyin yerel olarak yaptığı şey, paylaşılan bir depodaki herhangi bir paylaşılan şubeye hatalı veya hatalı kod iletilmediği sürece, diğer ekip üyeleri üzerinde bir etkisi olmaz ve olmamalıdır.

Ancak rebase komutu, tekrarlanan komisyonlardan birinde bir birleştirme çatışması olduğunda şubenin geçmişine zarar verebilir. Http://ryantablada.com/post/the-dangers-of-rebasing-a-branch adresinden

Rebase'in geri kalanı sorunsuz bir şekilde ilerliyor, testlerin hepsi geçti gibi görünüyor. Bir PR yapılır.

Ve sonra commentsForAllPosts özelliğine dayanan ve her şey bozulan bazı kodlar yazılır. Ama kime gider ve yardım isteriz? git suçlama, kod satırının sadece sunucu tarafı mühendisi tarafından yazıldığını ve ellerini yukarı attığını gösterir.

Artık ön mühendisiniz tatilde, hasta izninde veya kim bilir. Hiç kimse bu kodun neye benzemesi gerektiğini bulamıyor!

Rebase neyin yanlış gittiğini bulmak için ekibin tarihe bakma yeteneğini öldürdü, çünkü çocuk dalındaki herhangi bir birleşme çatışması öldü ve orijinal kod sonsuza dek kayboldu.

Bu aynı birleştirme çatışması ortaya çıktıysa ve birleştirme kullanıldıysa, suçlama, birleştirme sürecinde bu ana kod çizgisine, ana daldaki bağlılığa ve alt daldaki bağlılığa dokunulduğunu gösterecekti. Bazıları üç permütasyonla oynar ve orijinal niyetini tekrar kod tabanına sokabilir ve bir ton başını parmakla çizmeden çalıştırabilirsiniz. Ve tek sahip olduğun başka bir şeydi.

Ayrıca, çoklu dallanma modelinde hiçbir iki dalın birbirine bağımlı kod değişiklikleri içeremeyeceği varsayılmaktadır. Bu kaçınılmaz bir şekilde gerçekleştiğinde, geliştirici şimdi verimli bir şekilde çalışmak için henüz daha fazla dalla oynamalıdır.

Gördüğüm en temel anti-patern, dallarla ve depolarla ilgili değil, çok akıllı insanların bir süredir bahsettiği sorun türleri hakkında daha fazla şey ifade ediyor: birim testleri ve iyi bir mimari? Geliştiricileriniz değişikliklere kolayca sebep olabilir ve bir değişimin ne yapacağını anlayabilecek şekilde, kodunuzda artımlı değişiklikler yapabilir misiniz? Geliştiricileriniz gerçekten işe yarayıp yaramadığını görmek için bir kez bile yeni kod kullanıyorlar mı? (Evet, bunu daha önce görmüştüm).

Bu soruların cevabı hayır ise, o zaman kaç şubenizin olduğu önemli değil - geliştiriciler, kodun gerçekten hazır olmadığı zaman kodun hazır olduğunu, çalıştığını ve üretime uygun olduğunu ve hiçbir dalın olmadığını söyleyecektir. Bu kod zaten üretime geçtiğinde size yardımcı olur.


2
Yeniden yapılanma ile birleştirme çözünürlüğü sorunları hakkında yorumunuz doğru değil. Rebase, gerçek bir birleştirme ile aynı türde birleştirmedir. Git, sadece kaputun altındaki işleri birleştiriyor. Bir birleştirme çatışmasını yeniden oluşturmak ve çözmek, taahhüt geçmişine zarar vermez. Bir birleştirme çatışmasının yeniden doğması ve yanlış bir şekilde çözülmesi, normal bir birleşme ile muhtemel olan şeylere zarar verir. Özellik dallarının karmaşıklık eklediğine katılıyorum, ancak geliştiricilerin ilgisiz birden fazla değişiklik yapması gerektiğinde bu gerekli bir karmaşıklık olabilir.
Greg Burghardt

Yani birleşmelerin tarihi yok edebileceğini mi söylüyorsun? Çok fazla şubeye sahip olmaktan kaçınmak için bu sadece bir gerekçe gibi görünüyor!
RibaldEddie

1
Birleşmeler tarihi yok edemez. Yeniden doğuş ve birleşmenin nasıl çalıştığını yanlış anlıyor olabilirsiniz. Bir birleştirme çatışması tetiklendiğinde, bunu çözmek insanın görevidir. İnsan yanlış çözerse Git'i (veya SVN'yi veya CVS'yi veya {buraya kaynak kontrolü ekleyin}) suçlayamazsınız.
Greg Burghardt,

Şimdi söyledikleriniz daha önce söylediklerinizle çelişiyor. Aldığım yazıyı okudun mu? Bir rebase'ın tarihi kaybedeceği bağlamı anlıyor musunuz?
RibaldEddie

1
Makaleyi okudum. “Keen olarak, neredeyse her taahhüdün ardından kodumuzu zorlamaya çalışıyoruz.” Bu bana deli geliyor. Ya aşırı derecede büyük taahhütlerde bulunuyorlar ya da henüz hazır olmayan kodları bastırıyorlar. Tüm taahhütlerinizi derhal kamuya açıklarsanız, o zaman evet, yeniden yapılanma sorunlara neden olacaktır. "Doktor, doktor, bunu yaptığımda canım yanıyor" prensibi.
Kyralessa

1

git stashbir araçtır. Kendi içinde bir kalıp değildir, ne de bir anti kalıptır. Bir alettir, çekiç gibi bir alettir. Çivileri sürmek için bir çekiç kullanmak bir kalıptır ve vidaları sürmek için bir çekiç kullanmak bir anti-kalıptır. Aynı şekilde, git stashkullanılacak doğru aracın olduğu iş akışları ve ortamlar ve yanlış olan iş akışları ve ortamlar vardır.

'Herkes bağlı ve ana hatta itiyor' iş akışı, yüksek risk değişikliklerinin olmadığı yerlerde oldukça makul şekilde çalışan bir iş akışıdır. Genellikle, kodu olan yetkili bir merkezi sunucunun bulunduğu svn ortamlarında kullanılır.

Bununla birlikte Git, tek bir merkezi sunucuyla yapmayı bağlar. Yapıyor bütün geliştiriciler olması commit, pull(veya rebasebunun içine iseniz), pushher zaman büyük bir karmaşa yaratabilir.

En büyük sorun, ortaya çıkan kırık bir şeyin var ve öncelikli bir hata üzerinde çalışmanız gerekiyor. Bunun anlamı, bu işi bir kenara ayırmanız, en yenilerini almanız, üzerinde bir önceki çalışmanın yapılmasına gerek kalmadan üzerinde çalışmak zorunda kalmanıza neden olur.

Bunun git stashiçin kullanmak için uygun bir araç olacaktır.

Bununla birlikte, bu iş akışının kalbinde gizlenen daha büyük bir sorun var. Olmasıdır tüm sürüm kontrol dallarının roller tek dal üzerinde bulunmaktadır. Ana hat, geliştirme, bakım, biriktirme ve paketleme işlemleri Master'dadır. Bu bir problem. ( Şubelere bu yaklaşım hakkında daha fazla bilgi için bkz. Gelişmiş SCM Dallanma Stratejileri )

Ve evet, bunun harika bir iş akışı olmadığını ve bununla ilgili sorunların olduğunu söylediniz. Ancak sorun araçla ilgili değil git stash. Sorun, roller veya uyumsuz politikalar için farklı dallanma eksikliğidir .

git stashAncak, bir süredir kurduğum bir durum olduğunda kullandığım, doğru durumda olup olmadığından emin olamadığım yapışkan bir hal aldı ... bu yüzden değişikliklerimi bıraktım ve sonra sorunu çözmek için başka bir yaklaşım araştırdı. Eğer işe yaradıysa - harikaydı, zuladaki şeyleri atın ve devam edin. Diğer keşif daha sertleştiyse, önceki değişikliğe geri dönün ve bunun üzerinde çalışmak için zula uygulayın. Alternatif, taahhüt etmek, ödeme yapmak, şube açmak ve sonra bu yeni şube üzerinde devam etmek veya geri dönüp sıfırlamak olacaktır. Asıl soru, biraz keşfetmek istediğim bir şey olduğunda bunu tarihe sokmaya gerçekten değer mi?

git stashanti bir kalıp değildir. git stashHerkes Üstad'a taahhüt ederken dallanmaya alternatif olarak kullanmak anti bir örüntüdür - çünkü değil git stash.

Henüz vurmadıysanız , bir sürü dosyada (ve birleştirme çatışmalarında) önemli mimari değişiklikler yapması gerektiğinde veya bunun için prodüksiyona sızan test edilmemiş bir çalışma kodunda önemli değişiklikler yapana kadar bekleyin. Anti-desen size yetişmek için.

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.