Git'te, bir düzine kitaplık için versiyonlama nasıl yapılır?


11

Projeler yapıyoruz, ancak projeler arasında çok fazla kod kullanıyoruz ve ortak kodumuzu içeren çok sayıda kütüphanemiz var. Yeni projeler uygularken, ortak kodu ortadan kaldırmanın ve kütüphanelere koymanın daha fazla yolunu buluyoruz. Kütüphaneler birbirine, projeler kütüphanelere bağlıdır. Her projenin ve bu projede kullanılan tüm kütüphanelerin, atıfta bulundukları tüm kütüphanelerin aynı sürümünü kullanmaları gerekir. Bir yazılım parçası yayınlarsak, hataları düzeltmemiz ve belki de yıllarca, bazen on yıllarca yeni özellikler eklememiz gerekir. Yaklaşık bir düzine kütüphanemiz var, değişiklikler genellikle ikiden fazla kesiliyor ve birkaç ekip paralel olarak birkaç proje üzerinde çalışıyor ve tüm bu kütüphanelerde eşzamanlı değişiklikler yapıyor.

Son zamanlarda git'e geçtik ve her kütüphane ve her proje için depolar kurduk. Stash'ı ortak bir depo olarak kullanırız, özellik dallarında yeni şeyler yaparız, sonra çekme istekleri yaparız ve bunları yalnızca incelemeden sonra birleştiririz.

