Rehber

git add ve git commit: değişiklikler doğru şekilde nasıl kaydedilir

Güncellendi: · Skillaria.Top

Git'te değişiklikler iki adımda kaydedilir: git add istenen değişiklikleri index'e (staging area) ekler, git commit -m "mesaj" ise bunları geçmişe tek bir anlık görüntü olarak yazar. git status neyin değiştiğini ve neyin hazırlandığını gösterir. Son commit git commit --amend ile düzeltilebilir.

Git'te «kaydet» düğmesi yoktur. Değişiklikler iki adımda kaydedilir: önce git add bir sonraki anlık görüntüye hangi değişikliklerin gireceğini seçer, ardından git commit bu anlık görüntüyü geçmişe yazar. Aradaki ara bölgeye index ya da staging area denir. Pek çok kişi bu bölgeyi yıllarca anlamaz, oysa commit'leri anlamlı kılan tam da odur.

Bir dosyanın üç durumu: çalışma dizini, index, geçmiş

Her değişiklik üç bölgeden geçer:

  1. Çalışma dizini (working directory) — dosyayı editörde düzenlersiniz.
  2. Index (stage) — git add, dosyanın mevcut halini bir sonraki commit'in taslağına koyar.
  3. Geçmiş — git commit, index'in içeriğini yazar, tarih ve mesaj içeren bir commit'e dönüştürür.

Kullanışlı bir benzetme: kargo paketi. Çalışma dizini eşyaların bulunduğu odadır, index göndermek istediklerinizi koyduğunuz açık kutudur, commit ise kapatılmış ve üzerine adres yazılmış pakettir. Kutuya ne koyacağınıza siz karar verirsiniz ve her şeyi tek seferde göndermek zorunda değilsiniz.

Index neden gerekli?

Şöyle düşünün: bir saat içinde kimlik doğrulamadaki bir hatayı düzelttiniz, bu arada README'deki bir yazım hatasını giderdiniz ve yeni bir özelliğe başladınız. Index olmasaydı bunların hepsi «çeşitli» adlı tek bir commit'e girerdi. Index sayesinde üç ayrı commit yaparsınız; her biri kolayca anlaşılır, code review'da incelenir ve gerekirse diğerlerine dokunmadan geri alınabilir.

git status: ne değişti ve ne hazırlandı

Her add ve commit öncesinde git status'a bakmak faydalıdır. Git'in en güvenli komutudur — hiçbir şeyi değiştirmez.

$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/auth.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        src/profile.js
  • Changes to be committed — zaten index'te, commit'e girecek;
  • Changes not staged — değişmiş ama eklenmemiş;
  • Untracked files — Git'in henüz bilmediği yeni dosyalar.

Çok sayıda dosya olduğunda kısa format daha kullanışlıdır:

$ git status -s
M  src/auth.js
 M README.md
?? src/profile.js

İlk sütun index'teki durumu, ikincisi çalışma dizinindeki durumu gösterir. Soldaki M «değişti ve eklendi», sağdaki M «değişti, eklenmedi», ?? ise «izlenmiyor» anlamına gelir.

git add: değişiklikleri index'e ekleme

KomutNeyi ekler
git add file.jsBelirli bir dosyayı
git add src/Klasördeki tüm değişiklikleri
git add .Geçerli klasör ve altındaki tüm değişiklikleri, yeni ve silinmiş dosyalar dahil
git add -ATüm repository'deki bütün değişiklikleri
git add -uYalnızca zaten izlenen dosyaları, yenilere dokunmaz
git add -pEtkileşimli olarak, parça parça (hunk)
git add '*.css'Kalıba uyan dosyaları

git add'in eş anlamlısı git stage'dir: ikisi aynı komuttur; «stage», «stage'e almak» terimleri de buradan gelir.

git add -p: dosyanın bir kısmını ekleme

En çok hafife alınan tekniktir. Bir dosyada iki farklı değişiklik karışmışsa, git add -p her parçayı gösterip eklenip eklenmeyeceğini sorar:

$ git add -p src/auth.js
@@ -12,7 +12,7 @@ function login(user) {
-  if (user.password = input) {
+  if (user.password === input) {
(1/2) Stage this hunk [y,n,q,a,d,s,e,?]?

y — ekle, n — atla, s — parçayı daha küçük parçalara böl, q — çık. Böylece tek bir dosyadan iki düzenli commit çıkar.

Commit'e tam olarak neyin gideceğini kontrol etme

git diff            # henüz index'e EKLENMEMİŞ değişiklikler
git diff --staged   # zaten index'te olan ve commit'e girecek olanlar

Sık yaşanan bir karışıklık: git add'den sonra sade git diff hiçbir şey göstermez. Bu, değişikliklerin kaybolduğu anlamına gelmez — index'tedirler, git diff --staged ile bakın (eş anlamlısı --cached).

Bir dosyayı index'ten çıkarma

git restore --staged file.js

Dosyadaki değişiklikler yerinde kalır, dosya yalnızca commit için hazırlanmış olmaktan çıkar. Git'in eski sürümlerinde bunun için git reset HEAD file.js kullanılırdı — hâlâ çalışır.

git commit: değişiklikleri kaydetme

git commit -m "Girişte parola kontrolünü düzelt"
[main 3f2a9c1] Girişte parola kontrolünü düzelt
 1 file changed, 1 insertion(+), 1 deletion(-)

Çıktıda branch, yeni commit'in kısa hash'i ve istatistik bulunur. Commit'e yalnızca index'in içeriği girer. git add'den sonra dosyayı yeniden düzenlediyseniz, bu yeni değişiklikler siz tekrar ekleyene kadar commit'e girmez.

git commit'in faydalı seçenekleri

KomutNe yapar
git commitÇok satırlı mesaj için editör açar
git commit -m "..."Mesajı doğrudan komutta verir
git commit -am "..."Değişmiş tüm izlenen dosyaları ekleyip commit eder; yeni dosyalar girmez
git commit -vMesajı yazarken editörde diff'i gösterir
git commit --amendSon commit'in üzerine yazar
git commit --allow-empty -m "..."Boş commit, örneğin CI'ı yeniden tetiklemek için

Varsayılan editör Vim ise ve içinde takılıp kaldıysanız: mesajı yazın, Esc'ye basın, ardından :wq yazıp Enter'a basın. Editörü değiştirmek için: git config --global core.editor "code --wait" ya da nano.

İyi bir commit mesajı nasıl yazılır

Mesaj, altı ay sonra bir hatanın nereden geldiği araştırılırken okunur. «Bugün ne yaptım» sorusuna değil, «ne ve neden» sorusuna cevap vermelidir.

  • ilk satır 50–72 karakteri geçmesin, değişikliğin özünü anlatsın;
  • emir kipinde ya da nötr yazın: «E-posta doğrulaması ekle», «Fix login redirect»;
  • gerekirse boş bir satır bırakıp ayrıntıları ekleyin: neden böyle yapıldı, hangi kısıtlar var;
  • bir commit — bir mantıksal değişiklik.

Kötü: fix, düzeltmeler, wip, asdf. İyi: Ürün listesi boşken sepetin çökmesini düzelt. Birçok ekip Conventional Commits formatını kullanır: feat: ..., fix: ..., docs: ....

git commit --amend: son commit nasıl düzeltilir

Mesajda yazım hatası mı var ya da bir dosyayı eklemeyi mi unuttunuz? «Dosyayı unuttum» diye yeni bir commit yapmanıza gerek yok. Bunun için amend vardır.

Mesajı düzeltme

git commit --amend -m "Girişte parola kontrolünü düzelt"

Unutulan dosyayı ekleme

git add forgotten.js
git commit --amend --no-edit

--no-edit seçeneği önceki mesajı korur.

amend hakkında önemli not

--amend commit'i «düzenlemez»; farklı hash'e sahip yeni bir commit oluşturur ve eskisinin yerine koyar. Commit yalnızca sizdeyken bu güvenlidir. Zaten git push yaptıysanız, amend'den sonra normal push reddedilir ve git push --force-with-lease kullanmanız gerekir. Başkalarının çalıştığı ortak branch'lerde bunu yapmamak gerekir: üzerine iş inşa ettikleri geçmişi yeniden yazmış olursunuz.

Amend yanlışlıkla yapıldıysa, eski commit'i git reflog'da bulup git reset --soft HEAD@{1} ile ona dönebilirsiniz.

Sık yapılan hatalar

«nothing to commit, working tree clean»

Değişiklik yok — her şey zaten commit edilmiş ya da dosyayı başka bir klasörde düzenliyorsunuz. git status'u ve proje yolunu kontrol edin.

«no changes added to commit»

Dosyalar değişmiş ama index'e eklenmemiş. git add çalıştırın ya da zaten izlenen dosyalar için git commit -am kullanın.

«Please tell me who you are»

Ad ve e-posta ayarlanmamış. Bir kez git config --global user.name "Adınız" ve git config --global user.email "e-posta" çalıştırın.

Fazladan bir şey commit edildi

Commit henüz gönderilmediyse, değişiklikleri index'te tutarak geri alın: git reset --soft HEAD~1. Ardından fazlalığı git restore --staged ile çıkarın ve yeniden commit edin. Commit'e bir gizli bilgi (secret) girdiyse, onu ele geçirilmiş sayın ve yenisini oluşturun.

git add . gereksiz dosyalar ekledi

.gitignore'u önceden ayarlayın ve commit öncesinde git status'a bakın. Zaten izlenen bir dosya ancak git rm --cached dosya sonrasında izlenmeyi bırakır.

Commit aslında nedir

Commit, önceki sürümle farkı değil, tüm projenin anlık görüntüsünü saklar: dosya ağacına bir referans, üst (parent) commit'e bir referans, yazar, tarih ve mesaj. Değişmemiş dosyalar kopyalanmaz — Git zaten kaydedilmiş nesnelere referans verir, bu yüzden geçmiş az yer kaplar.

Commit hash'i (örneğin 3f2a9c1) tüm bu içerikten hesaplanır. Mesajdaki tek bir harfi değiştirseniz bile farklı bir hash elde edersiniz. İşte bu yüzden --amend ve rebase eskilerini düzeltmek yerine yeni commit'ler oluşturur ve bu yüzden yeniden yazılmış geçmiş, ekip arkadaşlarınızdaki kopyalarla çakışır.

Geçmişe kısaca şöyle bakabilirsiniz:

git log --oneline --graph -10

Her satır bir commit'tir; geçmişinizdeki mesajlar diff'i açmadan anlaşılıyorsa, her şeyi doğru yapıyorsunuz demektir.

Günlük çalışma döngüsü

git status                 # ne değişti
git diff                   # değişikliklere bak
git add -p                 # gerekenleri seç
git diff --staged          # commit'e neyin gideceğini kontrol et
git commit -m "Anlaşılır bir açıklama"
git log --oneline -5       # commit'in yerinde olduğundan emin ol
git push                   # sunucuya gönder

Commit değişiklikleri yalnızca yerel olarak kaydeder. GitHub'a veya başka bir sunucuya ulaşmaları için git push gerekir.

Özet

git add bir sonraki anlık görüntüyü index'te toplar, git status ve git diff --staged ona neyin gireceğini gösterir, git commit ise anlık görüntüyü geçmişe yazar. Anlaşılır mesajlara sahip küçük ve mantıklı commit'ler yapın; son commit'teki küçük düzeltmeler için push'tan önce git commit --amend kullanın. Index ve add → commit iki adımlı şeması Git kursunda uygulamalı olarak ele alınıyor.

Sık sorulan sorular

Ne sıklıkla commit yapmalıyım?

Bir mantıksal değişiklik tamamlandığında ve proje çalışır durumdayken. Gün sonunda tek dev bir commit yerine çok sayıda küçük commit daha iyidir.

Git'te git save komutu var mı?

Hayır, böyle bir komut yok. Kaydetme git add ve git commit ile yapılır; yarım kalan işi geçici olarak kenara koymak için git stash kullanılabilir.

Bir commit'in içinde ne olduğunu nasıl görürüm?

git show hash komutu commit'in yazarını, mesajını ve tüm değişikliklerini gösterir. Hash vermezseniz son commit'i gösterir.

git add . ile git add -A arasındaki fark nedir?

Git'in güncel sürümlerinde ikisi de yeni, değişmiş ve silinmiş dosyaları ekler. Fark kapsamdadır: git add . geçerli klasör ve alt klasörlerle, git add -A ise tüm repository ile çalışır.

Son commit'i değil, daha eski bir commit'i değiştirebilir miyim?

Evet, etkileşimli rebase ile: git rebase -i üst-commit-hash'i, ardından ilgili commit'i edit veya reword olarak işaretleyin. Bunu yalnızca henüz ortak branch'e gönderilmemiş commit'lerle yapın.

Bu konuyu videoyla öğrenin

Bu konu “Sıfırdan Güvenilir Geliştiriciye Git” kursunda uygulamalı olarak ayrıntılı işleniyor.

Kursa git