Mert Özen Her Satırda Daha İleri
DevOps Git & GitHub — #29

Git 3.0'a Hazırlık: Ne Değişiyor, Ne Kalkıyor, Bugünden Ne Yapmalı

Mert Özen 6 Kas 2026 8 dk 1 görüntülenme
Git 3.0'a Hazırlık: Ne Değişiyor, Ne Kalkıyor, Bugünden Ne Yapmalı

Git 3.0 için resmi durumu (BreakingChanges.adoc: henüz tarih yok) GitLab ve LWN'in aktardığı plandan ayırıyoruz. main, SHA-256 ve reftable varsayılanlarını, safe.bareRepository'yi, zorunlu Rust'ı, kaldırılacak komutları ve git checkout'un neden kaldığını Git 2.54'te deneyip bir hazırlık listesi çıkarıyoruz.

Sürüm notu: Bu yazı Git 3.0'a hazırlığı anlatır; Git 3.0 henüz yayınlanmadı. Komutlar Git 2.54 ile denenmiştir, bilgiler 5 Kasım 2026 itibarıyla günceldir.

Önce Tahmin Et

Eski bir blog yazısında, bir commit'in hangi dosyalara dokunduğunu görmek için şu komut öneriliyor. Git 2.54'te bookstore repo'sunda çalıştırıyorsun. Sence ne olur: commit listesi mi gelir, bir uyarıyla birlikte liste mi, yoksa hiçbiri mi?

$ git whatchanged -1

Cevap:

$ git whatchanged -1
'git whatchanged' is nominated for removal.

hint: You can replace 'git whatchanged <opts>' with:
hint:	git log <opts> --raw --no-merges
hint: Or make an alias:
hint:	git config set --global alias.whatchanged 'log --raw --no-merges'

If you still use this command, here's what you can do:

- read https://git-scm.com/docs/BreakingChanges.html
- check if anyone has discussed this on the mailing
  list and if they came up with something that can
  help you: https://lore.kernel.org/git/?q=git%20whatchanged
- send an email to <git@vger.kernel.org> to let us
  know that you still use this command and were unable
  to determine a suitable replacement

fatal: refusing to run without --i-still-use-this

Hiçbiri. Komut hâlâ Git'in içinde ama sen --i-still-use-this demeden çalışmayı reddediyor. Git 3.0'a böyle hazırlanılıyor: önce uyarı, sonra kullanmayı zorlaştırmak, en son kaldırmak. Bu yazı serinin son halkası. Git 3.0'da ne değişecek, ne kalkacak, ne kalacak ve bugünden ne yapabilirsin, ona bakıyoruz.

Resmi Durum ve Konuşulan Plan

Önce ayrımı net yapalım, çünkü internette ikisi sık karışıyor.

Resmi durum şu: Git 3.0 yayınlanmadı, v3 ile başlayan bir tag yok. Git'in kendi deposundaki Documentation/BreakingChanges.adoc belgesi 3.0'da nelerin değişeceğini listeliyor ve tarih konusunda açık: "There is no planned release date for this breaking version yet." Yani bu kırıcı sürüm için henüz planlanmış bir tarih yok. Belgenin söz verdiği bir şey daha var: 3.0'dan önceki son sürüm uzun süreli destekli (LTS) olacak, en az dört sürüm döngüsü boyunca hata düzeltmesi, altı döngü boyunca güvenlik düzeltmesi alacak. Bir de sürüm numarası değişti: güncel sürüm 2.56, ama master branch'te "Git 2.98" döngüsü başladı ve taslak release notes 2.98'i 3.0'a hazırlanan sondan üçüncü sürüm olarak tanımlıyor.

Konuşulan plan ise şu: GitLab'in 28 Eylül 2026 tarihli "What's new in Git 2.56.0" yazısı ve LWN'in 18 Eylül 2026 tarihli haberi, 2.98'in Aralık 2026'da, 2.99 ile 3.0'ın ise 2027 baharında birlikte çıkmasının planlandığını yazıyor. Buna göre 2.99 LTS sürüm olacak ve 3.0'dan tek farkı, kırıcı değişikliklerin anahtarının açık olmaması. LWN bu takvimin Git Contributor Summit'te konuşulduğunu ve maintainer Junio Hamano'nun bunu mail listesinde henüz duyurmadığını da not ediyor. Yani bu tarihler bir plan; bir duyuru değil. Takvimine yazarken "civarı" diye yaz.

Kırıcı değişikliklerin her biri WITH_BREAKING_CHANGES adlı bir derleme anahtarının arkasında duruyor. Git'i bu anahtarla derlersen 3.0 davranışını bugünden görürsün; proje CI'da bu derlemeyi düzenli olarak test ediyor. Normal dağıtılan Git'lerde bu anahtar kapalı.

Değişecek Varsayılanlar: main, SHA-256, reftable

Üç varsayılan değişiyor ve üçünü de seride daha önce gördük. İlki branch adı. Ayarı olmayan bir makinede git init'in hint'i bunu zaten söylüyor:

$ git init fresh
hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
...

Bu karar 2.52'de resmen ilan edildi. İkincisi yeni repo'larda object hash'inin SHA-1'den SHA-256'ya, üçüncüsü de ref deposunun "files"tan reftable'a geçmesi. Belge, SHA-256 için kütüphanelerin ve barındırma platformlarının, reftable için de JGit, libgit2 ve Gitoxide'ın hazır olmasını şart koşuyor. SHA-1 deprecated olmayacak; var olan repo'ların olduğu gibi çalışmaya devam edecek. Değişen yalnızca yeni açılan repo'ların varsayılanı.

Bunların üçünü de bugün açıkça seçebilirsin:

$ git config set --global init.defaultRefFormat reftable
$ git init -q --object-format=sha256 b3
$ cd b3
$ git repo info object.format references.format
object.format=sha256
references.format=reftable
$ git branch --show-current
main
$ git commit -m "Add README"
[main (root-commit) c380a48] Add README
 1 file changed, 3 insertions(+)
 create mode 100644 README.md
$ git push ../bookstore.git main:sha256-test
fatal: the receiving end does not support this repository's hash algorithm

Son satır, SHA-256'nın neden hâlâ "yerelde dene" aşamasında olduğunu gösteriyor: SHA-1 bir remote'a push edemiyorsun ve iki format arasında dönüşüm yok. reftable ise bugün güvenle denenebilir; ref biçimi yereldir ve remote'u ilgilendirmez.

Güvenlik: safe.bareRepository

Bir saldırgan, repo'sunun içine dosya olarak bir bare repo koyabilir. Sen o repo'yu clone'layıp o klasöre cd ettiğinde Git, içinde bulunduğun klasörü bare repo olarak keşfeder ve onun config'ini okur. Config'de çalıştırılacak bir komut tanımlıysa, sıradan bir git status bile onu tetikleyebilir. 3.0'da safe.bareRepository'nin varsayılanı all'dan explicit'e geçecek: Git, kendiliğinden keşfettiği bare repo'larda çalışmayı reddedecek. Bugün açıp etkisine bakalım:

$ git config set --global safe.bareRepository explicit
$ cd bookstore.git
$ git log --oneline -1
fatal: cannot use bare repository '.../bookstore.git' (safe.bareRepository is 'explicit')
$ git --git-dir=. log --oneline -1
4734313 Add cart total
$ cd ..
$ git -C bookstore ls-remote ../bookstore.git main
47343131d946a43f3c701a7499a1ffc49e1734a3	refs/heads/main

Bare repo'nun içinde dolaşırken artık --git-dir ile açıkça söylemen gerekiyor. Ama remote olarak kullanmak etkilenmiyor: push, fetch ve ls-remote yolu zaten açıkça verdiği için çalışmaya devam ediyor. Etkilenecek olanlar, bare repo klasörüne girip doğrudan komut çalıştıran script'ler ve sunucu bakım işleri.

Rust Zorunlu Oluyor

Git şimdiye kadar C ile yazıldı ve bir C derleyicisi olan her platformda derlenebiliyordu. Rust'ın girişi adım adım oldu: 2.49'da Rust için bir arayüz geldi, 2.52'de ilk isteğe bağlı Rust parçası eklendi, 2.55'te Rust iki build sisteminde de varsayılan olarak açıldı. 3.0'da kapatma seçeneği kalkacak, yani Git'i derlemek için bir Rust derleyicisi gerekecek.

Senin için bunun pratik anlamı büyük ihtimalle yok; Git'i paket yöneticisinden ya da resmi installer'dan kuruyorsan derleme meselesi paketleyicinin işi. Etkilenecekler Rust desteği olmayan eski ya da egzotik platformlar. 2.99'un LTS olması tam bu platformlar düşünülerek planlanıyor. Belge, dağıtımlar üzerindeki etki fazla büyük olursa Rust zorunluluğunun 3.0'dan sonraya kayabileceğini de söylüyor.

Kaldırılacaklar

Açılıştaki whatchanged listedeki tek komut değil. git pack-redundant da aynı muameleyi görüyor; 2023'ten beri --i-still-use-this olmadan çalışmıyor. name-rev --stdin ise 2.40'tan beri bir uyarıyla çalışıyor:

$ git log --raw --no-merges -1
commit 47343131d946a43f3c701a7499a1ffc49e1734a3
Author: Ada Lovelace <ada@example.com>
Date:   Sat Nov 7 10:02:00 2026 +0300

    Add cart total

:000000 100644 0000000 aee2863 A	src/cart.js
$ git log --format=%H -1 | git name-rev --stdin
warning: --stdin is deprecated. Please use --annotate-stdin instead, which is functionally equivalent.
This option will be removed in a future release.
47343131d946a43f3c701a7499a1ffc49e1734a3 (main)
$ git log --format=%H -1 | git name-rev --annotate-stdin
47343131d946a43f3c701a7499a1ffc49e1734a3 (main)

