Git taahhütleri neden oluşturuldukları dalın adını içermiyor?


20

Özellik dalları kullanan bir ekipte git ile çalışırken, tarihte şube yapısını anlamakta zorlanıyorum.

Örnek:

Diyelim ki bir özellik dalı özelliği / kahve yap , ve hata düzeltmesi özellik dalına paralel olarak master'da devam etti .

Tarih şöyle görünebilir:

*     merge feature/make-coffee
|\
| *   small bugfix
| |
* |    fix bug #1234
| |
| *    add milk and sugar
| |
* |    improve comments
| |
* |    fix bug #9434
| |
| *    make coffe (without milk or sugar)
| |
* |    improve comments
|/
*

Sorun

İlk bakışta, hangi tarafın özellik dalı olduğunu söylemekte zorlanıyorum. Hangisi hakkında bir fikir edinmek için genellikle her iki tarafta birkaç yoruma göz atmam gerekir. Paralel olarak birden fazla özellik dalı varsa (özellikle yakından ilişkili özellikler içinse) veya özellik dalı ile master arasında her iki yönde birleşme varsa bu daha karmaşık hale gelir.

Bunun aksine, Subversion'da, şube adı tarihin bir parçası olduğu için bu çok daha kolaydır - bu yüzden başlangıçta "özellik / make-coffee" üzerine bir taahhüt yapıldığını söyleyebilirim.

Git , bir taahhüt oluştururken (yazar, tarih vb. İle birlikte) mevcut şubenin adını taahhüt meta verilerine ekleyerek bunu kolaylaştırabilir. Ancak git bunu yapmaz.

Bunun yapılmamasının temel bir nedeni var mı? Yoksa kimsenin bu özelliği istememesi mi? Eğer ikinciyse, tarihi şubelerin adını görmeden anlamanın başka yolları var mı?


1
İlgili soru: Bir taahhüdün hangi şubeden geldiğini bulmak . Bu, git'in açıkça kaydetmemesine rağmen, bu bilgiyi nasıl bulacağınızla ilgilidir.
sleske

1
Kendime not: İlginçtir, Mercurial içinde taahhüt vermez şube adını içeriyor. Görünüşe göre Mercurial geliştiriciler git geliştiricilerden farklı bir tasarım kararı aldı. Ayrıntılar için bkz. Örneğin felipec.wordpress.com/2012/05/26/… .
sleske

Yanıtlar:


14

Muhtemelen şube adları sadece bir depo içinde anlamlı olduğu için. Ben isem make-coffeeekibi ve bir bekçi aracılığıyla tüm değişiklikleri göndermek, benim masterşube ağ geçidi denetleyicisinin için çekilmiş olabilir olsun make-coffee-guionun birleştirilecek dalı, make-coffee-backendbir karşı rebasing önce, şube make-coffeemerkezi birleştirilecek alır şube masterşube.

Tek bir depoda bile, şube adları iş akışınız geliştikçe değişebilir ve değişebilir. örneğin masterdaha sonra çağrılacak şekilde değişebilir development.

CodeGnome'un belirttiği gibi, git gerekli değilse verilere bir şey pişirmemek için güçlü bir tasarım felsefesine sahiptir. Kullanıcıların , verileri, gerçeklerden sonra beğenilerine göre kullanmaları git logve git diffçıktıları almaları beklenir. Sizin için daha uygun bir biçim bulana kadar denemenizi öneririz. git log --first-parent, örneğin, birleştirilen bir şubedeki taahhütleri göstermez.


2
İlk ebeveynin genellikle yanlış olanı olduğuna dikkat edilmelidir. Çünkü genellikle kişi sadece üzerinde çalıştıkları her şeye doğru çeker ve işlerini birinci ebeveyn ve ikinciyi ustalaştırır.
Jan Hudec

