Git Staging ve Commit İşlemleri

Git, kaydettiğiniz her dosyayı otomatik olarak geçmişe yazmaz. Bunun yerine, bir sonraki commit’in tam olarak hangi değişiklikleri içereceğine karar verdiğiniz bir hazırlık katmanı sunar: staging area.

Bu ek katman Git’in en güçlü özelliklerinden biridir, ancak yeni başlayanlar için aynı zamanda en kafa karıştırıcı kavramlardan biri olabilir. Bir dosya aynı anda commit edilmiş, değiştirilmiş, kısmen stage edilmiş ve yeniden değiştirilmiş durumda bulunabilir. Açık bir zihinsel model olmadan git add, git diff, git restore ve git commit gibi komutlar tutarsızmış gibi görünebilir.

Bu rehber staging area kavramını ayrıntılı biçimde açıklar ve disiplinli bir commit iş akışı oluşturur. Git’in working tree, index ve son commit’i nasıl karşılaştırdığını; dosyaların tamamını veya seçilen hunk’ları nasıl stage edeceğinizi; güvenli biçimde nasıl unstage yapacağınızı; commit’lerin nasıl oluşturulduğunu; yararlı commit mesajlarının nasıl yazıldığını ve amend ya da geçmişi yeniden yazmanın ne zaman uygun olduğunu öğreneceksiniz.

Anlamanız Gereken Üç Durum

Normal bir Git iş akışında projenin üç önemli temsili bulunur:

  1. HEAD: Geçerli commit tarafından saklanan anlık görüntü.

  2. Index: Bir sonraki commit için önerilen anlık görüntü; genellikle staging area olarak adlandırılır.

  3. Working tree: Diskte görebildiğiniz ve düzenleyebildiğiniz mevcut dosyalar.

Şu diyagramı kullanabilirsiniz:

Son Commit (HEAD)
        |
        | karşılaştırma: git diff --staged
        v
Staging Area (Index)
        |
        | karşılaştırma: git diff
        v
Working Tree

Her katman aynı dosyanın farklı bir sürümünü içerebilir.

Örneğin:

  • Son commit sürüm 1’i içerir.

  • Staging area sürüm 2’yi içerir.

  • Working tree sürüm 3’ü içerir.

Bu bir hata değildir. Git’in siz düzenlemeye devam ederken hassas bir commit hazırlamanıza izin verme biçimidir.

Staging Area Nedir?

Staging area, Git’in bir sonraki commit için önerdiği anlık görüntüdür. Git bu bilgiyi dahili olarak index içinde saklar.

Şu komutu çalıştırdığınızda:

git add app.php

Git, app.php dosyasının o anki içeriğini index’e kopyalar. Yalnızca dosya adını seçilmiş olarak işaretlemez.

app.php dosyasını stage ettikten sonra tekrar düzenlerseniz index daha önce stage edilen sürümü korur. Working tree ise daha yeni düzenlemeyi içerir.

Bu ayrım sayesinde:

  • Birbiriyle ilgisiz değişiklikleri farklı commit’lere ayırabilirsiniz.

  • Bir sonraki commit’in tam olarak ne içereceğini inceleyebilirsiniz.

  • Bir dosyanın yalnızca belirli bölümlerini stage edebilirsiniz.

  • Deneysel değişiklikleri kararlı bir commit’in dışında bırakabilirsiniz.

  • Working directory dağınık olsa bile temiz bir geçmiş hazırlayabilirsiniz.

Git Neden Staging Area Kullanır?

Bir giriş hatasını düzeltirken üç dosyayı değiştirdiğinizi düşünün:

  • LoginController.php gerçek hata düzeltmesini içeriyor.

  • README.md konuyla ilgisiz bir dokümantasyon iyileştirmesi içeriyor.

  • config.php geçici hata ayıklama değişiklikleri içeriyor.

Staging area olmasaydı üç değişikliği birlikte commit etmek veya commit öncesinde bazı çalışmalarınızı manuel olarak geri almak zorunda kalabilirdiniz.

Git ile yalnızca hata düzeltmesini stage edebilirsiniz:

git add LoginController.php
git diff --staged
git commit -m "Süresi dolmuş giriş token'larını reddet"

Dokümantasyon ve hata ayıklama değişiklikleri daha sonra karar vermeniz için working tree içinde kalır.

Bu nedenle staging area, mevcut çalışma ile kalıcı geçmiş arasında editoryal bir sınır görevi görür.

Tracked, Untracked, Modified ve Staged Dosyalar

Bir depodaki dosyalar genellikle şu durumlar arasında ilerler:

DurumAnlamıTipik İşlem
UntrackedDosya mevcut ancak Git index’inin veya geçmişinin parçası değilStage edin veya yok sayın
Tracked ve değişmemişWorking sürümü index ve geçerli commit ile eşleşiyorİşlem gerekmez
ModifiedWorking sürümü index’ten farklıİnceleyin ve seçilen çalışmayı stage edin
StagedIndex geçerli commit’ten farklıİnceleyin ve commit edin
Staged ve yeniden modifiedIndex ve working tree farklı yeni sürümler içeriyorSonraki düzenlemenin stage edilip edilmeyeceğine karar verin

