Git neden varsayılan olarak hızlı ileri birleştirme yapar?


641

Civadan geldiğimde, özellikleri düzenlemek için dalları kullanıyorum. Doğal olarak, bu iş akışını tarihimde de görmek istiyorum.

Git ile yeni projeme başladım ve ilk özelliğim bitti. Özelliği birleştirirken git'in hızlı ileri kullandığını fark ettim, yani değişikliklerimi mümkünse doğrudan ana şubeye uygular ve şubemi unutur.

Geleceği düşünmek için: Bu proje üzerinde çalışan tek kişi benim. Git'in varsayılan yaklaşımını (hızlı ileri birleştirme) kullanırsam geçmişim dev bir ana dalla sonuçlanır. Kimse her özellik için ayrı bir dal kullandığımı bilmiyor, çünkü sonunda sadece o devasa ana dalım olacak. Bu profesyonelce görünmeyecek mi?

Bu nedenle hızlı ileri birleştirme istemiyorum ve bunun neden varsayılan olduğunu göremiyorum. Ne bu kadar iyi?


38
Not: ayrıca sandofsky.com/blog/git-workflow.html adresine bakın ve no-ffikiye veya suçu kıran "kontrol noktası taahhütleri" ile " 'den kaçının .
VonC

15
bir adam projesinde git kullanarak pişman mı?
HaveAGuess

27
Kesinlikle hayır! Çalışma klasörümde git kullandığım 7 tek kişilik projem var. Şunu yeniden ifade edeyim: Bu soruyu sorduğumdan beri birçok projeye başladım ve hepsi git ile versiyonlandı. Bildiğim kadarıyla, sadece git ve mercurial, yerel versiyonlamayı destekliyor, bu benim alıştığımdan beri benim için gerekli. Kurulumu kolaydır ve her zaman tüm geçmişe sahip olursunuz. Grup projelerinde daha da iyidir, çünkü devam eden çalışma kodunuza kimseye müdahale etmeden iş yapabilirsiniz. Ayrıca git'in bir gereklilik olduğu bazı projelerimi (örneğin mikro-optparse) paylaşmak için github kullanıyorum.
Florian Pilz

7
@Cawas true, -no-ffnadiren iyi bir fikirdir, ancak yine de ana dalda sadece bir taahhüt kaydederken bir özellik-dahili tarih tutmaya yardımcı olabilir. Bu, ana dalda ilerlemesini zaman zaman birleştirdiğinizde uzun özellik geçmişi için mantıklıdır.
VonC 16:12

12
Bu arada, "Bu [doğrusal bir dal geçmişi] profesyonelce görünmüyor mu?" Varsayılan olarak bir kaynak kodu sistemi kullanma konusunda profesyonel olmayan bir şey yoktur. Bu profesyonellik ile ilgili değil. Bu, hangi dallanma felsefesinin size abone olduğunuzu belirlemekle ilgilidir. Örneğin @VonC, sandofsky'nin makalesine bağlandı ve burada ileriye doğru üstün bir yaklaşım olarak şampiyon oldu. Doğru ya da yanlış değil, sadece farklı bağlamlar için farklı felsefeler.
Marplesoft

Yanıtlar:


718

Hızlı ileri birleştirme, kısa ömürlü dallar için mantıklıdır, ancak daha fazlası karmaşık bir tarihte , hızlı ileri birleştirme, tarihin anlaşılmasını kolaylaştırabilir ve bir grup taahhüdü geri almayı kolaylaştırabilir.

Uyarı : Hızlı yönlendirmenin potansiyel yan etkileri de vardır. Lütfen https://sandofsky.com/blog/git-workflow.html dosyasını inceleyin, ikiye veya suçu kıran "kontrol noktası taahhütleri" ile "no-ff" kullanmaktan kaçının ve varsayılan yaklaşımınız olup olmadığını dikkatlice düşünün master.

alternatif metin
(Dan nvie.com , Vincent Driessen , post " Başarılı Git dallanma modeli ")

Geliştirilmiş bir özelliği geliştirme üzerine dahil etme

Biten özellikler, önümüzdeki sürüme eklenecek şekilde geliştirme dalında birleştirilebilir:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

--no-ffBayrak birleştirme ileri sarma ile yapılabilir bile, her zaman yeni bir nesne işlemek oluşturmak için birleştirme neden olur. Bu, bir özellik dalının tarihsel varlığı hakkında bilgi kaybını önler ve birlikte özelliği ekleyen tüm taahhütleri gruplandırır.

Jakub Narębski da söz yapılandırmamerge.ff :

