Takip et

Keşke Daha Önce Bilseydim: Git Komutları ile Geliştirme Sürecinizi Hızlandırın

Git, modern yazılım geliştirmenin vazgeçilmez bir parçasıdır. Çoğu geliştirici temel komutları (git add, git commit, git push, git pull, git branc…

Keşke Daha Önce Bilseydim: Git Komutları ile Geliştirme Sürecinizi Hızlandırın

Git, modern yazılım geliştirmenin vazgeçilmez bir parçasıdır. Çoğu geliştirici temel komutları (git add, git commit, git push, git pull, git branch, git merge) günlük olarak kullanır. Ancak Git’in derinliklerinde, iş akışınızı inanılmaz derecede hızlandırabilecek, hataları gidermenize yardımcı olabilecek ve kod tabanınızı daha düzenli tutmanızı sağlayacak güçlü komutlar ve özellikler bulunmaktadır. Bu makalede, birçok geliştiricinin “keşke daha önce bilseydim” dediği, daha az bilinen ancak son derece faydalı Git komutlarını ve tekniklerini detaylı bir şekilde inceleyeceğiz. Bu bilgilerle Git ustalığınızı bir üst seviyeye taşıyarak daha verimli bir geliştirici olmaya hazır olun.

1. Gelişmiş Log İncelemeleri: Geçmişi Anlamak

Git geçmişini incelemek, bir projenin evrimini anlamak, belirli bir değişikliğin ne zaman yapıldığını bulmak veya bir hatanın kökenini tespit etmek için kritik öneme sahiptir. git log komutu, basit bir geçmiş dökümünden çok daha fazlasını sunar.

–graph –oneline –all ile Görselleştirme

Varsayılan git log çıktısı oldukça detaylı olabilir. Ancak --graph, --oneline ve --all parametreleri ile çok daha okunabilir ve görsel bir geçmiş elde edebilirsiniz. Bu kombinasyon, dalların birleşmelerini ve çatallanmalarını grafiksel olarak gösterirken, her commit’i tek bir satırda özetler.

git log --graph --oneline --all

Bu komut, tüm dallardaki commit'leri kompakt bir şekilde gösterir ve projenin genel yapısını anlamanıza yardımcı olur.

--grep ile Commit Mesajlarında Arama

Belirli bir özelliği veya hatayı içeren commit'i arıyorsanız, commit mesajlarında anahtar kelime araması yapmak çok işinize yarar. --grep parametresi ile commit mesajları içinde düzenli ifade aramaları yapabilirsiniz.

git log --grep="feature-x"

Bu komut, mesajında "feature-x" geçen tüm commit'leri listeler. Büyük projelerde belirli bir değişikliği bulmak için harika bir yöntemdir.

-p veya --patch ile Değişiklikleri Görme

Bir commit'in tam olarak hangi değişiklikleri içerdiğini görmek için -p veya --patch parametresini kullanabilirsiniz. Bu, her commit'in içeriğini (eklenen/silinen satırları) gösterir.

git log -p -1

Bu komut, en son commit'in mesajını ve yaptığı tüm kod değişikliklerini gösterir. Belirli bir commit'in detaylarını incelemek için commit ID'sini de kullanabilirsiniz: git show .

--author ve --since ile Filtreleme

Belirli bir yazarın commit'lerini veya belirli bir tarihten sonraki commit'leri görmek isteyebilirsiniz. --author ve --since (veya --until) parametreleri bu filtrelemeyi sağlar.

git log --author="John Doe" --since="2 weeks ago"

Bu komut, "John Doe" tarafından son iki hafta içinde yapılmış tüm commit'leri listeler. Bu sayede belirli bir geliştiricinin katkılarını veya belirli bir zaman dilimindeki çalışmaları kolayca inceleyebilirsiniz.

2. Değişiklikleri Geçici Olarak Saklamak: git stash

Bazen üzerinde çalıştığınız bir özelliği tamamlamadan başka bir işe geçmeniz gerekebilir. Ancak mevcut değişiklikleri commit etmek istemezsiniz çünkü henüz bitmemişlerdir. İşte bu noktada git stash devreye girer. git stash, mevcut değişikliklerinizi (hem staged hem de unstaged) geçici olarak bir kenara koymanızı ve çalışma dizininizi temiz bir hale getirmenizi sağlar.

Temel Kullanım: git stash save ve git stash apply/pop

Değişikliklerinizi saklamak için:

git stash save "Incomplete feature-y work"

Bu komut, çalışma dizininizi ve indeksinizi temizler. Sakladığınız değişiklikleri geri getirmek için:

git stash apply

apply komutu, stash'i uygularken stash listesinden kaldırmaz. Eğer stash'i uygulayıp aynı zamanda listeden kaldırmak isterseniz pop komutunu kullanın:

git stash pop

Stash'leri Yönetmek: git stash list, git stash show, git stash drop

Birden fazla stash'iniz olabilir. Bunları yönetmek için şu komutları kullanabilirsiniz:

  • git stash list: Tüm kaydedilmiş stash'leri listeler. Her stash'in bir indeksi (örneğin stash@{0}) vardır.
  • git stash show stash@{1}: Belirli bir stash'in içeriğini (değişiklik özetini) gösterir. -p ile detaylı patch'i görebilirsiniz.
  • git stash drop stash@{1}: Belirli bir stash'i listeden siler.
  • git stash clear: Tüm stash'leri siler. Dikkatli kullanın!

Belirli Dosyaları Stash'lemek: git stash push -p

Tüm değişiklikleri stash'lemek yerine, sadece belirli dosyaları veya değişiklikleri stash'lemek isteyebilirsiniz. git stash push -p (veya --patch) interaktif bir şekilde hangi değişiklikleri stash'leyeceğinizi seçmenizi sağlar.

git stash push -p

Bu komut, her bir "hunk" (değişiklik bloğu) için size bir seçenek sunar (stash'le, atla, düzenle vb.). Bu, daha granüler bir kontrol sağlar.

3. Temiz Bir Geçmiş İçin: git rebase -i

git rebase -i (interaktif rebase), commit geçmişinizi yeniden yazmak için inanılmaz güçlü bir araçtır. Özellikle feature branch'lerinizi ana branch'e birleştirmeden önce commit'lerinizi düzenlemek, birleştirmek veya yeniden sıralamak için kullanılır. Ancak dikkatli kullanılmalıdır, çünkü geçmişi değiştirmek başkalarıyla paylaşılan dallarda sorunlara yol açabilir.

İnteraktif Rebase Nedir ve Neden Kullanılır?

İnteraktif rebase, bir dizi commit üzerinde çeşitli işlemler yapmanızı sağlayan bir Git özelliğidir. Genellikle, bir feature branch'indeki dağınık commit'leri daha anlamlı ve düzenli bir hale getirmek için kullanılır. Bu, ana branch'in geçmişinin temiz ve okunabilir kalmasını sağlar.

git rebase -i HEAD~3

Bu komut, son üç commit'inizi interaktif olarak düzenlemenizi sağlar. Git, size bir düzenleyici açar ve bu commit'ler üzerinde yapabileceğiniz işlemleri listeler (pick, squash, reword, edit, drop, fixup).

Commit'leri Birleştirmek (squash)

Birden fazla küçük, anlamsız commit'i tek bir anlamlı commit'te birleştirmek (squash) yaygın bir kullanımdır. Örneğin, "fix typo", "add console log", "another small change" gibi commit'leri tek bir "Implement user login feature" commit'ine dönüştürebilirsiniz.

Rebase ekranında, ilk commit'i pick olarak bırakın ve sonraki commit'leri squash olarak işaretleyin:

pick 1a2b3c4 Implement user login part 1
squash 5d6e7f8 Fix typo in login form
squash 9h0i1j2 Add validation for password field

Kaydettikten sonra, Git sizden bu birleştirilmiş commit için yeni bir mesaj yazmanızı isteyecektir.

Commit Mesajlarını Düzenlemek (reword) ve Yeniden Sıralamak (reorder)

Bir commit'in mesajını değiştirmek için reword komutunu kullanabilirsiniz. Yanlış yazılmış veya yetersiz bir commit mesajını düzeltmek için idealdir.

pick 1a2b3c4 Implement user login part 1
reword 5d6e7f8 Fix typo in login form
pick 9h0i1j2 Add validation for password field

Commit'lerin sırasını değiştirmek için ise sadece editörde commit satırlarını yukarı veya aşağı taşıyabilirsiniz.

Commit'leri Bölmek veya Silmek

Bazen bir commit'in çok fazla değişiklik içerdiğini fark edersiniz ve onu daha küçük, mantıksal parçalara bölmek istersiniz. Bu durumda, ilgili commit'i edit olarak işaretlersiniz. Git bu commit'e geldiğinde durur, değişiklikleri sıfırlar ve size yeni commit'ler oluşturma fırsatı verir. Bitirdiğinizde git rebase --continue ile devam edersiniz.

Bir commit'i tamamen silmek için ise ilgili satırın başındaki komutu drop olarak değiştirebilir veya satırı tamamen silebilirsiniz.

4. Kayıp İşlemleri Kurtarmak ve Geçmişi İzlemek: git reflog

Git'te "kaybolan" bir commit'i kurtarmak veya yanlışlıkla yaptığınız bir işlemi geri almak için git reflog komutu gerçek bir cankurtarandır. git reflog, HEAD'in (yani bulunduğunuz yerin) tüm hareketlerini kaydeder, bu da yanlışlıkla silinen dalları, rebase hatalarını veya reset işlemlerini geri almanızı sağlar.

Reflog Nedir ve Nasıl Çalışır?

git reflog, Git deposundaki HEAD referansının yerel hareketlerinin bir kaydıdır. Bu, bir commit'in silinmesi durumunda bile, o commit'in SHA-1 hash'ini bulup ona geri dönebileceğiniz anlamına gelir. Reflog, sadece sizin yerel deponuzda tutulur ve başkalarıyla paylaşılmaz.

git reflog

Çıktı, her bir HEAD hareketini listeler: commit'ler, merge'ler, rebase'ler, reset'ler ve branch değiştirmeler. Her girişin bir indeksi (örneğin HEAD@{0}, HEAD@{1}) ve bir commit hash'i vardır.

Yanlışlıkla Silinen Commit'leri Kurtarma

Diyelim ki bir branch'i yanlışlıkla sildiniz veya git reset --hard ile bazı commit'leri kaybettiniz. git reflog çıktısında, kaybolduğunu düşündüğünüz commit'in hash'ini bulabilirsiniz. Örneğin, HEAD@{5} olarak görünen bir commit'e geri dönmek için:

git checkout HEAD@{5}

Bu sizi o commit'in durumuna getirir. Daha sonra bu durumu yeni bir branch olarak kaydedebilirsiniz:

git checkout -b recovered-branch

Böylece kaybolan işinizi geri kazanmış olursunuz.

Eski Bir Duruma Geri Dönme

Bir rebase işlemi sırasında işleri karıştırdınız ve eski, güvenli bir duruma dönmek istiyorsunuz. git reflog size rebase öncesi durumu gösterecektir. Örneğin, rebase'den önceki durumu HEAD@{1} olarak görürseniz, bu duruma geri dönmek için:

git reset --hard HEAD@{1}

Bu komut, çalışma dizininizi ve geçmişinizi belirtilen duruma sıfırlar. git reflog, Git'in en güçlü "geri alma" araçlarından biridir.

5. Belirli Değişiklikleri Taşımak: git cherry-pick

Bazen bir branch'teki belirli bir commit'i (veya birkaç commit'i) başka bir branch'e taşımak istersiniz, ancak tüm branch'i birleştirmek istemezsiniz. İşte bu senaryoda git cherry-pick komutu devreye girer. Bu komut, başka bir branch'teki herhangi bir commit'i alıp mevcut branch'inize uygulamanızı sağlar.

Cherry-Pick Nedir ve Ne Zaman Kullanılır?

git cherry-pick, bir veya daha fazla mevcut commit'i alıp bunları mevcut HEAD'in üzerine yeni commit'ler olarak uygulamak için kullanılır. Yaygın kullanım senaryoları şunlardır:

  • Bir hotfix'i geliştirme branch'inden ana branch'e hızlıca taşımak.
  • Farklı bir branch'te geliştirilmiş küçük bir özelliği veya düzeltmeyi kendi branch'inize entegre etmek.
  • Bir branch'teki yanlışlıkla yapılmış bir commit'i diğer branch'lerden ayırmak.

Bir Commit'i Başka Bir Branched'e Uygulama

Diyelim ki feature-A branch'inde önemli bir düzeltme yaptınız ve bu düzeltmenin main branch'ine de gitmesi gerekiyor, ancak feature-A henüz tam olarak hazır değil. İlk olarak, düzeltmenin yapıldığı commit'in hash'ini bulun (git log ile).

git log --oneline

Çıktıdan commit hash'ini (örneğin abcdef1) kopyalayın. Ardından, main branch'ine geçin ve cherry-pick komutunu çalıştırın:

git checkout main
git cherry-pick abcdef1

Bu, abcdef1 commit'inin değişikliklerini main branch'inize yeni bir commit olarak uygular. Yeni commit'in hash'i farklı olacaktır, ancak içeriği aynıdır.

Çakışmaları Çözme

cherry-pick işlemi sırasında, uygulanan commit ile mevcut branch arasında çakışmalar meydana gelebilir. Bu durumda Git size çakışmaları çözmenizi söyleyecektir. Çakışmaları çözdükten sonra, değişiklikleri staged hale getirip cherry-pick işlemini tamamlamanız gerekir:

# Çakışmaları çözün
git add .
git cherry-pick --continue

Eğer cherry-pick işlemini iptal etmek isterseniz:

git cherry-pick --abort

6. Hataları Hızla Bulmak: git bisect

Bir projenin geçmişinde bir hata olduğunu fark ettiniz, ancak hatanın hangi commit tarafından tanıtıldığını bilmiyorsunuz. Manuel olarak commit'leri tek tek kontrol etmek zaman alıcı ve yorucu olabilir. git bisect, bu süreci otomatikleştiren ve bir hatayı tanıtan ilk commit'i bulmak için ikili arama algoritmasını kullanan güçlü bir araçtır.

Git Bisect Nedir ve Nasıl Çalışır?

git bisect, bir dizi commit arasında ikili arama yaparak, bir hatanın ne zaman ortaya çıktığını bulmanızı sağlar. Sizden "iyi" (hatanın olmadığı) ve "kötü" (hatanın olduğu) bir commit belirtmenizi ister. Daha sonra, bu iki nokta arasındaki commit'lerin tam ortasına atlar ve o commit'te hatanın olup olmadığını test etmenizi ister. Bu süreci tekrarlayarak, hatayı tanıtan commit'i logaritmik bir sürede bulur.

Hatalı ve İyi Commit'leri Tanımlama

git bisect sürecini başlatmak için:

git bisect start

Şu anki commit'in hatalı olduğunu varsayalım (veya hatanın olduğu bilinen bir commit'e geçin):

git bisect bad

Şimdi hatanın olmadığı bilinen eski bir commit'i belirtmeniz gerekiyor:

git bisect good 

Örneğin, main branch'inin son stabil sürümü iyi bir başlangıç noktası olabilir.

Git şimdi iyi ve kötü commit'lerin tam ortasındaki bir commit'e geçiş yapacaktır. Sizden bu commit'te hatanın olup olmadığını test etmenizi isteyecektir. Test sonucuna göre:

  • Eğer hata mevcutsa: git bisect bad
  • Eğer hata yoksa: git bisect good

Bu adımları tekrarlayarak, Git size hatayı tanıtan ilk commit'i bildirecektir. İşlem bittiğinde, bisect modundan çıkmak için:

git bisect reset

Otomatik Bisect Kullanımı

Eğer hatayı test eden bir komut dosyanız (örneğin bir birim testi) varsa, git bisect sürecini tamamen otomatikleştirebilirsiniz. Bunun için git bisect run komutunu kullanırsınız:

git bisect start
git bisect bad
git bisect good 
git bisect run ./test_script.sh

test_script.sh, eğer test başarılı olursa 0 (iyi) ile, başarısız olursa 1-127 arası bir değerle (kötü) çıkış yapmalıdır. Bu, özellikle büyük projelerde ve uzun commit geçmişlerinde hatayı bulma süresini dramatik bir şekilde azaltır.

Sonuç

Git, sadece bir versiyon kontrol sistemi olmanın ötesinde, geliştiricilerin iş akışını optimize etmelerine, hataları gidermelerine ve projelerini daha düzenli yönetmelerine olanak tanıyan zengin bir komut setine sahiptir. Bu makalede ele aldığımız git log'un gelişmiş kullanımı, git stash ile değişiklikleri yönetme, git rebase -i ile temiz bir geçmiş oluşturma, git reflog ile kayıp işleri kurtarma, git cherry-pick ile belirli değişiklikleri taşıma ve git bisect ile hataları hızla bulma gibi komutlar, birçok geliştiricinin "keşke daha önce bilseydim" dediği araçlardır. Bu komutları öğrenmek ve pratik etmek, Git ustalığınızı artıracak ve günlük geliştirme süreçlerinizde size önemli avantajlar sağlayacaktır. Unutmayın, Git'in gücü, sadece temel komutları bilmekle değil, aynı zamanda daha az bilinen ancak güçlü özelliklerini keşfetmekle ortaya çıkar. Deneyerek ve uygulayarak bu komutları kendi iş akışınıza entegre etmekten çekinmeyin!

SSS (Sık Sorulan Sorular)

1. git rebase ve git merge arasındaki temel fark nedir?

git merge, iki branch'in geçmişini birleştirirken yeni bir "merge commit" oluşturur ve her iki branch'in geçmişini korur. Bu, geçmişi daha şeffaf ve izlenebilir yapar. git rebase ise, bir branch'teki commit'leri başka bir branch'in üzerine "yeniden temel alır", yani commit'lerin geçmişini yeniden yazar. Bu, doğrusal ve daha temiz bir commit geçmişi sağlar, ancak paylaşılan branch'lerde kullanılırken dikkatli olunmalıdır çünkü geçmişi değiştirmek sorunlara yol açabilir.

2. git reflog komutu kalıcı mıdır? Yanlışlıkla sildiğim bir commit'i ne kadar süreyle kurtarabilirim?

git reflog girdileri kalıcı değildir. Git, reflog girdilerini belirli bir süre (varsayılan olarak 90 gün) saklar. Bu süre zarfında, yanlışlıkla sildiğiniz veya kaybettiğiniz commit'leri reflog sayesinde kurtarabilirsiniz. Süre dolduktan sonra, ilgili commit'ler Git'in "garbage collection" (çöp toplama) mekanizması tarafından temizlenebilir ve kurtarılamaz hale gelebilir.

3. git stash ile untracked dosyaları da saklayabilir miyim?

Varsayılan olarak, git stash sadece takip edilen (tracked) ve değiştirilmiş dosyaları saklar. Untracked dosyaları da stash'lemek isterseniz, git stash -u veya git stash --include-untracked komutunu kullanmanız gerekir. Ayrıca, hem untracked hem de ignore edilen dosyaları saklamak için git stash -a veya git stash --all komutunu kullanabilirsiniz.

4. git cherry-pick kullanırken dikkat etmem gerekenler nelerdir?

git cherry-pick kullanırken dikkat edilmesi gereken en önemli nokta, seçtiğiniz commit'in bağımlılıklarıdır. Eğer bir commit, önceki commit'lerde yapılan değişikliklere bağlıysa ve siz sadece o commit'i alırsanız, kodunuz çalışmayabilir veya beklenmedik hatalara yol açabilir. Ayrıca, cherry-pick ile alınan commit'ler yeni bir commit hash'i ile uygulandığı için, aynı değişiklikleri daha sonra merge ederseniz duplike commit'ler oluşabilir. Bu nedenle, genellikle küçük, bağımsız düzeltmeler veya özellikler için kullanılması önerilir.

5. git bisect hatayı bulduktan sonra ne yapmalıyım?

git bisect size hatayı tanıtan commit'i bildirdiğinde, bu commit'in detaylarını incelemek için git show komutunu kullanabilirsiniz. Hatayı anladıktan sonra, bir düzeltme commit'i oluşturabilir ve bu düzeltmeyi ana branch'inize entegre edebilirsiniz. İşiniz bittiğinde, git bisect reset komutunu kullanarak bisect modundan çıkmayı unutmayın. Bu, HEAD'inizi bisect işlemine başlamadan önceki branch'e geri getirir.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.