Ayrıntılı açıklama için:

git status

Kısa özet için:

git status --short

Kısa Durum Çıktısını Doğru Okumak

Kısa biçim iki sütun kullanır:

XY PATH
  • X: HEAD ile index arasındaki fark.

  • Y: Index ile working tree arasındaki fark.

Yaygın örnekler:

?? notes.txt      Untracked
A  notes.txt      Yeni dosya stage edilmiş
 M app.php        Değiştirilmiş ancak stage edilmemiş
M  app.php        Değiştirilmiş sürüm stage edilmiş
MM app.php        Stage edilmiş sürüm ve daha yeni unstaged değişiklik
D  old.php        Silme işlemi stage edilmiş
R  old.php -> new.php
                  Yeniden adlandırma stage edilmiş

Boşluklar önemlidir. M ile M farklı katmanları ifade eder.

Deneme Deposu Oluşturma

Örnekler için geçici bir proje oluşturun.

macOS, Linux veya Git Bash

mkdir git-staging-demo
cd git-staging-demo
git init -b main

cat > calculator.php <<'EOF'
<?php

function add(int $a, int $b): int
{
    return $a + $b;
}
EOF

cat > README.md <<'EOF'
# Calculator Demo

Git staging ve commit işlemlerini uygulamak için küçük bir proje.
EOF

git add calculator.php README.md
git commit -m "Hesap makinesi demosunu oluştur"

PowerShell

New-Item -ItemType Directory git-staging-demo
Set-Location git-staging-demo
git init -b main

@"
<?php

function add(int `$a, int `$b): int
{
    return `$a + `$b;
}
"@ | Set-Content calculator.php

@"
# Calculator Demo

Git staging ve commit işlemlerini uygulamak için küçük bir proje.
"@ | Set-Content README.md

git add calculator.php README.md
git commit -m "Hesap makinesi demosunu oluştur"

Başlangıç durumunu doğrulayın:

git status
git log --oneline

Working tree temiz olmalıdır.

git add Nasıl Çalışır?

git add, working tree içeriğini kullanarak index’i günceller.

Komutun adı biraz yanıltıcı olabilir; çünkü yalnızca yeni dosyaları eklemekle sınırlı değildir. Şunları stage eder:

  • Yeni dosyalar.

  • Tracked dosyalardaki değişiklikler.

  • Çözülmüş merge conflict’leri.

  • Uygun path veya update seçenekleriyle seçildiğinde dosya silmeleri.

Tek dosya stage etmek:

git add calculator.php

Birden fazla adı belirtilmiş path’i stage etmek:

git add calculator.php README.md

Bir dizini stage etmek:

git add src/

Geçerli dizin altındaki değişiklikleri stage etmek:

git add .

Depo genelindeki tüm ekleme, değiştirme ve silmeleri stage etmek:

git add -A

Tracked dosyalardaki değişiklikleri ve silmeleri stage edip yeni untracked dosyaları dışarıda bırakmak:

git add -u

git add ., git add -A ve git add -u

Bu komutların işlevleri örtüşür, ancak amaçları farklıdır.

KomutYeni DosyalarDeğiştirilen DosyalarSilinen DosyalarKapsam
git add .EvetEvetSeçilen path kapsamı içinde evetGeçerli dizin ve alt dizinleri
git add -AEvetEvetEvetVarsayılan olarak tüm depo
git add -uHayırEvetEvetSeçilen kapsamdaki tracked path’ler

Basit depolarda git add . ve git add -A aynı sonucu veriyormuş gibi görünebilir. Fark özellikle komutu bir alt dizinden çalıştırdığınızda veya untracked dosyaları bilinçli biçimde dışarıda bırakmak istediğinizde belirginleşir.

Hangi komutu kullanırsanız kullanın commit öncesinde stage edilen sonucu inceleyin.

Stage Etmeden Önce İnceleme

Hesap makinesini değiştirin:

<?php

function add(int $a, int $b): int
{
    return $a + $b;
}

function subtract(int $a, int $b): int
{
    return $a - $b;
}

Ardından çalıştırın:

git status
git diff

git diff, working tree içindeki stage edilmemiş değişiklikleri gösterir.

Yalnızca bir dosyayı incelemek istediğinizde path belirtin:

git diff -- calculator.php

Çift tire, komut seçeneklerinin bittiğini ve path argümanlarının başladığını gösterir.

Stage Ettikten Sonra İnceleme

Dosyayı stage edin:

git add calculator.php

Artık normal git diff ek bir unstaged düzenleme bulunmadığı için hiçbir şey göstermeyebilir.

Önerilen commit’i şu komutla inceleyin:

git diff --staged

--cached eş anlamlıdır:

git diff --cached

Bu karşılaştırma index’i HEAD ile karşılaştırır.

