İlk İş Günü İçin Git Rehberi

Emincan Özcan
Huawei Developers - Türkiye
10 min readJul 6, 2022

Giriş

Git dağıtık yapıda çalışan, son derece performanslı bir versiyon kontrol sistemidir. Linus Torvalds tarafından yaratılan bu araç o kadar başarılı ki, zamanla neredeyse tüm sektörü ele geçirdi.

Yazılım dünyasında neredeyse her teknoloji için “Hangisi daha iyi?” tartışması vardır. Hangi işletim sistemi, hangi programlama dili, hangi kod editörü daha iyi diye onlarca saat tartışabiliriz. Diğer taraftan Git öylesine standart haline gelmiştir ki, “Git mi kullansak X mi?” gibi bir tartışma konusuna dahi neredeyse hiç rastlamayız.

Git’e dair eğitim arayışı içerisine girdiğimizde binlerce makale, komut listesi ve eğitim programına denk geliriz. Bu içerik, en temelde bilgiyi ele alış biçimiyle ve hedefleriyle onlardan ayrılıyor. İlk iş gününüzde size yardımcı olmak, adaptasyon sürecinizi hızlandırmak için oluşturuldu.

Biraz Sizden ve Git’ten Bahsedelim

Yeni bir staj veya iş fırsatını değerlendirdiniz, yakın zamanda başlıyorsunuz. Git denen versiyon kontrol sisteminin varlığından haberdarsınız, temel birkaç kavrama aşinasınız, geçmişte Github veya Gitlab’da bir hesap oluşturdunuz ve birkaç kez kod gönderip kod getirdiniz.

Diğer taraftan eğer bir ekiple birlikte Git kullanma pratiğiniz olmadıysa, ilk iş gününüzde bu aracı nasıl kullanmanız gerektiğine dair soru işaretleriniz olabilir.

Bireysel çalışırken nadiren merge conflict görürüz, branch adlarını ve commit mesajlarını daha az önemseriz, kendi çalışmamız için pull request açarak vakit kaybetmeyiz.

Takım olarak çalışırken ister istemez çakışmalarla karşılaşmaya, daha iyi isimlendirmeler ve mesajlar seçmemiz gerektiğini anlamaya başlarız.

Bu içeriğin odak noktası, ilk iş gününüzde sorunsuz bir Git deneyimi yaşamanızı sağlamak. Sistemin tüm inceliklerini irdelemek, en iyi pratikleri ödün vermeden takip etmek gibi bir hedefimiz yok. Hedefimiz hızlıca çarkları döndürmeye başlamak. Daha fazlasını ilerleyen zamanlarda ilgi ve ihtiyaçlarınıza bağlı olarak öğrenebilirsiniz.

Çalışma arkadaşlarınıza soru sormaktan çekinmeyin. Sizi bilgilendirmek veya gerekli eğitimlere yönlendirmek şirkette ortak bir sorumluluk.

Git Arayüz Seçimi: GUI vs CLI

Git doğrudan komut satırı üzerinden kullanılabildiği gibi 3. parti grafik arayüzü sunan bazı uygulamalar üzerinden de kullanılabilir. Hangisinin daha iyi olduğu sorusu son derece eğlenceli bir tartışma konusu olsa da, günün sonunda sadece kişisel tercih meselesi.

Örneğin ben, komut satırı üzerinden ilerlemeyi daha çok severim ancak bazen grafik arayüz sunan uygulamalardan ya da kod editörümün verdiği Git desteğinden de yararlanırım. Bir dönem LazyGit adlı bir araç da kullanıyordum; onu ne GUI ne CLI kategorisinde değerlendirebiliriz, TUI adlı farklı bir kategoriye ait.

Peki sizin tercihiniz ne olmalı?

Hedefiniz gerçekten Git’i öğrenmekse komut satırında vakit geçirmenizi öneririm. Git’i gerçekten deneyimlemenin tek yolu bu.

Hedefiniz hızlıca işyerinde Git kullanmaya başlamaksa muhtemelen grafik arayüzü sunan 3. parti yazılımları tercih etmeniz daha mantıklıdır.