Projelerde ele almak zorunda olduğumuz sorunların çoğu, çeşitli kütüphanelerde ve projenin özel kodunda değişiklikler yapmamızı gerektirir. Bunlar genellikle bazıları uyumsuz olan kütüphane arayüzlerinde yapılan değişiklikleri içerir. (Bunun kulağa hoş geldiğini düşünüyorsanız: Donanımla arayüz oluştururuz ve genel arayüzlerin arkasındaki belirli donanımları gizleriz. Hemen hemen başka bir satıcının donanımını her birleştirdiğimizde, mevcut arayüzlerimizin öngörmediği ve bunları düzeltmek zorunda kaldık. örnek bir proje hayal P1kütüphaneleri kullanılarak L1, L2ve L3. L1Ayrıca kullandığı L2ve L3ve L2kullanımları L3da. Bağımlılık grafiği şöyle görünür:

   <-------L1<--+
P1 <----+  ^    |
   <-+  |  |    |
     |  +--L2   |
     |     ^    |
     |     |    |
     +-----L3---+

Şimdi bu proje için bir özellik değişikliği gerektiren P1ve L3hangi arayüzü değiştirmek düşünün L3. Şimdi bu kütüphanelere atıfta bulunan projeleri P2ve P3karışıma ekleyin . Hepsini yeni arayüze geçirmeyi, tüm testleri çalıştırmayı ve yeni yazılımı dağıtmayı göze alamayız. Peki alternatifi nedir?

  1. yeni arayüzü L3
  2. bir talepte L3bulunun ve inceleme için bekleyin
  3. değişikliği birleştir
  4. yeni bir sürüm oluştur L3
  5. yeni sürümüne P1başvurarak özellik üzerinde çalışmaya başlayın L3, ardından özelliği P1özellik dalında uygulayın
  6. bir istekte bulunun, bunu inceleyin ve birleştirin

(Sadece yeni sürüme geçmeyi L1ve L2yeni sürüme geçmeyi unuttuğumu fark ettim . Ve bunu nereye yapıştıracağımı bile bilmiyorum, çünkü paralel olarak yapılması gerekecek P1...)

Bu, bu özelliği uygulamak için sıkıcı, hataya eğilimli ve çok uzun bir süreçtir, bağımsız incelemeler gerektirir (bu da incelemeyi çok zorlaştırır), hiç ölçeklenmez ve muhtemelen bizi işten çıkarır çünkü süreç içinde bu kadar bataklık olsun asla hiçbir şey yapmıyoruz.

Ancak, çok fazla ek yük olmadan yeni projelerde yeni özellikler uygulamamıza izin veren bir süreç oluşturmak için dallanma ve etiketlemeyi nasıl kullanıyoruz?


1
Takımınızı değiştirmek, uyguladığınız işlemleri çok fazla etkilememelidir. Peki, git'e geçmeden önce bu problemle nasıl başa çıktınız?
Bart van Ingen Schenau

Çok fazla kütüphane bağımlı olduğunda mevcut olanı bozmadan arayüze yeni bir yöntem eklemek mümkün müdür? Normalde bu en iyi fikir değildir, ancak en azından yeni özelliğin uygulanmasına "devam etmenize" izin verir ve boş bir an olduğunda eski yöntemi uygun şekilde kullanımdan kaldırırsınız. Yoksa bu arayüzler bunun gibi "paralel arayüzler" için fazla durumlu mudur?
Ixrec

1
@Ixrec: Bana bir şeyler yapmanın "bu git yolu değil" söylendi. Herkes bireysel projeler için bireysel depolar kullanır, bu yüzden bunu da yapmaya karar verdik.
sbi

2
Sık sık birlikte değiştirilmeleri gerekiyorsa ayrı projeler olmadıklarını iddia ediyorum. "Projeler" arasındaki sınırlar her zaman uzun vadeli geriye dönük uyumluluk garantisi imo'ya sahip olmalıdır.
Ixrec

1
@Ixrec: Daha fazla donanımı entegre etmek kodu daha fazla platforma taşımakla aynıdır: bunu ne kadar çok yaparsanız, başka bir donanım / platform için o kadar az değiştirmeniz gerekir. Böylece uzun vadede kod stabilize olacak. Ancak, şu anda piyasaya oraya varmak için yeterince uzun kalmamızı sağlayan bir süreç bulmamız gerekecek.
sbi

Yanıtlar:


5

Burada bariz bir şekilde ortaya koymak, ama belki de bahsetmeye değer.

Git depoları genellikle lib / proje başına uyarlanır çünkü bağımsız olma eğilimindedirler. Projenizi güncellersiniz ve gerisini umursamazsınız. Buna bağlı diğer projeler, uygun olduklarında lib'lerini güncelleyecektir.

Bununla birlikte, davanız yüksek oranda ilişkili bileşenlere bağımlı görünmektedir, böylece bir özellik genellikle birçoğunu etkiler. Ve bütün bir demet olarak paketlenmelidir. Bir özellik / değişiklik / hata uygulamak çoğu zaman birçok farklı kütüphaneyi / projeyi aynı anda uyarlamayı gerektirdiğinden, belki de hepsini aynı depoya koymak mantıklıdır.

Bunun güçlü avantajları / dezavantajları vardır.

Avantajları:

  • İzlenebilirlik: şube, bu özellik / hata ile ilgili her projede / lib'de değişen her şeyi gösterir.
  • Paketleme: bir etiket seçmeniz yeterlidir, tüm kaynakları doğru şekilde alırsınız.

Dezavantajları:

  • Birleştirme: ... bazen tek bir proje için zaten zor. Paylaşılan şubeler üzerinde çalışan farklı ekiplerle etki yaratmaya hazır olun.
  • Tehlikeli "ayy" faktörü: Bir çalışan depoyu hata yaparak dağıtırsa, tüm projeleri ve ekipleri etkileyebilir .

Fiyatın faydaya değip değmeyeceğini bilmek size kalmış.

DÜZENLE:

Şu şekilde çalışır:

  • X Özelliği uygulanmalıdır
  • Şube oluştur feature_x
  • Tüm geliştiriciler bu dal üzerinde çalışmaya ve muhtemelen proje / lib ile ilgili özel dizinlerde paralel olarak çalışmaya başladı.
  • Bittikten sonra gözden geçirin, test edin, paketleyin, her neyse
  • Onu ustalıkla birleştirin ... ve bu arada zor olan kısım da olabilir feature_yve feature_zeklenmiş olabilir. Bu bir "takımlar arası" birleşmesi haline geliyor. Bu yüzden ciddi bir dezavantaj.

sadece kayıt için: Bu çoğu durumda kötü bir fikir olduğunu ve dikkatli bir şekilde yapılması gerektiğini düşünüyorum çünkü birleştirme dezavantajı genellikle bağımlılık yönetimi / uygun özellik izleme yoluyla elde edenden daha yüksektir.


Teşekkürler, aslında şu anda buna bakıyoruz. Bunun ışığında anlamadığım şey git ile nasıl dallandığımızdır. SVN'de şubeler, bir alt ağacın (depoda) başka bir yere (depoda) kopyalanması anlamına gelir. Bununla, repoda herhangi bir alt ağacın dallarını oluşturmak kolaydır, bu nedenle orada çok sayıda projeniz varsa, her birini ayrı ayrı dallayabilirsiniz. Git'te böyle bir şey var mı, yoksa her zaman sadece bir repoyu kollayabilecek miydik?
sbi

sbi: tüm repoyu kollayacaksın. Durumunuzdaki noktayı yenecek olan farklı branşlardaki alt ağaçlarla çalışamazsınız. Git hiçbir şeyi "kopyalamaz", üzerinde çalıştığınız daldaki değişiklikleri izler.
dagnelies

Bu nedenle, bir kütüphanenin birleştirme veya yeniden basma işleminde tüm diğerlerini birleştirmesi için bir özellik dalı oluşturan biri gerekir. Bu gerçek bir dezavantaj. (BTW, SVN de sadece tembel kopyalar yapıyor.)
sbi

@sbi: see edit
dagnelies

1
Şu anda çoğumuz rahat değiliz. :-/Dahası, (git gitmeye iten) bile, geliştirme sürecimizi git ile nasıl uyumlu hale getireceğimizi bilmiyoruz. İç çekmek. Korkarım, işler daha pürüzsüz hale gelene kadar birkaç zor ay olacak. Neyse, şimdiye kadar en yararlı tek cevap sizindir.
sbi

4

Aradığınız çözüm git submodules ile koordineli bir bağımlılık yönetim aracıdır

Gibi araçlar:

  • Uzman
  • Karınca
  • Besteci

Bir projenin bağımlılıklarını tanımlamak için bu araçları kullanabilirsiniz.

Bir alt modülün en az > 2.xx sürümüne sahip olmasını veya uyumlu = 2.2. * Veya belirli bir sürümden <2.2.3 daha düşük sürümleri belirtmesini isteyebilirsiniz .

Paketlerden birinin yeni bir sürümünü her yayınladığınızda sürüm numarasıyla etiketleyebilirsiniz, böylece kodun bu belirli sürümünü diğer tüm projelere çekebilirsiniz


Ancak bağımlılık yönetimi bizim sorunumuz değil, bu çözüldü. Şu anda düzenli olarak birçok kütüphanede değişiklikler yapıyoruz ve istikrarlı proje sürümlerini korurken yeni sürümler oluşturma yükünü en aza indirmemiz gerekiyor. Cevabınız buna bir çözüm sunmuyor gibi görünüyor.
sbi

@sbi Bu, yeni sürümler oluşturma ve sabit proje sürümlerini koruma yükünü yönetir. X projesinin proje y 2.1.1 sürümüne dayandığını belirtebildiğiniz için, y projesinin x projesini etkilemeyen yeni sürümleri oluşturabilirsiniz.
Patrick

Yine, bağımlılıkları beyan etmek bizim sorunumuz değil. Bunu zaten yapabiliriz. Sorun, birkaç proje / kütüphanede yapılan değişikliklerin verimli bir şekilde yönetilmesidir. Cevabınız bunu açıklayamıyor.
sbi

@sbi: sorununuz tam olarak nedir? Değişikliklerinizi yaparsınız, sürümü çarptırırsınız, gerektiğinde bağımlılıkları günceller ve voila. İlk yazınızda açıkladığınız şey tipik maven & co. şey. Her dağıtım açıkça tanımlanmış versiyonlanmış kütüphanelere dayanmaktadır. Nasıl daha net olabilirdi?
dagnelies

@arnaud: Üç veya daha fazla katmanı keserek (şu anda oldukça yaygın) değişiklikler için böyle bir işlemin geri dönüş süreleri bizi öldürür. Sorumun bunu tarif ettiğini düşündüm.
sbi

0

Altmodüller

Sen hiç bir denemelisiniz git altmodulden bir açıklamada önerildiği gibi.

Projesi ne zaman P1üç submodules atıfta L1, L2ve L3, aslında her üç depoları belirli kaydedilmesini bir başvuru saklar: olanlardır çalışan her kütüphanelerin versiyonları o proje için .

Bu nedenle, birden çok proje birden çok alt modülle çalışabilir: proje yeni sürümü kullanırken P1kitaplığın eski sürümüne işaret edebilir .L1P2

Sitesinin yeni bir sürümünü teslim ettiğinizde ne olur L3?

  • yeni arayüz uygulamak L3
  • taahhüt, test , çekme talebi yap, gözden geçir, birleştir, ... (bundan kaçınamazsın)
  • sağlamak ile L2çalışmak L3, taahhüt, ...
  • sağlamak ile L1çalışır yeni L2, ...
  • sağlamak P1tüm kütüphanelerin yeni sürümleriyle çalışır:
    • içeride P1'ın yerel çalışma kopyası L1, L2ve L3, sen ilgilenen değişiklikleri fetche.
    • git add L1 L2 L3Modüllere yeni referans vermek için değişiklik yapma
    • çekme isteği P1, test, inceleme, çekme isteği, birleştirme ...

metodoloji

Bu, bu özelliği uygulamak için sıkıcı, hataya eğilimli ve çok uzun bir süreçtir, bağımsız incelemeler gerektirir (bu da incelemeyi çok zorlaştırır), hiç ölçeklenmez ve muhtemelen bizi işten çıkarır çünkü süreç içinde bu kadar bataklık olsun asla hiçbir şey yapmıyoruz.

Evet, bağımsız incelemeler gerektirir , çünkü şunları değiştirirsiniz:

  • kütüphane
  • ona bağlı kütüphaneler
  • birden fazla kütüphaneye bağlı projeler

Saçmalık yaptığınız için işten çıkarılır mısınız? (Belki de değil). Evetse, testler yapmanız ve değişiklikleri gözden geçirmeniz gerekir.

Uygun git araçlarıyla (çift gitk), her bir projenin hangi kitaplık sürümlerini kullandığını kolayca görebilir ve ihtiyaçlarınıza göre bağımsız olarak güncelleyebilirsiniz. Alt modüller durumunuz için mükemmeldir ve işleminizi yavaşlatmaz.

Belki bu sürecin bir kısmını otomatikleştirmenin bir yolunu bulabilirsiniz , ancak yukarıdaki adımların çoğu insan beyni gerektirir. Zamanı azaltmanın en etkili yolu, kütüphanelerinizin ve projelerinizin kolayca geliştirilmesini sağlamaktır. Kod tabanınız yeni gereksinimleri zarif bir şekilde işleyebiliyorsa, kod incelemeleri daha basit olacak ve çok az zaman alacaktır.

(Düzenle) size yardımcı olabilecek başka bir şey ilgili kod incelemelerini gruplandırmaktır. Tüm değişiklikleri taahhüt edersiniz ve bu değişiklikleri, çekme isteklerini vermeden önce (veya bunlarla ilgilenmeden önce) kullanan tüm kitaplıklara ve projelere geçirene kadar beklersiniz. Sonunda tüm bağımlılık zinciri için daha büyük bir inceleme yapıyorsunuz. Belki de her yerel değişiklik küçükse zaman kazanmanıza yardımcı olabilir.


Bağımlılık sorununun nasıl çözüleceğini açıklarsınız (ki daha önce söylediğim gibi, çözdük) ve yaşadığımız problemi ortadan kaldırırsınız. Neden rahatsız oluyorsun? (FWIW, elektrik santrallerini
yöneten

@sbi Özel bir dallanma ve etiketleme durumu değilse alt modüller nelerdir? Sen düşünmek onlar da bağımlılıkları takip çünkü alt modüller, bağımlılık yönetimi ile ilgilidir. Ama elbette, lütfen alt modülleri etiketlerle yeniden icat edin, umursamıyorum. Sorununuzu anlamıyorum: incelenen kod birinci sınıf bir özellikse, incelemeler için biraz zaman ayırmanız gerekir. Aşağı düşmüyorsunuz, size verilen kısıtlamalarla mümkün olduğunca hızlı gidiyorsunuz.
coredump

Yorumlar bizim için çok önemlidir. Bu, birkaç havuzdaki çeşitli değişiklikler için çeşitli incelemeler arasında bölünmüş bir sorunun (ve incelemelerinin) endişelenmesinin nedenlerinden biridir. Ayrıca, bizi tek bir konu üzerinde idam ettirmekle uğraşmak istemiyoruz, zamanınızı kod yazarak ve gözden geçirerek geçirmeyi tercih ediyoruz. Alt modüller: şimdiye kadar, onlar hakkında duyduğum tek şey "rahatsız etmeyin, bu git yolu değil" dir. Gereksinimlerimizin çok benzersiz göründüğü göz önüne alındığında, belki de bu kararı tekrar gözden geçirmeliyiz ...
sbi

0

Anladığım kadarıyla P1 için L3 arayüzünü değiştirmek istiyorsunuz ama L3 arayüzüne bağlı diğer P2 ve P3'ün hemen değişmesini istiyorsunuz. Bu tipik bir geriye dönük uyumluluk durumudur. Bu Geriye Dönük Uyumluluğu Koruma hakkında güzel bir makale var

Bunu çözmenin birkaç yolu vardır:

  • Her seferinde eski arayüzleri genişletebilecek yeni arayüzler oluşturmanız gerekir.

VEYA

  • Bir süre sonra eski arayüzü emekliye ayırmak isterseniz, arayüzlerin birkaç sürümüne sahip olabilirsiniz ve tüm bağımlı projeler taşındıktan sonra eski arayüzleri kaldırırsınız.

1
Hayır, sürüm dalları ile geriye dönük uyumluluk sağlanır ve bizim sorunumuz değildir. Sorun şu ki, arayüzlerin hala sık sık değiştikleri aşamada olmasına rağmen, şu anda hızla değişen bir kod tabanına oturuyoruz. SVN'de bu tür hayvanların nasıl yönetileceğini biliyorum, ama yönetimde boğulmadan git içinde bunu nasıl yapacağımı bilmiyorum.
sbi

0

Sorununuzu doğru şekilde alıyorsam:

  • 4 adet birbiriyle ilişkili modülünüz var, P1 ve L1 - L3
  • sonuçta L1 ila L3'ü etkileyecek olan P1'de bir değişiklik yapmanız gerekir
  • 4'ün tamamını birlikte değiştirmek zorunda kalırsanız işlem hatası olarak sayılır
  • hepsini birer birer değiştirmeniz gerektiğinde işlem hatası olarak sayılır.
  • önceden değişiklik yapılması gereken parçaları önceden tanımlamanız gerekiyorsa, işlem hatası olarak sayılır.

Yani amaç P1 ve L1'i bir seferde yapabilmeniz ve bir ay sonra L2 ve L3'ü bir seferde yapabilmeniz.

Java dünyasında, bu önemsizdir ve belki de varsayılan çalışma yolu:

  • her şey ilgili bir dallanma kullanımı olmadan tek bir depoda gider
  • modüller derlenir + hepsi aynı dizin ağacında değil, sürüm numaralarına göre maven tarafından birbirine bağlanır.

Böylece L3 için yerel diskinizde, diskinizdeki diğer dizindeki P1'in kopyasına karşı derleme yapmazsa derlemeyeceğiniz kod olabilir; Neyse ki öyle değil. Java bunu doğrudan yapabilir çünkü masalları derleme / bağlama, kaynak kodu yerine derlenmiş jar dosyalarına karşı yerleştirir.

C / C ++ dünyası için bu soruna önceden var olan yaygın olarak kullanılan bir çözümün farkında değilim ve dilleri değiştirmek istemediğinizi hayal ediyorum. Ancak bir şey, eşdeğer şeyi yapan make dosyaları ile kolayca saldırıya uğratılabilir:

  • kurulu kütüphaneler + gömülü sürüm numaraları ile bilinen dizinlere başlıklar
  • modül başına uygun derleyici yolları uygun sürüm numaraları için dizine değiştirildi

C / C ++ desteğini maven'de bile kullanabilirsiniz , ancak çoğu C geliştiricisi size garip bir şekilde bakarsanız ...


msgstr "4'ü birlikte değiştirmek zorunda kalırsanız işlem hatası olarak sayılır" . Aslında olmazdı. Aslında, SVN kullanarak yaptığımız da budur.
sbi

Bu durumda sanırım tüm projeleri depoya koymakla ilgili bir sorun yok.
soru

Şimdi kütüphaneleri sadece iki veri havuzuna koymayı değerlendiriyoruz. Bu hala birden fazla, ama "her proje için bir tane" den çok daha az ve kütüphaneler iki gruba ayrılabilir. Girdiniz için teşekkürler!
sbi

PS: "Çok fazla dil değiştirmek istemediğini hayal ediyorum." Bu gömülü şeyler. :)
sbi

-1

Basit bir çözüm var: tüm depodaki serbest bırakma dallarını kesin, tüm düzeltmeleri aktif olarak gönderilen tüm sürümlerle birleştirin (git durumunda kolay olması kolaydır).

Tüm alternatifler zaman içinde ve proje büyümesiyle korkunç bir karmaşa yaratacaktır.


Lütfen biraz açıklayabilir misiniz? Ne önerdiğinden emin değilim.
sbi

Açık bir durumda, bir dallanma noktasını temel dal ve zaman damgası olarak tanımlarsınız. Şu hiyerarşiniz var: temel şube -> sürüm-geliştirme-şube -> özel geliştirme dalı. Tüm gelişim özel branşlarda yapılır ve hiyerarşiyi birleştirir. Müşteri sürüm şubeleri sürüm-geliştirme-şubesinden ayrılır. Git'e aşina değilim ama serbest kaynak kontrol sistemleri arasında durumu açıklığa kavuşturmak için en yakın şey gibi görünüyor.
zzz777

Sorumun dikkatli bir şekilde okunması, depolar arasındaki değişiklikleri yaymakla ilgili ek yük ile ilgili sorunlarımız olduğunu göstermiş olmalıdır. Bunun cevabınızla bir ilgisi yok.
sbi

@sbi Sorunu yanlış anladığım için üzgünüm. Ve er ya da geç korkunç bir karmaşa ile karşı karşıya kalacağınızdan korkuyorum.
zzz777
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.