1
@JanHudec: Aslında, bu :-) bağlıdır. İşi yapan kişi birleştirirse, evet. Birleştirme daha sonra gerçekleşirse, belki de bir incelemeden sonra, gözden geçirenin kaptanı teslim almış ve özellik dalını kaptanla birleştirmiş, test etmiş ve itmiş olması daha olasıdır.
sleske

5

Şube Geçmişini şununla takip et: --no-ff

Git'te, bir taahhüdün ataları vardır, ancak bir "dal" aslında sadece bir gelişim çizgisinin şu anki başkanıdır. Başka bir deyişle, bir taahhüt, zaman zaman çalışma ağacının bir anlık görüntüsüdür ve aynı anda herhangi bir sayıda şubeye ait olabilir. Git dallamayı diğer DVCS'lere kıyasla bu kadar hafif yapan şeyin bir parçası.

Git taahhütleri şube bilgilerini taşımaz çünkü Git geçmişi için gerekli değildir. Ancak, hızlı ileri almayan birleşmeler, hangi şubenin birleştirildiği hakkında kesinlikle ek bilgi taşıyabilir. Her zaman --no-ffbayrağı birleştirmelerinize ileterek geçmişinizin bu bilgileri içermesini sağlayabilirsiniz . git-merge (1) diyor ki:

   --no-ff
       Create a merge commit even when the merge resolves as a
       fast-forward. This is the default behaviour when merging an
       annotated (and possibly signed) tag.

Bu genellikle aşağıdakine benzer bir birleştirme iletisi oluşturur Merge branch 'foo', böylece tipik olarak aşağıdakine benzer bir çizgiyle "ata dalları" hakkında bilgi bulabilirsiniz:

$ git log --regexp-ignore-case --grep 'merge branch'

Teşekkürler, ama bu (çoğunlukla) soruma cevap vermiyor. Orijinal şubeyi bulmak için başka hangi yolların olduğunu sormuyorum, ancak bilgilerin neden normal meta veriler olarak dahil edilmediğini - daha çok bir tasarım sorusudur.
sleske

1
@sleske Sanırım cevabım duyarlıydı: Git izlemiyor çünkü Git geçmişinin buna ihtiyacı yok; Bundan daha temel olduğunu sanmıyorum. Özellikler için kaynağa bakmanız gerekir, ancak tarih geçerli dalın ucundan geriye doğru etkili bir şekilde hesaplanır. Bunu her zaman dallara birinci sınıf nesneler olarak davranan diğer DVCS'lerle karşılaştırabilir ve bu tasarım felsefesini daha iyi beğenip beğenmediğinizi görebilirsiniz. YMMV.
CodeGnome

1
Sonuncusu olmalı git log --merges.
Dan

3

En basit cevap, şube isimlerinin geçici olmasıdır. Ya bir dalı ( git branch -m <oldname> <newname>) yeniden adlandırsaydınız ? O şubeye karşı yapılan tüm taahhütlere ne olurdu? Ya da iki kişinin farklı yerel depolarda aynı ada sahip şubeleri varsa?

Git'te anlamı olan tek şey, taahhüdün kendisinin sağlama toplamıdır. Bu temel izleme birimidir.

Bilgi orada, sadece siz istemiyorsunuz ve tam olarak orada değil .

Git her şubenin başının sağlama toplamını saklar .git/refs/heads. Örneğin:

... /. git / refs / kafaları $ ls testi 
-rw-rw-r-- 1 michealt michealt 41 Eyl 30 11:50 testi
... /. git / refs / kafaları $ cat testi 
87111111111111111111111111111111111111d4

(evet, benim git sağlama toplamlarımı toparlıyorum, bu özel değil, ama kazara bir şey sızdırması gerekmediği anlara baktığım özel depolar).

Buna bakarak ve bir ebeveyn veya ebeveyn ebeveyn veya ebeveyn ebeveyn olarak sahip olduğu her bir taahhüdü izleyerek ... verilen bir taahhüdün hangi dallarda olduğunu öğrenebilirsiniz. Bu sadece oluşturulacak büyük bir grafik.