Eğer kullanacaksanız, hangi 3. parti yazılımı kullanmalısınız?

Kendinizi en konforlu hissettiğiniz yazılımı kullanın.

  • Kod editörü ve IDE’lerin pek çoğu Git için yardımcı araçlar barındırıyor. Çoğu işlem için son derece yeterliler, muhtemelen en hızlı adapte olacağınız ortam da bu ortamdır.
  • GitHub Desktop son derece pratik ve temiz bir arayüze sahip, şirketiniz de GitHub kullanıyorsa size gönderdiği bildirimlerle de iyi bir deneyim yaşatıyor.
  • Daha gelişmiş, daha fonksiyonel bir uygulama arıyorsanız SourceTree’ye bakabilirsiniz. Bu aracın history gösterimini muazzam buluyorum.
  • GitKraken, Sublime Merge gibi ücretli bazı araçlara da göz atabilirsiniz. Şirketiniz belki ücretli bir aracı tüm şirket için satın almış olabilir.

Git Kullanırken Takip Edilebilecek Genel Bir Akış

Git’i kullanırken izlenecek genel bir akışla başlayalım ve aşinalık kazanmak için birkaç komut görelim. Daha sonra bu akışı detaylandırarak devam edeceğiz.

  1. Genel geliştirme branch’ine geç:
    git checkout develop && git pull origin develop
  2. Buradan yeni bir branch yarat:
    git checkout -b my-feature-branch
  3. Geliştirirken gerekli anlarda commitle. Planlanan geliştirmeler sonlanana kadar bu adımın birkaç kez tekrar edilmesi gerekebilir, geliştirmeler tamamlanınca bir sonraki adıma geç.
    1. git add .
    2. git commit -m “Harika bir commit mesajı”
  4. Çakışma olmadığından emin ol, varsa çöz.
    1. git checkout develop
    2. git pull origin develop
    3. git checkout my-branch
    4. git rebase develop
  5. Geliştirmeleri uzak sunucuya gönder:
    git push -u origin yourworkbranch
  6. Pull request aç.

Şimdi her adımı detaylarıyla inceleyerek devam edelim.

1. Genel geliştirme branch’ine geç

İlk adımımız son derece doğal duruyor, pek açıklanmaya ihtiyacı yok. Lakin dikkat edilmediği taktirde minik sorunlar oluşabilir, bir örnek üzerinden görelim.

Diyelim ki bir özellik geliştirdiniz, Git sunucusuna gönderdiniz ve süreci tamamladınız. İkinci bir özellik geliştirmeye başlamak için derhal yeni bir branch yaratırsanız, yarattığınız branch eski branch’inizden türemiş olur. Ancak istenen durum bu değildir, Git sunucusundaki develop branch’inden türetmektir. Daha net görebilmek adına, istenen durumu ve sorunlu durumu bir grafikle inceleyelim.

Branch-a üzerinde çalışmalar tamamlandıktan sonra branch-b adlı yeni bir branch yaratıp yeni bir çalışmaya başlamak isteniyor. Grafikte görebileceğiniz gibi; branch-b adlı yeni yaratılan branch, branch-a’dan türetilmiş. Ancak istenen durum develop branch’inden türetmekti.

Bu durum bir problem yaratır mı? Kimi zaman evet, kimi zaman hayır. Yarattığı durumlara birkaç örnek:

  • Branch-b, branch-a’dan bağımsız olarak birleştirilmek istenirse bu hata süreci karmaşıklaştırır, ek müdahale gerektirir.
  • İlerleyen zamanlarda geçmişe bakıldığında yapılanların analizi zorlaşabilir.
  • Code review süreçlerinde kafa karışıklığı yaratarak diğer geliştiricilerin vaktini gereksiz yere alabilir.

Bu bahsettiğim problemlerin ve dahasının çözümleri sürecin farklı aşamalarında her daim bulunabilir. Zaman içerisinde ihtiyaç duydukça bu çözümleri ve teknikleri de öğrenirsiniz mutlaka. Ancak yazının başında da belirttiğim gibi, burada hedefimiz mümkün olduğunca kolay ve temiz şekilde projeye katkıda bulunmaya başlamak. Dolayısıyla oluşabilecek minik problemleri önden çözerek ilerlemek istiyoruz.