Disiplinli bir iş akışı her iki karşılaştırmayı da kullanır:

git diff
git add calculator.php
git diff --staged
git commit -m "Çıkarma işlemini ekle"

Bir Dosya Aynı Anda Staged ve Modified Olabilir

Bir değişikliği stage edin:

git add calculator.php

Ardından aynı dosyayı yeniden düzenleyin ve çarpma fonksiyonu ekleyin:

function multiply(int $a, int $b): int
{
    return $a * $b;
}

Çalıştırın:

git status --short

Şunu görebilirsiniz:

MM calculator.php

Index çıkarma değişikliğini içerir. Working tree ise çıkarma ve çarpma değişikliklerinin ikisini de içerir.

Her katmanı karşılaştırın:

# Working tree ile index karşılaştırması
git diff

# Index ile HEAD karşılaştırması
git diff --staged

Çarpma aynı commit’in parçası olacaksa dosyayı tekrar stage edin:

git add calculator.php

Daha sonraki bir commit’e ait olacaksa unstaged bırakın ve yalnızca index’te bulunan sürümü commit edin.

git add -p ile Kısmi Staging

Bazen tek bir dosya mantıksal olarak ilgisiz birkaç düzenleme içerir. Kısmi staging, hunk adı verilen ayrı bölümleri seçmenize izin verir.

Çalıştırın:

git add -p calculator.php

Git her seferinde bir hunk gösterir ve ne yapılacağını sorar.

Yaygın seçenekler:

TuşAnlamı
yBu hunk’ı stage et
nBu hunk’ı stage etme
qÇık ve kalan hunk’ları kararsız bırak
aBu hunk’ı ve dosyadaki sonraki tüm hunk’ları stage et
dBu hunk’ı ve dosyadaki sonraki tüm hunk’ları atla
sMümkünse geçerli hunk’ı daha küçük hunk’lara böl
eStage etmeden önce patch’i manuel olarak düzenle
?Yardımı göster

Hunk seçiminden sonra iki tarafı da inceleyin:

git diff --staged
git diff

İlk komut commit edilecek içeriği, ikincisi commit dışında kalan içeriği gösterir.

Örnek: Refactoring ile Özelliği Ayırmak

calculator.php dosyasının iki değişiklik içerdiğini düşünün:

  1. Daha anlaşılır olması için bir değişkenin adını değiştirmek.

  2. Yeni bir bölme işlemi eklemek.

İlki refactoring, ikincisi davranış değişikliği olduğu için ayrı commit’lere ait olabilirler.

Şunu kullanın:

git add -p calculator.php

Yalnızca yeniden adlandırmayı stage edin ve commit oluşturun:

git diff --staged
git commit -m "Hesap makinesi parametre adlarını netleştir"

Bölme kodu unstaged kalır. Daha sonra stage edip commit edin:

git add calculator.php
git diff --staged
git commit -m "Bölme işlemini ekle"

Bu yaklaşım incelemesi ve geri alınması daha kolay bir geçmiş oluşturur.

git add -i ile Etkileşimli Staging

Git ayrıca etkileşimli bir staging arayüzü sunar:

git add -i

Şu işlemlerde yardımcı olabilir:

  • Durumu görüntülemek.

  • Güncellemeleri eklemek.

  • Stage seçimlerini geri almak.

  • Untracked dosyaları eklemek.

  • Patch’leri stage etmek.

  • Diff’leri incelemek.

Birçok geliştirici doğrudan hunk seçimine geçtiği için git add -p komutunu daha sık kullanır. Ancak birden fazla staging işleminin birlikte yönetilmesi gerektiğinde -i yararlıdır.

Intent to Add

Şu seçenek:

git add -N new-file.php

veya:

git add --intent-to-add new-file.php

Dosyanın tam içeriğini normal bir ekleme olarak stage etmeden, path’in ileride ekleneceğini kaydeder.

Böylece yeni dosya son içeriği stage edilmeden önce diff tabanlı iş akışlarında görünebilir. Bu gelişmiş bir kolaylıktır ve normal başlangıç iş akışları için gerekli değildir.

Bir Commit Neleri Kaydeder?

Commit, index içinde hazırlanan anlık görüntüyü kaydeder ve mevcut geçmişe bağlar.

Bir commit nesnesi şu bilgileri içerir:

  • Anlık görüntüyü temsil eden üst düzey tree nesnesine referans.

  • İlk commit hariç bir veya daha fazla parent commit.

  • Yazar kimliği ve yazarlık zamanı.

  • Committer kimliği ve commit zamanı.

  • Commit mesajı.

Git daha sonra commit’e bir object identifier verir.

Commit, working tree içindeki tüm unstaged düzenlemeleri içermez. Index’i kaydeder.

Author ve Committer Farkı

Git hem author hem de committer bilgisi saklar.

  • Author: Değişikliği ilk oluşturan kişi.

  • Committer: Commit’in bu sürümünü mevcut geçmişe kaydeden kişi.

