özet
Varsayılan git pull
olarak, kod geçmişine gürültü ve karmaşıklık katan birleştirme taahhütleri oluşturur. Ayrıca, pull
değişikliklerinizin gelen değişikliklerden nasıl etkilenebileceğini düşünmemeyi kolaylaştırır.
git pull
Komut kadar uzun sadece hızlı ileri birleştirmeyi gerçekleştirir olarak güvenlidir. Eğer git pull
üzere yapılandırılmış sadece hızlı ileri birleştirmeleri yapmak ve ileri sarma birleştirme mümkün olmadığı durumlarda, o zaman Git bir hata ile çıkılacak. Bu, gelen taahhütleri incelemek, yerel taahhütlerinizi nasıl etkileyebileceklerini düşünmek ve en iyi eylem yoluna (birleştirme, yeniden pazarlama, sıfırlama vb.) Karar vermek için bir fırsat verecektir.
Git 2.0 ve daha yenisi ile şunları yapabilirsiniz:
git config --global pull.ff only
varsayılan davranışı yalnızca ileri sarmak için değiştirmek. 1.6.6 ve 1.9.x arasındaki Git sürümleri ile yazma alışkanlığı edinmeniz gerekir:
git pull --ff-only
Ancak, Git'in tüm sürümlerinde git up
böyle bir takma ad yapılandırmanızı öneririz :
git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'
ve git up
yerine kullanmak git pull
. Bu takma adı tercih ederim git pull --ff-only
çünkü:
- Git'in tüm (eski olmayan) sürümleriyle çalışır,
- tüm yukarı akış dallarını getirir (yalnızca üzerinde çalışmakta olduğunuz dal değil) ve
origin/*
artık akış yukarı olmayan eski dalları temizler .
İle ilgili sorunlar git pull
git pull
doğru kullanılırsa fena değil. Git'te yapılan son değişikliklerin birçoğu git pull
düzgün kullanımını kolaylaştırdı , ancak maalesef bir ovanın varsayılan davranışının git pull
birkaç sorunu var:
- tarihte gereksiz doğrusallıklara neden olur
- yukarı doğru kasıtlı olarak yeniden yapılandırılan taahhütleri yanlışlıkla yeniden tanıtmayı kolaylaştırır
- çalışma dizininizi öngörülemeyen şekillerde değiştirir
- başkasının çalışmasını gözden geçirmek için yaptığınız işi duraklatmak
git pull
- uzak dalda doğru şekilde rebase yapmayı zorlaştırır
- uzak depoda silinen şubeleri temizlemiyor
Bu sorunlar aşağıda daha ayrıntılı olarak açıklanmaktadır.
Doğrusal Olmayan Tarih
Varsayılan olarak, git pull
komut çalışmanın git fetch
ardından gelen ile eşdeğerdir git merge @{u}
. Yerel depoda itilmemiş taahhütler varsa, birleştirme kısmı git pull
bir birleştirme taahhüdü oluşturur.
Birleştirme taahhütlerinde doğal olarak kötü bir şey yoktur, ancak tehlikeli olabilirler ve saygıyla davranılmalıdırlar:
- Birleştirme taahhütlerinin incelenmesi doğal olarak zordur. Birleşmenin ne yaptığını anlamak için, tüm ebeveynler arasındaki farklılıkları anlamalısınız. Geleneksel bir fark bu çok boyutlu bilgiyi iyi iletmez. Buna karşılık, bir dizi normal işlemin gözden geçirilmesi kolaydır.
- Birleştirme çakışması çözümü zor ve birleştirme işlemlerinin incelenmesi zor olduğu için hatalar genellikle uzun bir süre algılanmaz.
- Birleşme, düzenli taahhütlerin etkilerini sessizce geçersiz kılabilir. Kod artık artan taahhütlerin toplamı değildir ve gerçekte neyin değiştiği hakkında yanlış anlamalara yol açar.
- Birleştirme taahhütleri bazı sürekli entegrasyon şemalarını bozabilir (örneğin, ikinci ebeveynlerin devam etmekte olan çalışmaları tamamlamadığına işaret ettiği varsayılan kural uyarınca sadece ilk ebeveyn yolunu otomatik olarak oluştur).
Tabii ki birleşme için bir zaman ve bir yer vardır, ancak birleşme ne zaman kullanılmalı ve kullanılmamalıdır anlaşılması deponuzun kullanışlılığını artırabilir.
Git'in amacının bir kod tabanının evrimini paylaşmayı ve tüketmeyi kolaylaştırmak olduğunu, geçmişi tam olarak açıldığı gibi kesin olarak kaydetmemek olduğunu unutmayın. (Eğer katılmıyorsanız, rebase
komutu ve neden yaratıldığını düşünün .) Tarafından oluşturulan birleştirme taahhütleri git pull
başkalarına yararlı anlambilimleri aktarmaz - sadece siz değişikliklerinizi yapmadan önce bir başkasının depoya ittiğini söylerler. Bu birleştirme, başkaları için anlamlı değilse ve tehlikeli olabilirlerse neden taahhütte bulunurlar?
git pull
Birleştirme yerine yeniden taban oluşturmak üzere yapılandırmak mümkündür , ancak bunun da sorunları vardır (daha sonra tartışılacaktır). Bunun yerine, git pull
yalnızca hızlı ileri birleştirme yapacak şekilde yapılandırılmalıdır.
Geri Alınmış Komisyonların Yeniden Sunumu
Birisinin bir dalı yeniden bastığını ve onu zorladığını varsayalım. Bu genellikle olmamalıdır, ancak bazen gerekli olabilir (örneğin, yanlışlıkla taahhüt edilen ve itilen bir 50GiB günlük dosyasını kaldırmak). Tarafından yapılan git pull
birleştirme, yukarı akış dalının yeni sürümünü yerel deponuzda bulunan eski sürümle birleştirir. Sonucu zorlarsanız, zift çatalları ve el fenerleri yolunuza çıkmaya başlayacaktır.
Bazıları asıl sorunun zorlama güncellemeleri olduğunu iddia edebilir. Evet, genellikle mümkün olduğunda zorlamalardan kaçınmak önerilir, ancak bazen kaçınılmazdır. Geliştiriciler zorlayıcı güncellemelerle başa çıkmaya hazır olmalıdır, çünkü bazen olurlar. Bu, eski taahhütlerde sıradan bir yolla körü körüne birleşmemek anlamına gelir git pull
.
Sürpriz Çalışma Dizini Değişiklikleri
Çalışma dizininin veya dizininin git pull
tamamlanana kadar nasıl görüneceğini tahmin etmenin bir yolu yoktur . Başka bir şey yapmadan önce çözmeniz gereken birleştirme çakışmaları olabilir, birisi yanlışlıkla ittiği için çalışma dizininize 50GiB günlük dosyası ekleyebilir, içinde çalıştığınız bir dizini yeniden adlandırabilir, vb.
git remote update -p
(veya git fetch --all -p
) birleştirmeye veya yeniden pazarlamaya karar vermeden önce başkalarının taahhütlerine bakmanıza olanak tanır ve harekete geçmeden önce bir plan oluşturmanıza olanak tanır.
Diğer İnsanların Taahhütlerini Gözden Geçirme Zorluğu
Bazı değişiklikler yapmanın ortasında olduğunuzu ve bir başkasının sadece ittikleri bazı taahhütleri gözden geçirmenizi istediğini varsayalım. git pull
adlı birleştirme (veya rebase) işlemi, çalışma dizini ve dizini değiştirir, yani çalışma dizininizin ve dizininin temiz olması gerekir.
Kullanabilir git stash
ve sonra kullanabilirsiniz git pull
, ancak incelemeyi bitirdiğinizde ne yaparsınız? Bulunduğunuz yere geri dönmek için, oluşturduğunuz birleştirmeyi geri almanız git pull
ve saklamayı uygulamanız gerekir.
git remote update -p
(veya git fetch --all -p
) çalışma dizinini veya dizinini değiştirmez, bu nedenle aşamalı ve / veya değişmemiş değişiklikleriniz olsa bile, herhangi bir zamanda çalıştırılması güvenlidir. Yaptığınız işi duraklatabilir ve üzerinde çalıştığınız taahhüdü saklamak veya bitirmek konusunda endişelenmeden başkasının taahhüdünü inceleyebilirsiniz.git pull
size bu esnekliği vermez.
Uzak bir Dalda Yeniden Oluşturma
Ortak bir Git kullanım modeli, git pull
en son değişiklikleri getirmek için a yapmak ve bunu izleyen git rebase @{u}
birleştirme taahhüdünü ortadan kaldırmak için a yapmaktır git pull
. Bu Git anlatarak tek bir adımda için şu iki adımı azaltmak için bazı yapılandırma seçenekleri vardır bu ortak yeter git pull
yerine birleştirme (bkz bir rebase gerçekleştirmek için branch.<branch>.rebase
, branch.autosetuprebase
vepull.rebase
seçenekleri).
Bir unpushed birleştirme varsa maalesef korumak istediğiniz o taahhüt (örneğin bir içine itilmiş özellik dalı birleştirerek işlemek master
), (bir Rebase-çekme ne git pull
ile branch.<branch>.rebase
karşı kümesi true
), ne de bir birleştirme-çekme (varsayılan git pull
a takiben davranış) rebase işe yarayacak. Çünkü seçenek git rebase
olmadan birleştirme (DAG doğrusallaştırır) ortadan kaldırır --preserve-merges
. Rebase-pull işlemi, birleştirmeleri korumak için yapılandırılamaz ve bir birleştirme-çekmenin ardından birleştirme-çekmenin git rebase -p @{u}
neden olduğu birleşmeyi ortadan kaldırmaz. Güncelleme: Git v1.8.5 eklendi git pull --rebase=preserve
ve git config pull.rebase preserve
. Bunlar yukarı akış taahhütlerini getirdikten sonra git pull
yapılmasına neden olur git rebase --preserve-merges
. ( Funkaster'a teşekkürler -up !)
Silinmiş Şubeleri Temizleme
git pull
uzak depodan silinen dallara karşılık gelen uzaktan izleme dallarını budamaz. Örneğin, biri foo
uzak repodan şubeyi silerse , yine deorigin/foo
.
Bu, kullanıcıların hala aktif olduklarını düşündükleri için yanlışlıkla öldürülen dalları yeniden diriltmelerine yol açar.
Daha İyi Bir Alternatif: Kullanım git up
yerinegit pull
Bunun yerine git pull
, aşağıdaki git up
takma adı oluşturmanızı ve kullanmanızı öneririz :
git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'
Bu takma ad, tüm yukarı akış kollarından (ölü dalları budama) en son taahhütleri indirir ve yerel şubeyi yukarı akış dalındaki en son taahhüde hızlı bir şekilde iletmeye çalışır. Başarılı olursa, yerel taahhütler yoktu, bu nedenle birleşme çatışması riski yoktu. Yerel (sıkıştırılmamış) taahhütler varsa hızlı ileri alma başarısız olur ve harekete geçmeden önce yukarı akış taahhütlerini gözden geçirme fırsatı verir.
Bu, çalışma dizininizi öngörülemeyen yollarla değiştirir, ancak yalnızca yerel değişiklikleriniz yoksa. Bunun aksine git pull
, git up
sizi asla bir birleşme çatışmasını gidermenizi bekleyen bir isteme bırakmaz.
Başka seçenek: git pull --ff-only --all -p
Aşağıdaki git up
takma ad için bir alternatiftir :
git config --global alias.up 'pull --ff-only --all -p'
Öğesinin bu sürümü git up
, aşağıdaki git up
takma adla aynı davranışa sahip :
- yerel şubeniz yukarı akışlı bir dal ile yapılandırılmadıysa hata iletisi biraz daha şifreli
- Git'in gelecekteki sürümlerinde değişebilecek belgelenmemiş bir özelliğe (
-p
iletilen argüman fetch
) dayanır
Git 2.0 veya daha yenisini kullanıyorsanız
Git 2.0 ve daha yeni sürümlerle git pull
varsayılan olarak yalnızca ileri sarma birleştirmeleri yapılandırabilirsiniz :
git config --global pull.ff only
Bu git pull
gibi davranmasına neden olur git pull --ff-only
, ancak yine de tüm yukarı akış taahhütlerini getirmez veya eski origin/*
dalları temizlemez, bu yüzden hala tercih ederim git up
.