Git pull neden varsayılan olarak yeniden yapılandırma yerine bir birleştirme yapıyor?


71

Aşağıdaki durumu göz önünde bulundurun:

  • Git deposunun bir klonuna sahipsiniz
  • Bazı yerel taahhütleriniz var (henüz hiçbir yere itilmemiş olan taahhütler)
  • Uzak depoda henüz uzlaştırılmadığınız yeni taahhütler var.

Yani böyle bir şey:

Unmerged taahhütleri

Yürütürseniz git pullvarsayılan ayarlarla, böyle bir şey çıkacak:

birleştirme taahhüdü

Bunun nedeni Git'in bir birleşme gerçekleştirmesidir.

Yine de bir alternatif var. Çekme yerine yeniden yapmak için çekme söyleyebilir:

git pull --rebase

ve bunu alacaksın:

rebased

Bence, yeniden yapılanmış sürüm, çoğunlukla hem kodunuzu hem de geçmişi temiz tutmaya odaklanan çok sayıda avantaja sahip, bu yüzden git'in varsayılan olarak birleştirme yaptığı gerçeğini biraz şaşırdım. Evet, yerel taahhütlerinizin karmaları değişecek, ancak karşılığında aldığınız basit geçmiş için ödenmesi gereken küçük bir fiyat gibi görünüyor.

Hiçbir şekilde, bunun bir şekilde kötü ya da yanlış bir varsayılan olduğunu önermiyorum. Birleşmenin neden varsayılan olarak tercih edilmesinin nedenleri hakkında düşünmekte zorlanıyorum. Neden seçildiğine dair bir fikrimiz var mı? Varsayılan olarak daha uygun hale getiren faydalar var mı?

Bu sorunun temel motivasyonu, şirketimin, geliştiricilerin daha önce birlikte çalışmadıkları bir depoya yaklaşmalarını kolaylaştırmak için depolarımızı nasıl organize ettiğimiz ve yönettiğimiz konusunda bazı temel standartlar (umarım, daha çok kılavuz ilkeler) oluşturmaya çalışıyor olmasıdır. Genelde bu tür bir durum için yeniden düzenlemeliyiz (ve muhtemelen geliştiricilerin global konfigürasyonlarını varsayılan olarak yeniden düzenlemelerini öneririm) önermekle ilgileniyorum, ancak buna karşı olsaydım, kesinlikle yeniden düzenlemenin neden olmadığını soruyor olurdum. t Çok büyükse, varsayılan. Bu yüzden eksik bir şey olup olmadığını merak ediyorum.

Bu sorunun bir kopyası olduğu öne sürüldü. Bu kadar çok web sitesi neden “git birleştirme” yerine “git rebase” ı tercih ediyor? ; Ancak, bu soru biraz bunun tersidir . Yeniden birleştirme yerine yeniden kazanmanın faydalarını tartışırken, bu soru yeniden kazanmaya göre birleşmenin yararlarını soruyor. Buradaki cevaplar bunu yansıtır, birleşme ve yeniden kazanmanın yararları ile ilgili sorunlara odaklanır.



Diğer bir problem ise, yanlışlıkla ustalaşmaya karar verirseniz, birleştirilmiş bir çekme işlemi yaparsanız, birleşme normal görünse de, iki ustanın senkronizasyondan çıkabileceğidir. Bu yüzden benim çekme takma adı --ff-only içerir.
Ixrec

sourcetree grafik görüntüsünü değiştirirse, farklı şekilde yeniden açmalar / birleştirmeler gösterir, birleşmeye mi geçersiniz?
Ewan

1
@Ewan SourceTree bunun grafik görüntüsünü değiştirmemelidir. Grafiği doğru olarak temsil eder.
jpmc26

4
Dupe seçmenleri için, lütfen kabul ettiğim yanıttaki içeriğin, yinelenen iddiada bulunduğunuz kesinlikle bulunmadığını unutmayın.
jpmc26

Yanıtlar:


56

Bu kararı veren kişiden haber almadan neden birleştirme işleminin varsayılan olduğunu bilmek zordur.

İşte bir teori ...

Git, her çekiş için - rebase yapmanın uygun olmadığını varsayamaz. Kulağa nasıl geldiğini dinleyin. "Her çekilişi yeniden yap." Çekme isteklerini veya benzerini kullanırsanız sadece yanlış sesler. Çekme isteğini yeniden verir misiniz?