Varsayılan olarak Git, geçerli taahhüdün torunu olan bir taahhüt birleştirilirken fazladan birleştirme taahhüdü oluşturmaz. Bunun yerine, mevcut dalın ucu hızlı iletilir.
Olarak ayarlandığında false, bu değişken Git'e böyle bir durumda fazladan birleştirme taahhüdü oluşturmasını söyler ( --no-ffkomut satırından seçeneği vermekle eşdeğerdir ).
' only' Olarak ayarlandığında , yalnızca bu tür hızlı ileri birleştirme işlemlerine izin verilir ( --ff-onlykomut satırından seçeneğin verilmesine eşdeğerdir ).


Hızlı ileri sarma varsayılan ayardır çünkü:

  • Kısa ömürlü dalların Git'te kullanımı ve kullanımı çok kolaydır
  • kısa ömürlü dallar genellikle o dalda serbestçe yeniden düzenlenebilen birçok taahhüdü izole eder
  • bu taahhütler aslında ana dalın bir parçasıdır: bir kez yeniden düzenlendikten sonra ana dal onları dahil etmek için hızlı bir şekilde yönlendirilir.

Ancak, bir konu / özellik dalında yinelenen bir iş akışı bekliyorsanız (yani birleştiririm, bu özellik dalına geri dönüp daha fazla taahhüt ekliyorum), o zaman ana dalda yalnızca birleştirmeyi dahil etmek yararlı olur. özellik dalının tüm ara taahhütleri.

Bu durumda, bu tür bir yapılandırma dosyasını ayarlayabilirsiniz :

[branch "master"]
# This is the list of cmdline options that should be added to git-merge 
# when I merge commits into the master branch.

# The option --no-commit instructs git not to commit the merge
# by default. This allows me to do some final adjustment to the commit log
# message before it gets commited. I often use this to add extra info to
# the merge message or rewrite my local branch names in the commit message
# to branch names that are more understandable to the casual reader of the git log.

# Option --no-ff instructs git to always record a merge commit, even if
# the branch being merged into can be fast-forwarded. This is often the
# case when you create a short-lived topic branch which tracks master, do
# some changes on the topic branch and then merge the changes into the
# master which remained unchanged while you were doing your work on the
# topic branch. In this case the master branch can be fast-forwarded (that
# is the tip of the master branch can be updated to point to the tip of
# the topic branch) and this is what git does by default. With --no-ff
# option set, git creates a real merge commit which records the fact that
# another branch was merged. I find this easier to understand and read in
# the log.

mergeoptions = --no-commit --no-ff

OP yorumlarda şunları ekliyor:

[Kısa ömürlü] dallar için ileriye doğru bir anlam görüyorum, ama varsayılan eylemi yapmak git'in sizi [kısa ömürlü] dallara sahip olduğunu varsayar. Makul?

Jefromi cevapları:

Bence şube ömrü kullanıcıdan kullanıcıya büyük farklılıklar gösteriyor. Bununla birlikte, deneyimli kullanıcılar arasında, muhtemelen çok daha kısa ömürlü şubelere sahip olma eğilimi vardır.

Bana göre, kısa ömürlü bir branş, belirli bir işlemi kolaylaştırmak için (yeniden basma, muhtemelen veya hızlı yama ve test etme) oluşturmak için oluşturduğum ve sonra bitirdiğimde hemen silin.
Bu, büyük olasılıkla çatallandığı konu dalına emilmesi ve konu dalının bir dal olarak birleştirilmesi gerektiği anlamına gelir . Kimsenin bu özelliği uygulayan bir dizi taahhüt oluşturmak için dahili olarak ne yaptığımı bilmesine gerek yok.

Daha genel olarak şunu ekliyorum:

gerçekten geliştirme iş akışınıza bağlıdır :

  • doğrusal ise, bir dal mantıklıdır.
  • Özellikleri izole etmeniz ve üzerinde uzun süre çalışmanız ve tekrar tekrar birleştirmeniz gerekiyorsa, birkaç dal mantıklıdır.

Bkz. " Ne zaman dallanmalısınız? "

Aslında, Mercurial şube modelini düşündüğünüzde, her depoda çekirdek bir daldır ( anonim kafalar, yer imleri ve hatta adlandırılmış dallar oluşturmanıza rağmen )
Bkz. "Git ve Mercurial - Karşılaştır ve Kontrast" .

Mercurial, varsayılan olarak, terminolojisinde "kafa" olarak adlandırılan anonim hafif kodlayıcılar kullanır.
Git, uzak depodaki dalların adlarını uzaktan izleme dallarının adlarıyla eşleştirmek için bilinçli olarak adlandırılan dallar kullanır.
Git, sizi şubeleri adlandırmaya zorlar (" bağımsız bir HEAD " adı verilen bir durum olan tek bir adlandırılmamış dal hariç ), ancak bunun konu dalı iş akışı gibi dal ağır iş akışlarıyla daha iyi çalıştığını düşünüyorum. tek bir depo paradigmasında çoklu dallar.