Normal yerel çalışmada genellikle aynı kişidir.

Şu durumlarda farklı olabilir:

  • Bir maintainer başka bir geliştiricinin patch’ini uyguladığında.

  • Commit rebase edildiğinde.

  • Cherry-pick bir değişikliği başka bir geçmişte yeniden oluşturduğunda.

  • Commit farklı biri tarafından amend edildiğinde.

Her iki değeri incelemek için:

git log -1 --format=fuller

Commit Oluşturmak

Stage edilmiş içerikten satır içi mesajla commit oluşturun:

git commit -m "Çıkarma işlemini ekle"

Veya yapılandırılmış editörü açın:

git commit

Editör biçimi, kısa bir başlık ve ardından ayrıntılı açıklama gerektiren mesajlar için kullanışlıdır.

Commit öncesinde inceleyin:

git status
git diff --staged

Commit sonrasında inceleyin:

git status
git log -1 --stat

Güçlü Commit Mesajları Yazmak

Commit mesajı, kaydedilen değişikliğin amacını açıklamalıdır.

Zayıf örnekler:

update
changes
fix stuff
new code
final version

Daha güçlü örnekler:

Sıfıra bölmeyi reddet
Kayıttan önce e-posta biçimini doğrula
Yinelenen ödeme tekrarını kaldır
Yerel veritabanı kurulumunu belgele

Güçlü mesajlar anlamlı bir eylemi belirtir ve geçmişin aranabilir olmasını sağlar.

Pratik Bir Mesaj Yapısı

Basit bir commit için açık bir konu satırı çoğu zaman yeterlidir:

Çıkarma işlemini ekle

Daha karmaşık bir değişiklik için:

Parola sıfırlama token'larına süre kontrolü ekle

Kullanıcı yüklenmeden önce 30 dakikadan eski token'ları reddet.
Bu sayede süresi dolmuş sıfırlama bağlantıları parola formuna ulaşmaz.

Yaygın bir yaklaşım:

  • Kısa bir konu satırı yazın.

  • Ekle, Düzelt veya Kaldır gibi emir kipine yakın bir stil kullanın.

  • Gövde öncesinde boş satır bırakın.

  • Değişikliğin neden gerektiğini ve önemli uygulama bağlamını açıklayın.

  • Diff’in zaten açıkça gösterdiği bilgiyi tekrar etmeyin.

Depo veya organizasyon kuralları ek biçim şartları belirleyebilir.

Yalnızca Ne Değiştiğini Değil, Nedenini Commit Edin

Diff hangi satırların değiştiğini zaten gösterir. Mesaj daha sonra görünür olmayabilecek gerekçeyi korumalıdır.

Daha az yararlı:

Zaman aşımını 10'dan 30'a çıkar

Daha yararlı:

Yavaş sağlayıcılar için ödeme callback zaman aşımını artır

Bazı sağlayıcılar yoğun trafikte on saniyeden uzun sürüyor.
Otuz saniye, API sınırını aşmadan erken tekrar denemeleri önlüyor.

İkinci mesaj sayının arkasındaki operasyonel nedeni kaydeder.

Commit Mesajı Şablonları

Ekipler yazarlar için hatırlatıcılar içeren bir mesaj şablonu sağlayabilir.

Şöyle bir şablon oluşturun:

# Özet

# Bu değişiklik neden gerekli?

# Nasıl test edildi?

# İlgili issue:

Yapılandırın:

git config --global commit.template ~/.gitmessage.txt

git commit editörü açtığında şablon, geliştiricilerin tutarlı bağlam eklemesine yardımcı olur.

Yorum olarak işlenen satırlar Git’in mesaj temizleme davranışına göre genellikle kaldırılır.

Commit Oluşturmadan Önce İçeriği İnceleme

Dry run kullanın:

git commit --dry-run

Bu komut commit oluşturmadan nelerin dahil edileceğini ve nelerin dışarıda kalacağını gösterir.

Kısa durum biçimiyle birlikte de kullanabilirsiniz:

git commit --dry-run --short

İçeriği incelemenin en güvenilir yolu yine:

git diff --staged

git commit -a ile Tracked Değişiklikleri Commit Etmek

Şu kısayol:

git commit -a -m "Hesap makinesi işlemlerini güncelle"

zaten tracked olan dosyalardaki değişiklikleri ve silmeleri otomatik olarak stage eder, ardından commit oluşturur.

Normalde yeni untracked dosyaları dahil etmez.

Küçük ve odaklı bir değişiklikte kullanışlı olabilir, ancak git add ile yapılan açık inceleme adımını atlar. Varlığını unuttuğunuz düzenlemeleri de içerebilir.

Daha güvenli ve bilinçli sıra:

git status
git diff
git add -u
git diff --staged
git commit -m "Hesap makinesi işlemlerini güncelle"

Seçilen Path’leri Dikkatli Commit Edin

Git doğrudan path adları verilen commit biçimlerini destekler, ancak bunlar normal index tabanlı iş akışından farklı davranabilir.