Git'i sadece merkezi kaynak kontrolü için kullanmayan bir ekipte ...

  • Yukarı ve aşağı akıştan çekebilirsiniz. Bazı insanlar aşağı havzadan, katkıda bulunanlardan vb. Çok fazla şey yapıyor.

  • Diğer geliştiricilerle yakın işbirliği içinde, onlardan veya paylaşılan bir konu dalından çekerek ve bazen de yukarı akıştan güncellenen özellikler üzerinde çalışabilirsiniz. Her zaman yeniden doğarsanız, eğlenceli çatışma döngülerinden bahsetmek yerine, ortak geçmişi değiştirirsiniz.

Git, herkesin tek bir merkezi depoya girmediği ve zorlamadığı büyük bir dağınık ekip için tasarlandı . Yani varsayılan mantıklı.

  • Yenilemenin ne zaman uygun olduğunu bilmeyen geliştiriciler varsayılan olarak birleştirilecektir.
  • Geliştiriciler istedikleri zaman yeniden kazanabilirler.
  • Çok fazla çeken ve çok fazla çeken müşteriler, kendilerine en uygun olanı alırlar.

Niyet kanıtı için, Linus Torvalds'ın iyi bir e-postanın, ne zaman yeniden başlamaması gerektiği konusundaki görüşlerini içeren bir link. Dri-devel git çekme e-postası

Tüm diziyi izlerseniz, bir geliştiricinin başka bir geliştiriciden çekmekte olduğunu ve Linus'un ikisinden de çekmekte olduğunu görebilirsiniz. Fikrini oldukça netleştiriyor. Muhtemelen Git'in varsayılanlarına karar verdiğinden, bu nedenini açıklayabilir.

Artık pek çok kişi Git'i merkezi bir şekilde kullanıyor; burada küçük bir ekipteki herkes yalnızca bir yukarı akışlı merkezi depodan çekilir ve aynı uzaktan kumandaya itilir. Bu senaryo, yeniden yapılandırmanın iyi olmadığı, ancak genellikle bunları ortadan kaldırmadığı durumlardan bazılarını önler.

Öneri: Varsayılanı değiştirme politikası yapmayın. Git'i büyük bir geliştirici grubuyla bir araya getirdiğinizde, bazı geliştiriciler Git'i o kadar derin anlamaz (kendim dahil). Google, SO’ya gidecekler, yemek kitabı tavsiyesi alacaklar ve ardından neden bazı şeylerin işe yaramadığını merak edecekler, örneğin neden git checkout --ours <path>dosyanın yanlış sürümünü alıyor? Yerel ortamınızı her zaman revize edebilir, takma adlar vb. Zevkinize uygun hale getirebilirsiniz.


5
Varsayılanı değiştirmediği için +1 - kendi git iş akışınızı döndürmek yerine , var olanı yakalamak daha iyidir (örneğin, Atlassian atlassian.com/git/tutorials/comparing-workflows/… tarafından belgelenenlerden herhangi biri )
Rob Church

1
Cevap için teşekkürler. Aşağıdan çekme hakkında bilgi, eksik olan şeydi. Ayrıca, ilginç bir şekilde, verdiğiniz bağlantı tam olarak ulaşmak istediklerimi teşvik eder: “İnsanlar özel ağaçlarını (kendi işlerini) yeniden inşa edebilir (ve muhtemelen gerekir) ”.
jpmc26

2
@jpmc Harika. Aslında. Özel ağaçları yeniden asmak, ortak tarihin çok fazla dikkatini çeken pisliği engelleyebilir. Yaptım. Ne zaman yapmamamız gerektiği üzerine netlik önemlidir.
joshp

"geliştiricilerin bazıları Git'i o kadar derinden anlamıyor". Rebase, Git'in süper bir fantezi ("derin", vb.) Özelliği değildir. Bu şeyi gerçekten zor anlıyor musun? Bunun, dev'i yetersiz olarak adlandırmak için bir tetikleyici olması gerektiğini düşünüyorum.
Victor Yarema

15

Gitase sayfasını rebase için okursanız, der ki :