Bu problemi yaşamamak için yapılması gereken son derece basit. Yeni bir branch yaratmadan önce git checkout develop && git pull origin develop ile develop branch’ine dönmek ve yeni branch’i buradan yaratmak yeterli.

Muhtemelen farkındasınızdır, “develop” projenizdeki geliştirme branch’inin ismini temsil ediyor. Farklı projelerde farklı isimlendirmeler kullanılabilir, doğrulayıp uygun isimle devam edin.

2. Yeni Bir Branch Yarat

Yapacağımız geliştirmeler için yeni bir branch yaratmalıyız. Branch yaratırken iyi bir isimlendirme yapmak son derece önemli.

Branch Nasıl İsimlendirilir?

Burada farklı yaklaşımlar, farklı doğrular var. İnternette bir araştırma yaptığınızda da farklı yaklaşımların daha doğru olduğunu iddia eden pek çok içerikle karşılaşırsınız. Genellikle amaç, aşağıdaki birkaç maddeyi branch isminin bir parçası haline getirmektir:

  • JIRA veya benzeri bir uygulama üzerinde ticket olarak açılan bir iş ise ilgili id değeri, eğer Github vb. platformda issue açıldıysa ilgili issue id’si vb.
  • Geliştirmenin tipine göre bir kategorizasyon sözcüğü. (feature, bugfix, hotfix vb.)
  • Yapılan işin en fazla birkaç kelimelik özeti

Ayrıca bahsettiğim ifadeleri yazarken ayraçlara ihtiyaç duyulur. Bu ayraçlar “/”, “_”, “-” vb. olabilir. Kişisel tercihim “/” kullanmaktan yana ancak sektörde diğerlerine de sıkça rastlamak mümkün. Birkaç örnek branch adına bakalım:

  • fix/11787/extension-warning
  • 42483-color-tests
  • feat-custom-endpoints

Örnek sayısı çoğaltılabilir ancak farklı tarzlarda isimlendirmeler olduğunu görmek için bu 3'lü yeterli. Hangisi doğru, hangisi iyi tartışmasını bir yana bırakırsak, başlangıçta takımın kullandığı isimlendirme modeline bakıp ona uygun devam etmek en güzeli.

Ayrıca nispeten olgun bir projede çalışıyorsanız, bu isimlendirme modeli bir yerlerde dokümante edilmiş olabilir. Bu durumda ekstra şanslısınız, yazılanı takip edebilirsiniz.

3. Geliştirirken “gerekli anlarda” commitle

Yaptığınız geliştirmeleri mümkün olduğunca atomik şekilde ve doğru bir mesajla commitlemeye özen gösterin.

Hayal edin, 2 ay önce atılmış bir commit’e bakıyorsunuz. Binlerce satır değişmiş, mesaj olarak “Some changes…” yazılmış. Bu commit’te ne yapıldığı, hangi kodun niye eklendiği / silindiği son derece anlaşılmaz, algılamak ciddi efor gerektirir. Ek olarak bir conflict çözülecekse veya revert commit gibi gereksinimler doğarsa, iyi atılmış commitler hayatınızı kolaylaştırır.

Gelecekteki kendinize veya meslektaşlarınıza zorluk yaratmamak için, geliştirme yaparken bir ilerleme kaydettiğiniz, anlamlı bir şeyler ortaya koyduğunuzu hissettiğiniz noktalarda iyi bir commit mesajıyla bu anları saklamayı ihmal etmeyin.