Özel olarak bir şubenin adının (yukarıda belirtildiği gibi değişebilen) saklanması, bir taahhüdün kendisinde olduğu durumlarda, ona yardımcı olmayan taahhütte ek yük vardır. Taahhüdün ebeveynlerini veya mallarını saklayın.

Git log komutunu uygun bayrakla çalıştırarak dalları görebilirsiniz.

git log --branches --source --pretty = oneline --graph
git log --all --source --pretty = oneline --graf

Bunun için ne istediğinizi seçmenin birçok farklı yolu vardır - git log belgelerine bakın - -allbölüm ve takip eden birkaç seçenek.

* 87111111111111111111111111111111111111d4 testi 'test1' dalını teste birleştir
| \  
| * 42111111111111111111111111111111111111e8 test1 güncellemesi: malzeme ekle
* | dd11111111111111111111111111111111111159 test Birleştirme dalı 'test3' teste alındı
| \ \  

Bu 'test', 'test1' ve 'test2' bunların taahhüt edildiği dallardır.

Git log belgelerinin çok büyük olduğunu ve neredeyse istediğiniz her şeyi elde etmenin oldukça mümkün olduğunu unutmayın.


3

Git komutları neden oluşturuldukları dalın adını içermiyor?

Sadece bir tasarım kararı. Bu bilgilere ihtiyacınız varsa, bunu tek bir depoda uygulamak için bir ready-commit-msg veya commit-msg kancası ekleyebilirsiniz.

BitKeeper felaketinden sonra Linus Torvalds, Linux çekirdek geliştirme sürecine uyacak şekilde git geliştirdi. Orada, bir yama kabul edilene kadar, revize edilir, düzenlenir, birkaç kez cilalanır (hepsi Posta yoluyla), imzalanır (= bir taahhüt düzenlenir), kiraz seçilir, teğmen dallarında dolaşır, belki de sık sık yeniden düzenlenir, daha fazla düzenleme, kiraz -Nihayetinde Linus tarafından akıntıya karışana kadar devam eder.

Böyle bir iş akışında belirli bir taahhüdün kaynağı olmayabilir ve çoğu zaman git dağıldıkça komik şube adlarına sahip bazı önemsiz özel rasgele depodaki bazı geçici hata ayıklama dalında bir taahhüt oluşturulur.

Belki de bu tasarım kararı tesadüfen gerçekleşti, ancak Linux çekirdek geliştirme süreciyle tam olarak eşleşiyor.


2

Çünkü Git'te , özellik dalı birleştirildiğinde "kahve yap" gibi taahhütler her iki dalın bir parçası olarak kabul edilir . Bunu kontrol etmek için bir komut bile var:

% git branch --contains @
  feature/make-coffee
  master

Ayrıca, şubeler ucuz, yerel ve eterik; bunlar kolayca eklenebilir, kaldırılabilir, yeniden adlandırılabilir, aktarılabilir ve sunucudan silinebilir.

Git, her şeyin yapılabileceği ilkesini izler , bu nedenle bir dalı uzak bir sunucudan kolayca kaldırabilir ve geçmişi kolayca yeniden yazabilirsiniz.

Diyelim ki 'usta' dalındayım ve iki taahhütte bulundum: 'kahve yap' ve 'süt ve şeker ekle', sonra bunun için yeni dal kullanmaya karar verdim, bu yüzden 'master'ı' başlangıç ​​noktasına sıfırladım /usta'. Sorun değil, tüm tarih hala temiz: 'kahve yap' ve 'süt ve şeker ekle' ustanın bir parçası değil, sadece özellik / kahve yap.

Mercurial tam tersidir; bir şeyleri değiştirmek istemiyor. Şubeler kalıcıdır, yeniden yazma geçmişi kaşlarını çatmıştır, bir dalı sunucudan silemezsiniz.

Kısacası: Git her şeyi yapmanıza izin verir, Mercurial işleri kolaylaştırmak ister (ve istediğinizi yapmanıza gerçekten zorlaştırı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.