Özellikle öğrenme aşamasında açık ve öngörülebilir bir inceleme için şunu tercih edin:

git add path/to/file
git diff --staged
git commit -m "Değişikliği açıklayın"

Böylece geçmiş güncellenmeden önce önerilen anlık görüntü görünür hale gelir.

Bir Dosyayı Nasıl Unstage Edersiniz?

Staging geri alınabilir. Bir dosya yanlışlıkla index’e eklendiyse working değişikliklerini kaybetmeden unstage edebilirsiniz.

Şunu kullanın:

git restore --staged calculator.php

Bu komut varsayılan olarak index sürümünü HEAD üzerinden geri yükler, ancak working dosyasını değiştirmez.

Sonucu kontrol edin:

git status
git diff
git diff --staged

Değişiklikler staged karşılaştırmadan unstaged karşılaştırmaya taşınmalıdır.

Eski reset Sözdizimi

Şu komutla da karşılaşabilirsiniz:

git reset HEAD calculator.php

Bu şekilde bir path ile kullanıldığında index’i günceller ve genellikle working tree düzenlemelerini korur. Modern Git bu görev için daha açık bir komut olarak git restore --staged sunar.

Değişiklikleri Kısmen Unstage Etmek

Patch modunu kullanın:

git restore --staged -p calculator.php

Bu komut, diğer hunk’ları stage edilmiş halde bırakırken seçilen hunk’ları index’ten çıkarır.

Kısmi staging’in tersidir:

  • git add -p, index’e eklenecek hunk’ları seçer.

  • git restore --staged -p, index’ten çıkarılacak hunk’ları seçer.

Unstage ile Değişiklikleri Silmek Aynı Şey Değildir

Şu komut:

git restore --staged calculator.php

index’i değiştirir ancak working düzenlemesini korur.

Şu komut:

git restore calculator.php

varsayılan olarak working dosyasını index’ten geri yükler ve unstaged çalışmayı silebilir.

Working tree restore işlemi öncesinde inceleyin:

git diff -- calculator.php

Commit edilmemiş working değişiklikleri yıkıcı bir restore sonrasında geri alınamayabilir.

En Son Commit’i Amend Etmek

Son yerel commit’te bir hata varsa onu amend edilmiş yeni bir commit ile değiştirebilirsiniz.

Yaygın kullanım alanları:

  • Gerekli bir dosyanın unutulması.

  • Commit mesajında hata bulunması.

  • Küçük bir düzeltmenin mantıksal olarak aynı commit’e ait olması.

Unutulan Dosyayı Eklemek

git add forgotten-test.php
git commit --amend --no-edit

--no-edit mevcut mesajı korur.

Son Commit Mesajını Değiştirmek

git commit --amend

Mesajı düzenleyin, kaydedin ve editörü kapatın.

Yeni Satır İçi Mesajla Amend

git commit --amend -m "Çıkarma ve doğrulama testlerini ekle"

Amend işlemi yeni bir commit nesnesi oluşturur. Anlık görüntü veya meta veri değiştiği için commit kimliği de değişir.

Paylaşılan Geçmişi Düşünmeden Amend Etmeyin

Daha önce push edilmiş ve başkaları tarafından kullanılan bir commit’i amend etmek geçmişi yeniden yazar. Uzak depoyu güncellemek force push gerektirebilir ve ekip arkadaşlarının çalışmasını bozabilir.

Pratik kural:

  • Commit özel ve yalnızca yereldeyken rahatça amend edin.

  • Yayınlandıktan sonra dikkatli olun.

  • Paylaşılan dallar için ekip politikasını izleyin.

  • Geçmiş aktif kullanımdayken yeni bir düzeltme commit’i oluşturmayı tercih edin.

Boş Commit’ler

Stage edilmiş değişiklik olmadığında Git normalde işlemi durdurur.

Açıkça boş commit oluşturmak için:

git commit --allow-empty -m "Deployment pipeline'ını tetikle"

Olası kullanım alanları:

  • Commit olaylarına bağlı otomasyonu tetiklemek.

  • Tracked içerik değiştirmeden proje olayını işaretlemek.

  • Depo entegrasyonlarını test etmek.

Boş commit’ler bilinçli olmalı ve açık biçimde açıklanmalıdır.

Sign-Off ile Kriptografik İmzalama Farkı

Bu iki kavram farklıdır.

Developer Sign-Off

Şu seçenek:

git commit --signoff -m "Bölme işlemini ekle"

committer kimliğini kullanarak mesaja Signed-off-by trailer’ı ekler. Projeler bunu Developer Certificate of Origin gibi katkı politikalarına onayı kaydetmek için kullanabilir.

Kriptografik Commit İmzalama

Kriptografik olarak imzalanmış commit, doğrulanabilir bir imza eklemek için signing yapılandırması ve anahtarlar kullanır:

git commit -S -m "Bölme işlemini ekle"