Commit mesajı yazarken şu birkaç hususa dikkat ederseniz oldukça iyi sonuçlar alırsınız:

  • Sadece ilgili değişiklikleri commit’leyin. Varsayalım bir özelliği geliştirirken farklı bir metodda performans sorunu gördünüz ve bunu iyileştirdiniz. Bu çalışmayı, geliştirdiğiniz asıl özellikle birlikte commitlemeyin. Yaptığınız çalışmaların ilgili branch adları ve commit mesajlarının kapsamında olmasına özen gösterin. Gerekirse farklı commit ve/veya farklı branch kullanın.
  • Sık ve küçük commitler kullanın. Büyük commitlerin takibi de zordur. Pek çok farklı konuya dair kod barındıran bir commit içerisinde yapılanı anlamak, anlamaya çalışana çile haline gelebilir.
  • Tamamlanmamış işleri commitlemeyin. Sık ve küçük commitler kullanmaya çalışırken dengeyi doğru kurmak önemlidir. Proje geçmişinde herhangi bir commit’e dönüldüğünde proje tutarlı olmalıdır. Tamamlanmamış veya çalışmayan çalışmaları commitlemeyin.
    Minik bir ipucu: Eğer çalışırken bir önceki değişikliği erken commitlediğinizi fark ederseniz, “amend commit” kullanarak durumu toparlayabilirsiniz.
  • Commitlemeden önce testlerinizi yapın. Projenizdeki testleri çalıştırın, gözle test edilmesi gereken yerler varsa bunları gerçekleştirin, compile edilen bir dille çalışıyorsanız projeyi compile edin... Yaptığınız değişikliğin sistemin kalanına zarar vermediğine emin olun ki, gelecekte commitlediğiniz ana geri dönmek isteyen bir başka yazılımcı farklı sorunlarla başbaşa kalmasın.
  • İyi bir commit mesajı yazın. Bu konunun pek çok inceliği var, aşağıda daha geniş bir alanda devam edelim.

İyi bir commit mesajı yazmak için bir şablonu takip etmek ve bazı kriterleri yerine getirmek gerekir. Benim referans aldığım, her projede uygulanabileceğini ve iyi sonuçlar vereceğini düşündüğüm bir model var. Modelin anlatımı şurada: https://cbea.ms/git-commit/ Vaktiniz olduğunda okumanızı öneririm.

Birkaç “iyi” commit mesajına bakalım:

  • Add logout button
  • Remove unnecessary condition
  • Fix showing wrong currency in the cart page

Örneklerde de gördüğümüz üzere, mümkün olduğunca kısa ve emir kipinde cümleler kurulmalı. İlk başta bu biraz tuhaf gelebilir, çünkü günlük hayatta konuşurken veya yazarken bu şekilde davranmayız.

Bu tarz bir commit mesajı yazmanızı inanılmaz kolaylaştıran ve benim de ilk kez blog’da okuduğum formüle bir bakalım, yazarken aşağıdaki kalıbı hayal ediyoruz:

“If applied, this commit will remove unnecessary condition”.

Buradaki “If applied, this commit will…” ifadesi silinirse, commit mesajı kendiliğinden hazır hale gelir.

Ek olarak çok kritik olmasa da kaliteyi yüksek tutabilmek adına dikkat edilmesi gereken birkaç nokta daha var. Commit mesajının ilk harfini büyük yazmak, gerekli durumlarda body alanına iyi bir açıklama yazmak, mesajın sonuna nokta koymamak… Tümünden bahsedip detaylandırmak için paylaştığım makaleyi olduğu gibi buraya almam gerekir, dolayısıyla tekrardan uygun bir vaktinizde https://cbea.ms/git-commit/ adresine gidip okumanızı önereceğim. :)

Dikkatinizi çektiyse, commit yazma konusunda projenizde şimdiye kadar nasıl yapıldıysa onu yapın düsturunun dışında şeyler söyledim. Projenize atılan commitler, önerdiğim şekilde veya farklı da olsa mantıklı bir metadolijiyi takip ederek bugüne kadar gelmişse tabii ki buna saygı duyup devam ettirmekte fayda var. Gelgelelim bazı projelerde bu konu maalesef yeterince ciddiye alınmıyor, takip edilebilecek doğru pratikler olmayabiliyor. Bu durumda eskiyi tekrar etmek yalnızca var olan dağınıklığı daha da arttırır. Doğru pratikleri takip ederek projenin geleceğine yatırım yapmanızı öneririm.

4. Çakışma olmadığından emin ol, varsa çöz.