whatchanged'in yerine git log --raw --no-merges, name-rev --stdin'in yerine --annotate-stdin var. Listede başka neler var? Geçmişi yerel olarak "yamamaya" yarayan .git/info/grafts dosyası gidiyor; yerini çoktan git replace aldı. Remote tanımlamanın tarih öncesi yolları olan .git/branches/ ve .git/remotes/ klasörleri gidiyor; bugün herkes config'teki [remote] bölümlerini kullanıyor. 2.52'de deprecated olan core.commentChar=auto ve core.commentString=auto değerleri, ve symbolic ref'leri symlink olarak yazmak (core.preferSymlinkRefs=true) da kalkıyor; okuma desteği kalıyor, yazma gidiyor.

Kalanlar: git checkout Kaldırılmıyor

Blok B'nin ilk yazısında switch ve restore'un neden daha güvenli olduğunu konuştuk. Bu, git checkout'un gideceği anlamına gelmiyor:

$ git checkout -q -b try-checkout; git branch --show-current
try-checkout

BreakingChanges belgesinde "deprecated olmayacak, yerine yenisi gelmiş özellikler" diye ayrı bir bölüm var ve git checkout orada. Gerekçe basit: çok yaygın kullanılıyor ve kaldırmak sayısız script'i, eğitimi ve alışkanlığı kırar. Üç komut birlikte yaşamaya devam edecek. İnternette "Git 3.0 checkout'u kaldırıyor" diye bir başlık görürsen, yanlış.

Bugünden Hazırlık: Kontrol Listesi

Bir: global config'ine init.defaultBranch main yaz. 3.0 geldiğinde hiçbir şey değişmez, bugün de hint'ten kurtulursun. Eski repo'larında master kullanıyorsan acele etme; varsayılan yalnızca yeni repo'ları etkiliyor.

İki: script'lerinde ve alias'larında whatchanged, pack-redundant, name-rev --stdin geçiyor mu, bir grep ile bak. .git/branches ya da .git/info/grafts kullanan çok eski bir otomasyon varsa onu da listeye ekle.

Üç: ref dosyalarını doğrudan okuyan kodları Git komutlarına çevir ve bir deneme repo'sunu git refs migrate --ref-format=reftable ile taşı. IDE'n ve CI araçların açabiliyor mu, gör.

Dört: safe.bareRepository explicit'i kendi makinende aç. Bir şey kırılırsa bunu 3.0 gelmeden öğrenmiş olursun.

Beş: SHA-256'yı yalnızca yerel bir repo'da dene; barındırma platformun ve araçların desteklediğini görmeden ekip repo'su için seçme.

Altı: CI image'larındaki ve sunuculardaki Git sürümlerini not et. 2.99 LTS olacaksa ve 3.0'a geçemeyen bir platformun varsa, nerede kalacağını bilmek isteyeceksin.

Sık Düşülen Tuzaklar

İlki konuşulan takvimi kesin tarih sanmak. 2027 baharı bir plan; resmi belge hâlâ "tarih yok" diyor. Bir projenin yol haritasını bu tarihe kilitleme.

İkincisi "SHA-1 kalkıyor" paniği. Var olan SHA-1 repo'ları 3.0'da da çalışacak; değişen yeni repo'ların varsayılanı. Bütün repo'larını şimdiden dönüştürmeye çalışmak, şu an için çözümden çok sorun üretir.

Üçüncüsü --i-still-use-this'i kalıcı çözüm sanmak. Bu bayrak "biraz daha zaman ver" demek; 3.0 ile birlikte komutun kendisi gidiyor. Bayrağı script'ine eklediysen yanına bir not düş ve yerine geçen komuta geç.

Dördüncüsü checkout'u kullanan bütün script'leri panikle yeniden yazmak. Gerek yok; yeni yazdıklarında switch ve restore'u tercih etmen yeterli.

Küçük Bir Deneme

★☆☆ Kendi makinende git config list --show-scope çıktısında init.defaultBranch var mı? Yoksa ekle ve git init'in hint'inin kaybolduğunu gör.

★★☆ Kendi dotfile'larında ve proje script'lerinde whatchanged, name-rev --stdin, .git/refs/heads ve git config --get geçen yerleri bul. Kaç tane çıktı? Hangilerinin 3.0'da kırılacağını, hangilerinin sadece deprecated olduğunu ayır.

★★★ Bir deneme repo'sunu reftable'a taşı, safe.bareRepository explicit'i aç ve bir hafta boyunca günlük işini öyle yap. Sonunda hangi araçların sorun çıkardığını not et.

Bu yazıyla serinin şimdilik sonuna geldik: ilk commit'ten hook'lara, checkout'tan git history'ye kadar. Ama Git durmuyor. Seri, yeni Git sürümleriyle devam edecek: 2.98 çıktığında, 3.0 geldiğinde ve sonrasında, "eskiden böyle yapıyorduk, şimdi şöyle" diye yeni yazılar ekleyeceğiz.