Bu işlem önceden yapılandırma gerektirir ve metinsel sign-off trailer’ından ayrıdır.

--signoff seçeneğini kriptografik doğrulama olarak tanımlamayın.

Commit Trailer’ları

Yapılandırılmış meta veriler commit mesajının sonunda bulunabilir:

Yinelenen fatura üretimini düzelt

İlk istek başarıyla tamamlandıktan sonra retry worker'ın
yeniden fatura oluşturmasını engelle.

Reported-by: Jane Developer <jane@example.com>
Reviewed-by: Alex Maintainer <alex@example.com>

Bazı projeler belirli trailer’lar ve otomatik politikalar tanımlar. Yalnızca proje tarafından istenen veya tanınan trailer’ları kullanın.

Fixup ve Squash Commit’leri

Yerel geliştirme sırasında yeni bir değişikliğin önceki bir commit’e ait olduğunu fark edebilirsiniz.

Fixup commit oluşturun:

git add calculator.php
git commit --fixup=<target-commit>

Git fixup! ile başlayan bir mesaj oluşturur. Daha sonra autosquash ile interactive rebase kullanarak hedef commit ile birleştirebilirsiniz.

Squash commit ek mesajı koruyabilir:

git commit --squash=<target-commit>

Bu iş akışları geçmişi yeniden yazar ve commit’ler geniş çapta paylaşılmadan önce kullanılması daha uygundur.

Workflow ve geçmişi yeniden yazma makalelerinde daha ayrıntılı ele alınacaktır.

Commit Hook’ları ve Doğrulama

Git hook’ları, Git işlemlerinin belirli aşamalarında çalışan programlardır.

Commit ile ilgili hook’lar şu görevlerde kullanılabilir:

  • Stage edilmiş dosyaları biçimlendirmek.

  • Testleri çalıştırmak.

  • Gizli bilgileri reddetmek.

  • Commit mesajı yapısını kontrol etmek.

  • Meta veri eklemek veya doğrulamak.

Örnekler:

  • pre-commit

  • prepare-commit-msg

  • commit-msg

  • post-commit

Yerel hook commit’i engelleyebilir, ancak her makinede kurulu veya etkin olmayabileceği için tek denetim katmanı olarak görülmemelidir. Kritik kontroller ayrıca ortak CI veya server-side iş akışlarında çalıştırılmalıdır.

Tam Bir Temiz Commit İş Akışı

Günlük çalışmaların çoğunda şu sırayı kullanın:

1. Depoyu İnceleyin

git status

2. Unstaged Değişiklikleri İnceleyin

git diff

3. Tek Bir Mantıksal Değişikliği Stage Edin

git add path/to/file

Veya hunk seçin:

git add -p

4. Önerilen Anlık Görüntüyü Doğrulayın

git diff --staged
git status

5. İlgili Testleri Çalıştırın

# Yalnızca örnek; projenin gerçek test komutunu kullanın
php vendor/bin/phpunit

6. Yararlı Bir Mesajla Commit Oluşturun

git commit -m "Sıfıra bölmeyi reddet"

7. Sonucu Doğrulayın

git status
git log -1 --stat

8. Kalan Çalışmalar İçin Tekrarlayın

git status hâlâ ilgisiz düzenlemeler gösteriyorsa hepsini otomatik olarak birleştirmek yerine sonraki odaklı commit’i hazırlayın.

Manuel Uygulama: Tek Dosyadaki İki Değişikliği Ayırmak

Bu örnek kısmi staging’i baştan sona gösterir.

İlk Commit Edilmiş Dosya

<?php

function add(int $a, int $b): int
{
    return $a + $b;
}

Working Tree Sürümü

<?php

function add(int $left, int $right): int
{
    return $left + $right;
}

function subtract(int $left, int $right): int
{
    return $left - $right;
}

İki mantıksal değişiklik vardır:

  1. $a ve $b parametrelerini daha açıklayıcı adlarla değiştirmek.

  2. Çıkarma davranışı eklemek.

İnceleyin

git diff -- calculator.php

Seçilen Hunk’ları Stage Edin

git add -p calculator.php

Yalnızca parametre yeniden adlandırmasını seçin. Git ayırabiliyorsa hunk’ı s ile bölün. Görüntülenen patch biçimini anlamıyorsanız manuel patch düzenlemeyi kullanmayın.

Her İki Tarafı Doğrulayın

git diff --staged
git diff

Staged diff yeniden adlandırmayı, unstaged diff ise yeni çıkarma fonksiyonunu göstermelidir.

İlk Commit’i Oluşturun

git commit -m "Hesap makinesi parametre adlarını netleştir"

Kalan Özelliği Stage Edin

git add calculator.php
git diff --staged

İkinci Commit’i Oluşturun

git commit -m "Çıkarma işlemini ekle"

Geçmişi İnceleyin

git log --oneline --stat -2

Sonuç karışık tek bir anlık görüntü yerine anlaşılır iki commit’tir.