Git çoğu durumda son derece akıllı çalışır, yapılan değişiklikleri birleştirip bir bütün oluşturur. Takım arkadaşlarınız ve siz farklı alanlara müdahale ederseniz kodları birleştirme esnasında pürüzsüz bir süreç sizi bekler.

Gelgelelim kodları birleştirme konusunda Git’in de çaresiz kaldığı anlar var. Eğer siz ve takım arkadaşlarınız bir dosyanın aynı satırlarını değiştirdiyseniz, hangi değişikliğin geçerli olması gerektiğini seçmek Git’in üstesinden gelemeyeceği bir iş. Ayrıca bazen yalnızca iki değişiklikten bir tanesini seçmenin ötesinde her ikisinin de tutulması veya her ikisinin de kaldırılıp yeni bir kod yazılması gerekebilir.

Çakışmaları Kim Çözmeli?

Yazılan kodun diğer kodlarla nasıl birleşeceğine dair sorumluluk geliştiricinin kendisine ait olmalı. Çakışmaları bizzat çözmek ve gerekirse çakışmalara sebep olan kodu yazan diğer geliştiricilerle iletişime geçerek çözüm sürecini birlikte sürdürmek, ilgili geliştirmeyi tamamlamanın bir önkoşuludur. Tabii bunlar benim görüşlerim, siz dilerseniz takım arkadaşlarınıza “Çakışma olmadığından emin olmam ve düzeltmem gerekiyor mu?” sorusunu yöneltin, “Gerek yok.” derlerse bu adımı pas geçin.

Çakışmaları Çözmek

Kullanılan araçlar, eğer varsa çakışmaları geliştiricilere bildirir ve bir çözüme ihtiyaç duyulduğunu söylerler.

  • Bilgisayarınızda kod birleştirmeye karar verip merge / rebase komutlarını kullanırsanız Git sizi conflictler hakkında uyarır ve çözmenizi talep eder.
  • Github, Gitlab vb. servisler üzerinden Pull Request açarken bu duruma dair bir uyarı size gösterilir. (Pull request açılması engellenmez ancak pull request’i onaylamak için sunulan butonlar pasif hale getirilir, sorunlar çözülünce tekrar kullanılabilirler.)

Bu tarz yaşanabilecek çakışmaları çözmek için; birleştirilme planlanan branch’i, kendi branch’inize birleştirebilirsiniz.

git checkout develop        # develop branchine geç
git pull origin develop # remote develop branchini local'e getir
git checkout my-branch # çalışılan branche geri dön
git rebase develop # rebase yöntemiyle birleştir

Bu işlemi gerçekleştirmenin birden fazla yolu var ancak ilerleyişi açık açık görmek için bu 4 adımı takip etmenizi öneriyorum.

Rebase yerine merge yöntemini de tercih edebilirsiniz. Benim tercihim genel olarak rebase olsa da bu konu herkesin üzerinde uzlaştığı bir konu değil. Merge mü yoksa rebase mi kullanacağınızı proje geçmişine bakarak veya tecrübeli takım arkadaşlarına sorarak devam edebilirsiniz.

Çakışmaların çözümünde VS Code kullanmanızı öneririm, bence bu konuda en iyi deneyimi o sunuyor.

5. Geliştirmeleri uzak sunucuya gönder.

Geliştirmeler tamamlanınca içerikleri sunucuya gönderebiliriz. Burada eğer komut satırını kullanıyorsanız git push -u origin yourworkbranch şeklinde pushlamanız iyi olacaktır.

Neden -u flag’ini kullanıyoruz diye merak ederseniz…

-u ifadesi sayesinde kodunuzu pushlarken aynı zamanda local branch’inize uzaktaki branch’i takip edeceğine dönük bir referans eklemiş olursunuz. Buna upstream denir. Branch ismi belirtmeden git pull gibi ifadeler çalıştırılınca upstream olarak ayarlanmış uzak sunucu branch’i kullanılır. Yanlış ayarlanması durumunda yanlış branch’ten dosya getirme, yanlış branch’e dosya gönderme gibi durumlar söz konusu olabilir. Hiç ayarlanmadığında Git sizi uyarıp bir upstream ayarlamanız gerektiğini söyler. Normalde upstream ayarlamak için git branch --set-upstream yourbranchname origin/yourbranchname gibi ekstra bir komut kullanmanız gerekir. -u upstream ayarlama adımını aradan çıkarmaya yardımcı bir parametredir.