Başkalarının üzerinde çalışmış olduğu bir dalın yeniden yazılması (veya başka bir yeniden yazma şekli) kötü bir fikirdir: altından gelen herkes geçmişini elle düzeltmek zorunda kalır. Bu bölüm, düzeltmenin akış yönünün bakış açısından nasıl yapıldığını açıklar. Bununla birlikte, asıl sorun, ilk başta yukarı havayı yeniden asmaktan kaçınmak olacaktır.

Bence, rebase'ı hiç kullanmamanın bir neden olarak yeterince iyi olduğunu, otomatik olarak her çekiliş için yapabileceğini söylüyor. Bazı insanlar yeniden yapılanmanın zararlı olduğunu düşünüyor . Belki de hiçbir zaman oraya gitmemeliydi, çünkü göründüğü kadarıyla tarihi güzelleştirmek, tek işi asıl işi geçmişi korumak olan hiçbir SCM'de gerekli olmayan bir şey.

'Tarihi temiz tutmak' derken, yanıldığını düşün. Daha iyi görünebilir, ancak revizyon geçmişini tutmak için tasarlanmış bir araç için, ne olduğunu görebilmeniz için her taahhüdün sürdürülmesi çok daha kolaydır. Tarihi daha sonra sterilize etmek, patinayı parlatmak, zengin bir antikayı parlak bir repro gibi göstermek gibi.


3
@Ewan IMHO "çalışmıyor ama güzel görünüyor" BT moda endüstrisi için tamamen rezerve edilmesi gereken bir şey. IMHO git, stilin maddeden daha önemli olduğunu düşünmek için çok fazla insanı teşvik ettiği için onu kaldırmalı.
gbjbaanb

12
Tarihinizi temiz tutmanın yararsız olduğu konusundaki önerinize itiraz ediyorum. Değil. Havuz geçmişi, insan tüketimine yöneliktir ve bu nedenle onu okunabilir hale getirmede çok fazla değer vardır. Özel kullanım durumumda, geliştirici olmayan Proje Yöneticilerinin geçmişi okuyabileceklerini düşünüyoruz. Temiz bir tarih ancak bununla ilgili yardımcı olabilir ve bu, kod tabanını hiç görmemiş ve belirli bir kod alanında ne olduğunu anlamak ve dalmak ve bir hatayı düzeltmek zorunda olan yeni bir geliştiriciye yardımcı olabilir.
jpmc26

3
İlk önce bir makine tarafından çalıştırılması gereken kod var (muhtemelen derlendikten sonra). Yukarıdaki felsefeyi uygulayarak, kodun okunabilirliğinin önemli olmadığı sonucuna varacağız çünkü hiçbir okunabilirlik kodu anlama zorluğunu çözemez. Hiçbir şeyin ezilmesi gerektiğini önermedim. Sadece çok fazla geçiş yoluna ayrılan karmaşık bir grafiğin takip edilmesinin zor olduğunu söylüyorum, bu yüzden tarihinizi oldukça temiz tutmak için biraz yatırım yapmaya değer. Ayrıca doğrusal bir geçmişin, suçlama ve bisect gibi git araçlarından yararlanmaya daha elverişli olduğunu unutmayın.
jpmc26

6
Dokümanlar "yeniden dirilme" deme. Diyor ki, " diğer insanların akışındaki değişiklikleri yeniden gözden geçirme ". Bu ikisi arasında bir fark dünyası var. Linus , kabul edilen cevabın linkinde de görüldüğü gibi, tarihin düzenlenmesi için bazı yeniden doğuşlar önermektedir . Ve herhangi bir araç, hangi taahhütlerin önemsiz olduğunu nasıl bilebilir (özellikle araçlar doğrusal olmayan bir tarihi analiz etmekte zorlanıyorsa!) Ve hangisine bağlı kalmayı istediğinizi nasıl bileceksiniz? Dogmatik bir uç noktaya özgü bir durum hakkında bir uyarı alıyorsunuz.
jpmc26