Vay canına, hızlıydı. ;) --No-ff seçeneğini biliyorum, ancak hızlı ileri sarma özelliğini yalnızca özellikimi bozduktan sonra öğreniyorum. Kısa yaşayan dallar için ileriye doğru bir anlam görüyorum, ancak varsayılan eylem aracı yapmak, git'in bu tür kısa yaşam dallarına sahip olduğunuzu varsayar. Makul?
Florian Pilz

@Florian: Bunun sürece ilişkin makul bir görüş olduğuna inanıyorum. Master için birleştirme yönetmek istediğiniz şekilde ayarlayacak bir yapılandırma örneği ekledim.
VonC

Teşekkürler, yapılandırma dosyası bu tür gotchas önlemek için yardımcı olmalıdır. :) Bu yapılandırmayı yalnızca "git config branch.master.mergeoptions '--no-ff'" ile yerel olarak uyguladı
Florian Pilz

2
@BehrangSaeedzadeh: yeniden baslama başka bir konudur (bu sayfada onurlandırılmamış olan): featureşubenizi halka açık bir repoya itmedikçe, istediğiniz kadar yeniden temellendirebilirsiniz master. Bkz. Stackoverflow.com/questions/5250817/…
VonC

4
@BehrangSaeedzadeh: Bir rebase tek başına bir tarihi lineer yapmaz. Öyle nasıl size değişiklikler entegre featureiçine dal arka mastero markaların doğrusal veya olmasın tarihini söyledi. Basit bir hızlı ileri birleştirme onu doğrusal hale getirir. Bu, ileriye doğru birleştirme featureişleminden önce bu dalın geçmişini temizlediyseniz ve stackoverflow.com/questions/7425541/… ' da belirtildiği gibi yalnızca önemli taahhütler bırakırsanız mantıklıdır .
VonC

42

Bana bir üzerinde biraz genişletelim VonC 'ın çok kapsamlı bir cevap :


Birincisi, doğru hatırlıyorsam, Git'in varsayılan olarak hızlı ileri durumda birleştirme taahhütleri oluşturmadığı gerçeği, bu iki depoları senkronize etmek için karşılıklı çekmenin kullanıldığı tek dallı "eşit depolar" düşünülmesinden kaynaklanmıştır (a iş akışı, "Git Kullanıcı El Kitabı" ve "Örneğe Göre Sürüm Kontrolü" de dahil olmak üzere çoğu kullanıcı dokümanında ilk örnek olarak bulabilirsiniz. Bu durumda, tam olarak gerçekleşen dalı birleştirmek için çekmeyi kullanmazsınız, diğer işlere ayak uydurmak için kullanırsınız. Gelecekte saklanan ve depoda saklanan ve saklanan bir senkronizasyon yaptığınızda geçici ve önemsiz bir gerçeğe sahip olmak istemezsiniz.

Özellik şubelerinin ve tek bir depoda birden çok şubeye sahip olmanın kullanışlılığının ancak daha sonra geldiğini ve VCS'nin iyi birleştirme desteği ile daha çeşitli kullanımıyla ve çeşitli birleştirme tabanlı iş akışlarını deneyerek geldiğini unutmayın. Bu nedenle, örneğin Mercurial, eski "Mercurial: The Definitive Guide" (Eski Kılavuz):


Aşağıdaki İkincisi, en iyi uygulamaları kullanmanın özelliği dalları özelliği dalları, (genellikle son sürümden) kararlı sürümden tüm başlangıç muktedir olmalıdır yani o, kiraz-almak ve seçerek tarafından birleştirme hangi özelliği dalları içerecek şekilde hangi özellikleri seçmek size genellikle hızlı ileri bir durumda değildir ... bu da bu konuyu tartışıyor. İlk dalı birleştirirken gerçek bir birleştirme oluşturma konusunda endişelenmeniz ve hızlı ilerlememeniz gerekir (tekli değişiklikleri doğrudan 'master'a koymadığınız varsayılarak); diğer tüm birleşmeler elbette hızlı ileri olmayan bir durumdadır.

HTH


Kararlı sürümlerden gelen özellik dallarıyla ilgili olarak: Bir sonraki sürüm için geliştireceğim bir özellik, zaten geliştirip master ile birleştirdiğim başka bir özellik için yapılan değişikliklere bağlıysa ne olur? Elbette bu, bu ikinci özellik dalını master'dan oluşturmak zorunda olduğum anlamına mı geliyor?
dOxxx

1
@dOxxx: Evet, istisnalar vardır, örneğin bir kolun diğeri üzerine kurulduğu yerler (doğrudan ya da daha önce master ile birleştirildikten sonra).
Jakub Narębski
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.