6. Pull request aç.

Çalışmalar tamam, artık PR açabilirsiniz. PR açarken başlık ve açıklama kısmına özen göstermeniz harika olur. Pek çok organizasyonda açıklama alanı size bir şablon olarak sunulur, takip etmeniz yeterlidir.

PR açtıktan sonra açtığınız PR’a gelen yorumlara ve geri bildirimlere düzenli olarak göz atın. İyi kurgulanan bir Git servisinde bu gelişmeler size mail veya çeşitli bildirimlerle doğrudan ulaştırılır. Eğer ulaştırılmıyorsa arada bir elle kontrol etmekte fayda var.

Ek olarak, PR açtıktan sonra eklemek / değiştirmek istediğiniz geliştirmeler de olabilir. Bu durumda bilgisayarınızda branch’inize geçip, istediğiniz değişiklikleri yapıp tekrar push’lamanız yeterli. Branch’inize atacağınız yeni commitler kendiliğinden PR’ın bir parçası haline gelirler.

Git Kullanımı Bu Derece Katı Olamaz

Yazı boyunca “şu adımları takip edin.” dedikten sonra bu başlığı görmek biraz tuhaf gelebilir, ancak doğru olan bu. Günlük hayatta her zaman bu akışı takip ederek gitmeniz olanaksız. Birkaç örnek senaryoya bakalım:

  • Bir geliştirmeyi tamamlamadan başka bir geliştirmeye başlamanız gerekebilir.
  • Tamamlanmamış da olsa bir çalışmanızın yedeğini almak için Git’i kullanmak isteyebilirsiniz.
  • Çalışmanız tamamlanmamış olsa da tamamlanan bir bölümüne ihtiyaç duyan bir arkadaşınız olabilir. Sizin yarı tamamlanan çalışmanızı kendi branch’ine dahil etmek için Git’e yollamanızı rica edebilir.
  • Çalışmaları tamamlayınca attığınız eski bir commit mesajını değiştirmek isteyebilirsiniz. Hatta bazen 4–5 commit’i tek bir commit haline getirmek de isteyebilirsiniz.

Bu gibi durumlarda Git’in sağladığı diğer olanaklardan da faydalanarak daha esnek bir çalışma modeline sahip olmak gerekir.

Kötü haber şu ki, bu esnekliği bir metinden okuyarak elde edemezsiniz. İyi haber, bu durumu kafaya takmanıza hiç gerek yok, çalışırken minik araştırmalar yaparak çok kısa bir sürede bahsettiğim esnekliğe sahip olabilirsiniz.

Düşünüyorum da benim hayatımı en çok kolaylaştıran 2 komut muhtemelen şunlardır:

  • Rebase: Yalnızca merge’e alternatif bir birleştirme yöntemi olarak düşünülmemeli. Rebase kullanarak eski commitleri birleştirebilir, geçmişte atılan commit mesajlarını değiştirebilir, bazı commitleri direkt yok edebilir ve çok daha fazlasını yapabilirsiniz.
  • Stash: Yaptığınız çalışmaya dair commit atmadan bir yerde saklamak istediğinizde başvurabileceğiniz bir komut. Çalışmaları farklı bir branch’e taşımak için de son derece kullanışlı.

Bu komutlar ve işlevleri aklınızda bulunsun, ihtiyacınız olduğunda bir Google’larsınız.

Sonuç

Yazının başında da vurguladığım gibi soru sormaktan çekinmeyin. Git’e dair karşılaşacağınız çoğu problem ve bilinmezlik, biraz deneyimli bir geliştirici tarafından birkaç dakika içerisinde çözülebilir.

Birkaç kere soru sorup biraz da pratik yaptıktan sonra son derece konforlu bir Git deneyimi yaşamaya başlayacaksınız. ✌🏻

Referanslar

--

--