Juniorlar İçin Git: Deneyim Paylaşımı ve İpuçları
Git kullanmak junior bir geliştirici için kafa karıştırıcı olabiliyor. Özellikle eş zamanlı olarak birçok yeni feature geliştiriliyorsa yaşanabiliyor.
Ben de yeni başladığım dönemde, takım içerisinde çalışmayı, kod paylaşmayı ve Git kullanmayı öğrenmeme yardımcı olan bir anımdan bahsetmek istiyorum.
Yeni mezun olarak kariyerime başladığım zamanlardı, ilk görevim bir servisi Plsql’den Java’ya dönüştürmek ile ilgiliydi. Bu proje, aslında ayrılmak üzere olan bir geliştirici arkadaş tarafından başlatılmıştı. Görevim işi devralıp eksikliklerini giderip, çalışır hale getirmekti. Geliştirmeleri aktardıktan sonra da o arkadaş işten ayrıldı 😢.
Bende çalışmalara başladım. Plsql ve Java taraflarını çalıştırarak aynı sonuca ulaşıp ulaşmadığımı kontrol ederek ilerliyordum. Eksik veya hatalı olduğunu fark ettiğim kısımlarını takımın seniorlerine sorarak çözüyor ve gerekli implementasyonları gerçekleştirip işi ilerletiyordum. En sonunda, üzerine iki sprint uğraşarak servisi çalışır hale getirmeyi başardım. Sonunda, tester’a teslim edilecek duruma gelmişti. 🎉
Geliştirmeyi tamamladıktan sonra, gerekli dosyaları commitleyip pushladım. Ardından pull requesti açtım veeee conflicti yedim🤕.
Hepimizin conflict ile ilk tanışmasının benzer şekilde olduğunu tahmin edebiliyorum. Neden conflict çıktığından kısaca değinmek istiyorum.
Git nasıl çalışıyor?
Git bir versiyon kontrol sistemi. Kodumuzu paylaşmamızı, dosyalar üzerindeki değişikliklerimizi takip etmemizi kolaylaştıran bir araç. Linux geliştirme ekibinin bazı olaylar neticesinde ihtiyaç duymasıyla ortaya çıkıyor. (Olayların kısacası; bir şirket var, sunduğu versiyon kontrol sisteminin ücretsiz kullanım lisansını kaldırıyor. Bunun üzerine Linus Torvalds’ın önderliğinde Git ortaya çıkıyor.)
Bir versiyon kontrol sisteminden beklentimiz dosyaların üzerinde yapılan değişikliklerin takip edilmesini sağlamak. Akla gelen ilk yöntem dosyaları manuel versiyonlamak 😅.
Bunun aksine genel olarak delta-based versiyon kontrol denen bir yöntem var. Bu yöntemde her yeni versiyonda hangi dosyalarda ne değişiklik yapıldığı bilgisi tutuluyor.
Git ise farklı olarak tüm dosyaların durumunu snapshot denilen tek bir obje üzerinde tutuyor. Commit yapıldığında o anki bütün dosyaların durumunu saklıyor. Değişiklik içermeyen dosyalar ise daha verimli olması için bir önceki durumlarının referansını gösteriyor.
Bu saklama şekli Git’in branching sistemini de özel kılan bir etmen oluyor. Git de branch oluşturmak hızlı, performanslı ve daha efektif. Rakiplerinden ayıran ve sektör standartı haline gelmesini sağlayan başlıca özelliklerinden biri de bu.
Branching özelliği, ana koda dokunmadan geliştirme sürecini ayrıca yürütebilme imkanı sağlayan bir özellik. Örneğin yeni bir Feature geliştirmeye başladınız ve uzun bir geliştirme süreci olacak. Bu sırada acil çözülmesi gereken bir Prod bulgusu geldi. Bu durumda Prod branchinden bir branch daha oluşturup yeni Feature için yapılan geliştirmelere dokunmadan Prod sorunu üzerine çalışabiliyorsunuz.
Conflict oluşma senaryomuza gelirsek; diyelim ki hem Hotfix hem de Feature branchlerinde aynı yerde değişiklik yaptık. Bu durumda merge yapınca aynı yerde değişiklik içeren iki commit birbirinden farklı Parent commitlerden geldiğinden dolayı conflict çıkacaktır.
Bu conflict durumunda git cli merge yaparken bizim dosyaları manuel olarak çözmemizi bekliyor. Conflicti çözdükten sonra iki Parent’i olan yeni bir merge commit oluşacak. Daha detaylı bilgi sahibi olmak için bknz
Hikayenin devamı
Yaşadığım conflict olayına geri dönersek. Conflicti çözmek için hemen yan masamda oturan takım arkadaşıma “kanka bunu nasıl çözüyoruz?” diyip beraber conflicti çözmek için giriştik.
Yeni bir branch oluşturup, localimde merge yapıp çözmeye başladık, çıkan conflictleri Eclipse’de açtık çözüyoruz sırayla. Çözüyoruz ama bir yandan arkadaş diyor burada bir gariplik var. ☠
Commit geçmişine bakınca bir de ne görelim! Benim branch testden alınmış.😯
Geliştirme yaptığım projede Test ve Prod ortamları için farklı branchler vardı. Geliştirmeleri Prod branchinden alınan branche commitleyip sonra test branchine merge yaparak ilerlemem gerekiyordu. Bu sayede iki farklı ortamda geliştirmeler ilerletiliyordu. Biri kullanıcıya sunulan Prod ortamı diğeri de testerların testleri koştuğu test ortamı. Kodun amacı Prod ortama ulaşmak ama önce test aşamasından geçmeli.
Bu tarz test’den alınmış bir branchi fark etmeden Prod’a alınması durumunda test edilmemiş yeni bir geliştirmenin Prod ortama geçmesine neden olma ihtimali ortaya çıkıyor. 🤯
En tehlikelisi ise test ortamda yaşayan eski bir kodun hatalı bir şekilde Prod ortama taşınması durumu. Bu senaryoda tarihler eski gözüküyorsa kodun doğru olup olmadığını anlamakta zor olabiliyor. Bunu yakalamak için pull requestleri onaylarken dikkatli gözlere ihtiyaç oluyor. Bu tarz bir duruma bir kaç kez denk geldim, işin kötü yanı teste geçerken diff olarak da gözükmüyor 😨. (Neyse ki Yakup’un gözler sağlamdı fark etti 😂)
Böyle bir soruna neden olmadan çözmek için önce prod branchinden temiz bir branch açıp tek tek bütün değişiklikleri yer yer chery-pick yaparak yer yer kodları manuel ekleyerek birleştirdik. Burada biraz Eclipse’in hantallığı, biraz da bizim junior olmamızın verdiği acemilikle 3 gün uğraşıp branchleri adam edebilmiştik.
Bu tecrübe sayesinde hem git hakkında çok şey öğrenmiştim hem de ekip ile birlikte geliştirme yapma konusunda bilmediğim bir alana giriş yapmıştım. Buradan öğrendiğim tecrübeler sayesinde daha sonraları bu tarz sorunlar ile karşılaşan junior arkadaşlara da sorunun çözümü konusunda destek verebildim.
Buraya kadar okuduğunuz için teşekkürler. 👋