Manuel Uygulama: Çalışmayı Kaybetmeden Unstage Etmek

Her iki dosyanın yanlışlıkla stage edildiğini varsayın:

git add calculator.php README.md
git status --short

Beklenen durum:

M  README.md
M  calculator.php

README dosyasını unstage edin:

git restore --staged README.md

Tekrar inceleyin:

git status --short

Beklenen yapı:

 M README.md
M  calculator.php

README değişikliği working tree içinde durmaya devam eder. Silinmemiştir.

Yalnızca hesap makinesi değişikliğini commit edin:

git diff --staged
git commit -m "Hesap makinesi doğrulamasını ekle"

README başka bir commit için kullanılabilir halde kalır.

Manuel Uygulama: Unutulan Testi Amend Etmek

Commit oluşturun:

git add calculator.php
git commit -m "Sıfıra bölmeyi reddet"

Ardından ilgili testin eklenmediğini fark edin:

git add tests/CalculatorTest.php
git diff --staged
git commit --amend --no-edit

Amend edilmiş commit’i inceleyin:

git show --stat
git log -1 --format=fuller

Yeni commit artık hem uygulamayı hem testi içerir ve kimliği ilk commit’ten farklıdır.

Yaygın Staging Hataları

Her Şeyi İncelemeden Stage Etmek

git add . debug dosyalarını, üretilmiş çıktıları, ilgisiz düzenlemeleri veya kimlik bilgilerini içerebilir.

git add Komutunun Gelecekteki Düzenlemeleri Otomatik Olarak Takip Ettiğini Sanmak

Git dosyanın komut çalıştığı andaki içeriğini stage eder. Daha sonraki düzenlemeler aynı commit’e aitse tekrar stage edilmelidir.

Yalnızca git status Kullanmak

Status dosya düzeyindeki durumu gösterir, satır düzeyindeki içeriğin tamamını göstermez. Diff’leri de inceleyin.

Unstage ile Değişiklikleri Silmeyi Karıştırmak

git restore --staged index’i günceller. git restore komutu --staged olmadan working değişikliklerinin üzerine yazabilir.

Yeni Dosyalar İçin git commit -a Kullanmak

Bu kısayol tracked değişiklikleri ve silmeleri işler, normal untracked eklemeleri dahil etmez.

Karışık Commit’ler Oluşturmak

Tek commit ilgisiz refactoring, özellik, debugging ve dokümantasyon değişikliklerini birleştirmemelidir; ancak hepsi ayrılmaz tek bir değişikliğin parçasıysa istisna olabilir.

Yayınlanmış Commit’i Koordinasyonsuz Amend Etmek

Amend commit kimliğini değiştirir ve geçmişi yeniden yazan push gerektirebilir.

Sign-Off’u Kriptografik İmzalama Sanmak

Metinsel Signed-off-by trailer’ı ile doğrulanmış kriptografik imza farklı amaçlara hizmet eder.

Yaygın Commit Mesajı Hataları

  • update gibi belirsiz başlıklar kullanmak.

  • Amaç yerine yalnızca dosya adlarını açıklamak.

  • Birbiriyle ilgisiz değişiklikleri tek mesaj altında birleştirmek.

  • Açık bir ilk satır özeti olmadan uzun gövde yazmak.

  • Teknik değişikliği açıklamayan ticket başlıklarını kopyalamak.

  • Mesaja hassas bilgi eklemek.

  • Aynı depoda tutarsız kurallar kullanmak.

Temiz Commit’ler İçin En İyi Uygulamalar

  • git status ile başlayın.

  • Unstaged çalışmayı seçmeden önce inceleyin.

  • Değişiklikler karışıksa path’e özel veya patch staging kullanın.

  • Her seferinde git diff --staged çıktısını inceleyin.

  • Commit öncesinde odaklı testleri çalıştırın.

  • Mümkün olduğunda her commit’i build edilebilir durumda tutun.

  • Değişikliği açıklayan açık bir konu satırı yazın.

  • Gerekçe ve kısıtları korumak için gövdeyi kullanın.

  • Ekip farklı karar vermedikçe yalnızca özel geçmişi amend edin.

  • Gizli ve üretilmiş dosyaları index dışında tutun.

  • Her commit’ten sonra son durumu kontrol edin.

Yararlı Komut Referansı

KomutAmacı
git statusGeçerli working tree ve index durumunu açıklar
git status --shortİki sütunlu kısa durum kodlarını gösterir
git diffUnstaged değişiklikleri incelemeyi sağlar
git diff --stagedÖnerilen sonraki commit’i incelemeyi sağlar
git add fileBir dosyanın mevcut içeriğini stage eder
git add -pSeçilen hunk’ları etkileşimli biçimde stage eder
git add -iEtkileşimli staging arayüzünü açar
git add -uTracked değişiklikleri ve silmeleri stage eder
git add -AEkleme, değiştirme ve silmeleri stage eder
git restore --staged fileWorking değişikliklerini koruyarak path’i unstage eder
git restore --staged -pSeçilen hunk’ları kısmen unstage eder
git commitEditör kullanarak index’ten commit oluşturur
git commit -m "message"Satır içi mesajla commit oluşturur
git commit --dry-runCommit oluşturmadan dahil edilecek içeriği önizler
git commit -aTracked değişiklikleri ve silmeleri stage edip commit eder
git commit --amendEn son commit’i değiştirir
git commit --amend --no-editMesajını koruyarak en son commit’i değiştirir
git log -1 --format=fullerAuthor ve committer meta verisini gösterir