4
Bir geliştiricinin yapmış olduğu her taahhüdü içeriyorsa, kesinlikle "gözden geçirme geçmişini sakla" istemezsiniz. Bu mantığı takiben, geri alma tuşuna her basıldığında kodun orijinal sürümünü de kaydetmeliyiz. Her taahhüt , tüm projeyi hala istikrarlı durumda tutan minimum ve eksiksiz bir değişiklik olmalıdır . Orijinal taahhüdünüzün daha sonra hatalı olduğu tespit edilirse, taahhüdünüzü yeniden oluşturmak / düzenlemek / değiştirmek çok daha iyidir. Bununla birlikte, ayrıca bkz. Mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html
Mikko

12

Haklısın, yalnızca bir tane yerel / değiştirilmiş havuzunuz olduğunu varsayalım. Bununla birlikte, örneğin ikinci bir yerel bilgisayar olduğunu düşünün.

Yerel / değiştirilmiş kopyanız başka bir yere bastırıldığında, yeniden düzenleme işlemi bu kopyaları mahveder. Tabii ki, zorlamaya zorlayabilirsin, ama bu hızla karmaşıklaşıyor. Bunlardan bir veya daha fazlasının tamamen yeni bir taahhüdü varsa ne olur?

Gördüğünüz gibi, durumsal, ancak temel strateji özel olmayan / işbirliği vakalarında çok daha pratik görünüyor.


İkinci bir fark: Birleştirme stratejisi açık ve zaman tutarlı bir yapıyı koruyacaktır. Yeniden yapılanmaların ardından, eski taahhütlerin daha yeni değişiklikleri takip etmesi muhtemeldir, bu da tüm geçmişi ve akışını anlaşılmasını zorlaştırır.


1
“Yeniden yapılanmalardan sonra, eski taahhütlerin daha yeni değişiklikleri takip etmesi çok muhtemeldir” - bu da birleşme ile olur, bu yüzden bunu anlamak için güzel grafiğe ihtiyacınız olabilir. Bir taahhütte bulunma süresi, onu bu şubeye getiren birleşmeden çok önce olabilir.
Steve Jessop,

6

Bunun en büyük nedeni muhtemelen varsayılan davranışın halka açık depolarda "sadece çalışması" gerektiğidir. Zaten başkalarının birleştiği tarihi yeniden inşa etmek onların başını belaya sokacak. Özel reponuz hakkında konuştuğunuzu biliyorum, ancak genel olarak konuşmak Git özel veya kamu olanı bilmiyor veya umursamıyor, bu nedenle seçilen varsayılan her ikisi için de varsayılan olacak.

git pull --rebaseÖzel repo'mda oldukça fazla kullanıyorum , ancak orada bile potansiyel bir dezavantaj var; bu, HEADaslında üzerinde çalıştığım gibi artık ağacımı yansıtmıyor.

Büyük bir örnek için, her zaman testler yaptığımı ve bir taahhütte bulunmadan önce geçmelerini sağladığımı varsayalım. Bunu yaptıktan sonra daha az ilgiliydi git pull --rebase, çünkü artık her bir komisyonumdaki ağacın testleri geçtiği doğru değil. Sürece değişiklikler hiçbir şekilde karışmaz, ben çekin kodu test edilmiştir, o zaman muhtemelen o kadar olur testinde başarılı ama hiç denemedim çünkü biz bilmiyoruz. Sürekli entegrasyon iş akışınızın önemli bir parçasıysa, CIed olan bir repodaki herhangi bir rebase rahatsız edicidir.

Bunu gerçekten umursamıyorum, ancak bazı insanları rahatsız ediyor: Git'teki tarihlerinin gerçekten üzerinde çalıştıkları kodu yansıtmasını tercih ediyorlardı (ya da itdikleri zaman, bazı kullanımlardan sonra gerçeğin basitleştirilmiş bir versiyonu) "düzeltme").

Özellikle, bu sorunun Linus'un varsayılan olarak yeniden düzenleme yerine birleştirmeyi seçmesinin nedeni olup olmadığını bilmiyorum. Karşılaştımadığım başka dezavantajlar olabilir. Ancak görüşünü kodda ifade etmekten çekinmediğinden, çok fazla düşünmek istemeyen insanlar için (ve özellikle halk arasında çalışanlar için) uygun bir iş akışı olduğuna inanıyorum. özel bir depodan daha). Güzel grafikte paralel çizgileri kullanmak, paralel gelişmeyi olduğu gibi temsil etmeyen temiz düz çizgiden yana, sizinki olsa bile muhtemelen en büyük önceliği değildir :-)

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.