Staging ve Commit Kontrol Listesi

Commit oluşturmadan önce şunları doğrulayın:

  • Geçerli dal doğru.

  • Stage edilmiş dosyalar tek bir mantıksal değişikliğe ait.

  • Kimlik bilgileri veya özel veri stage edilmemiş.

  • Uygun olduğunda üretilmiş dosyalar dışarıda bırakılmış.

  • git diff --staged amacınızla eşleşiyor.

  • İlgili testler başarılı.

  • Konu satırı değişikliği açıkça açıklıyor.

  • Gerekli olduğunda gövde önemli gerekçeyi kaydediyor.

Commit sonrasında şunları doğrulayın:

  • Commit log içinde bulunuyor.

  • Author bilgisi doğru.

  • Amaçlanan dosyalar commit içinde mevcut.

  • Kalan working değişiklikleri anlaşılıyor.

  • Görev tamamlandığında depo temiz.

Sık Sorulan Sorular

Staging Area Zorunlu mu?

Index, Git’in normal anlık görüntü modelinin merkezindedir. Bazı commit seçenekleri tracked path’leri doğrudan seçebilir, ancak açık stage-review-commit iş akışı çoğu geliştirme süreci için daha anlaşılır ve güvenlidir.

git add Çalışmamı Kalıcı Olarak Kaydeder mi?

Hayır. İçeriği index içinde hazırlar. Commit bu anlık görüntüyü depo geçmişine kaydeder.

git diff Neden Hiçbir Şey Göstermiyor?

Değişiklikleriniz zaten stage edilmiş olabilir. git diff --staged çalıştırın. Working tree de temiz olabilir.

Bir Dosyanın Yalnızca Bir Bölümünü Stage Edebilir miyim?

Evet. git add -p path/to/file kullanın ve tek tek hunk’ları seçin.

Değişiklikleri Kaybetmeden Unstage Edebilir miyim?

Evet. git restore --staged path/to/file kullanın.

git status --short Çıktısındaki MM Ne Anlama Gelir?

Dosyada stage edilmiş bir değişiklik ve buna ek olarak unstaged bir değişiklik bulunur.

git commit Untracked Dosyaları Dahil Eder mi?

Önce stage edilmedikleri sürece hayır. git commit -a bile normalde untracked dosyaları eklemez.

Her Commit Küçük mü Olmalı?

Commit yapay biçimde küçük değil, odaklı olmalıdır. Tek bir tutarlı değişiklik için gerekli olduklarında çok sayıda dosyayı değiştirebilir.

Son Commit’i Değiştirebilir miyim?

Evet, git commit --amend ile. Koordinasyon olmadan paylaşılan geçmişi amend etmekten kaçının.

Amend Sonrasında Commit Hash Neden Değişti?

Amend yeni bir commit oluşturur. İçerik veya meta veri farklı olduğu için başka bir object identifier alır.

Signed-off-by Doğrulanmış Bir İmza mı?

Hayır. Metinsel bir trailer’dır. Kriptografik signing, signing anahtarları ve -S gibi seçenekler kullanır.

Sonuç

Staging area, düzenleme ile commit arasındaki gereksiz bir engel değildir. Bir sonraki anlık görüntüyü bilinçli biçimde tasarlamanızı sağlayan mekanizmadır.

Working tree mevcut düzenlemeleri, index önerilen commit’i, HEAD ise en son kaydedilen anlık görüntüyü temsil eder. Bu üç katmanlı model anlaşıldığında status ve diff komutları öngörülebilir hale gelir.

Profesyonel bir commit iş akışı basittir: depoyu inceleyin, working değişikliklerini gözden geçirin, tek bir mantıksal birimi stage edin, staged diff’i inceleyin, ilgili testleri çalıştırın, anlamlı bir commit oluşturun ve son durumu doğrulayın.

Temiz geçmiş daha sık commit etmekten veya karmaşık komutlar kullanmaktan doğmaz. Hangi değişikliklerin birlikte olması gerektiğine dair açık kararlar vermekten ve her değişikliğin nedenini korumaktan doğar.

Bir sonraki makale Git geçmişi, farklar ve yardım komutlarına odaklanacaktır. Gelişmiş git log filtreleri, commit inceleme, dosya geçmişi, blame, revision ifadeleri ve bir değişikliğin projeye ne zaman girdiğini bulma teknikleri ele alınacaktır.

Resmî Kaynaklar ve Ek Okumalar