Git Kurulumu ve İlk Ayarlar: git config ile Doğru Başlangıç
Git'i macOS, Windows ve Linux'a kurup sürümünü kontrol ediyor, system/global/local ayar katmanlarını, user.name ve user.email'i, init.defaultBranch main'in neden gerektiğini, core.editor'ü ve core.autocrlf'i görüyoruz. git config list/get/set/unset (2.46+) alt komutlarını eski --get biçimiyle karşılaştırıyoruz.
Sürüm notu: Bu yazıdaki komutlar Git 2.54 ile denenmiştir. git config get/set/list/unset alt komutları Git 2.46 ile geldi; daha eski bir sürümdeysen yazının sonundaki klasik biçimi kullan.
Önce Tahmin Et
Git'i yeni kurdun ve hiçbir ayar yapmadın. Boş bir klasörde git init hello çalıştırıyorsun. Ekrana ne gelir? Repo'nun ilk branch'inin adı ne olur? Bir de şunu düşün: bu repo'da ilk commit'i atsan, commit'in yazarı olarak kimin adı yazılır?
Bu yazıda bu soruların cevabını görüp Git'i bir kez, doğru ayarlarla hazırlayacağız. Bu ayarları bir kere yaparsın, sonra yıllarca dokunmazsın.
Kurulum ve Sürüm Kontrolü
macOS'ta Git'i almanın en kısa yolu Xcode Command Line Tools: terminalde xcode-select --install çalıştırırsın ve Apple'ın derlediği Git /usr/bin/git olarak gelir. Apple bu paketi kendi takvimiyle günceller, bu yüzden genellikle bir iki sürüm geride kalır. En güncel sürümü istiyorsan Homebrew ile brew install git kur; Homebrew'un Git'i PATH'te önce geldiği için o kullanılır.
Windows'ta git-scm.com'daki Git for Windows kurulum dosyasını kullan ya da winget install --id Git.Git -e --source winget çalıştır. Paketin içinde Git Bash adlı bir terminal ve Git Credential Manager da gelir. Linux'ta dağıtımının paket yöneticisi yeterli: Debian/Ubuntu'da sudo apt install git, Fedora'da sudo dnf install git. Dağıtım paketleri de güncel sürümün biraz gerisinden gelir. Bu kurulum komutlarını burada çalıştırmadım, her biri kendi platformuna özgü.
Kurulum nasıl olursa olsun ilk komut aynı:
$ which -a git
/usr/bin/git
$ git --version
git version 2.54.0 (Apple Git-157)
Benim makinemde tek bir Git var ve bu Apple'ın paketi: sürüm 2.54.0, parantez içindeki Apple Git-157 da Apple'ın kendi yama numarası. Bu yazı yazılırken en güncel kararlı sürüm Git 2.56.0. Serideki komutlar 2.54 ile denendi ve bu yazıdakiler 2.46'dan yeni her sürümde aynı çalışır. which -a git birden fazla satır gösterirse hangi Git'in kullanıldığını ilk satır söyler.
Ayarların Üç Katı: System, Global, Local
Git ayarları üç seviyede durur. System seviyesi makinedeki bütün kullanıcılar için geçerlidir ve Git'in kurulduğu yerdeki bir dosyada tutulur; okumak için --system kullanılır. Global seviye senin kullanıcına aittir ve home klasöründeki ~/.gitconfig dosyasında durur. Local seviye ise tek bir repo'ya aittir ve o repo'nun .git/config dosyasındadır.
Aynı ayar birden fazla seviyede varsa en dar olan kazanır: local, global'i; global de system'i ezer. CSS'teki özgüllük gibi düşün: genel kural herkese uygulanır, ama daha özel bir kural yazdığın yerde o geçerli olur. İş repo'larında şirket e-postanı, kişisel projelerde kendi e-postanı kullanmak tam olarak bu katmanlarla yapılır.
macOS'taki Apple Git'in bir de dördüncü, kendine ait bir katmanı var. Henüz hiçbir şey ayarlamamış bir kullanıcıda listeye bakınca şunu görürsün:
$ git config list --show-origin --show-scope
unknown file:/Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig credential.helper=osxkeychain
unknown file:/Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig init.defaultbranch=main
Kapsam unknown görünüyor, çünkü bu dosya Git'in tanıdığı üç seviyeden biri değil; Apple kendi paketine eklemiş. Yalnız Command Line Tools kuruluysa yol /Library/Developer/CommandLineTools altında olur. Dosyada iki ayar var: şifreleri macOS anahtar zincirinde saklayan credential helper ve init.defaultBranch=main. Yazının geri kalanındaki çıktıları bu katman olmadan, Homebrew ya da Linux'taki Git'in davranışıyla aldım; ayarları da sanki hiç yokmuş gibi kendimiz yapacağız.
İlk Repo ve master Uyarısı
Açılıştaki soruya dönelim. Hiç ayar yokken:
$ git init hello
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
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
hint:
hint: Disable this message with "git config set advice.defaultBranchName false"
Initialized empty Git repository in /.../hello/.git/
$ cd hello
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
Git repo'yu oluşturdu ama ilk branch'in adını master koydu ve uzun bir uyarı yazdı. Uyarının ikinci satırı önemli: bu varsayılan Git 3.0'da main olacak. GitHub da 1 Ekim 2020'den beri yeni repo'larda varsayılan branch'i main yapıyor. Yereldeki repo'nun master, GitHub'daki repo'nun main ile başlaması, ilk push'ta kafa karıştıran gereksiz bir uyumsuzluk yaratır.
Henüz commit'i olmayan bu repo'yu uyarının önerdiği gibi düzeltebiliriz:
$ git branch -m main
$ git status
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)
Ama her yeni repo'da bunu yapmak yerine ayarı bir kere global olarak yazmak daha doğru.
Kim Olduğunu Söyle: user.name ve user.email
Her commit'in içinde bir yazar adı ve e-posta adresi vardır. Git bunları user.name ve user.email ayarlarından alır. Ayarlanmamışlarsa bilgisayarın kullanıcı adından ve makine adından bir tahmin üretir; sonuç da çoğu zaman ada@Adas-MacBook-Pro.local gibi bir şey olur. Çoğu makinede commit yine atılır, Git yalnızca "Your name and email address were configured automatically" diye başlayan bir uyarı yazar. Açılıştaki üçüncü sorunun cevabı bu: ayar yoksa yazar kısmına ne yazılacağı şansa kalır. Dört temel ayarı birlikte yapalım:
# Bu komutların çıktısı yok; sessizlik başarı demek
$ git config set --global user.name "Ada Lovelace"
$ git config set --global user.email ada@example.com
$ git config set --global init.defaultBranch main
$ git config set --global core.editor "code --wait"
Burada adın ve e-postanın yanı sıra iki ayar daha var. init.defaultBranch main bundan sonraki her git init'in main ile başlamasını sağlar. core.editor ise Git'in mesaj yazman gerektiğinde açacağı editör; -m vermeden git commit dediğinde bu editör açılır. VS Code için code --wait yazıyoruz, çünkü --wait olmadan Git, sen mesajı yazmadan dosyanın kapandığını sanır. Terminalde kalmak istersen nano ya da vim da olur.
E-posta konusunda bir not: GitHub, commit'leri hesabına e-posta adresi üzerinden bağlar. Buraya yazdığın adres GitHub hesabına ekli değilse commit'lerin profilinde görünmez. Adresini açık etmek istemiyorsan GitHub'ın e-posta ayarlarında sana verdiği noreply adresini kullanabilirsin.
Ayarları Okumak: list, get ve --show-origin
Yazdıklarımızı kontrol edelim:
$ git config list --global --show-origin
file:/.../.gitconfig user.name=Ada Lovelace
file:/.../.gitconfig user.email=ada@example.com
file:/.../.gitconfig init.defaultbranch=main
file:/.../.gitconfig core.editor=code --wait
$ cat ~/.gitconfig
[user]
name = Ada Lovelace
email = ada@example.com
[init]
defaultBranch = main
[core]
editor = code --wait
--show-origin, her ayarın hangi dosyadan geldiğini söyler. Yolun başını ... ile kısalttım; sende home klasörünün tam yolu yazar. Dosyanın kendisi de gördüğün gibi düz bir metin dosyası: köşeli parantez içinde bölüm adı, altında key = value satırları. Elle de düzenleyebilirsin ama komutla yazmak yazım hatası riskini kaldırır. Ayrıca listede anahtarların küçük harfe döndüğüne dikkat et: init.defaultbranch. Git'te bölüm ve anahtar adları büyük-küçük harf duyarlı değildir.
Tek bir ayarı okumak için get var. Satır sonu ayarına da buradan bakalım:
$ git config get user.name
Ada Lovelace
# Ayar yoksa çıktı boştur ve komut 1 koduyla çıkar
$ git config get core.autocrlf
$ git config get --default=false core.autocrlf
false
core.autocrlf, Windows'un satır sonu (CRLF) ile macOS ve Linux'un satır sonu (LF) arasındaki çeviriyi yönetir. Windows'ta Git for Windows kurulumu bunu genellikle true yapar: dosyalar çalışma klasörüne CRLF ile çıkar, repo'ya LF ile girer. macOS ve Linux'ta ayarı boş bırakmak en sorunsuz yol. Ekipte farklı işletim sistemleri varsa daha sağlam çözüm, satır sonu kuralını repo'nun içine koyan .gitattributes dosyası; onu .gitignore yazısında kısaca göreceğiz. --default ise ayar yoksa ne döneceğini söyler; script yazarken işe yarar.
Repo'ya Özel Ayar ve Kim Kazanır?
Şimdi bir repo açıp yalnızca ona özel bir e-posta verelim:
$ git init bookstore
Initialized empty Git repository in /.../bookstore/.git/
$ cd bookstore
$ git branch --show-current
main
# Yalnız bu repo için farklı bir e-posta
$ git config set user.email ada@bookstore.example.com
$ git config list --show-scope --show-origin
global file:/.../.gitconfig user.name=Ada Lovelace
global file:/.../.gitconfig user.email=ada@example.com
global file:/.../.gitconfig init.defaultbranch=main
global file:/.../.gitconfig core.editor=code --wait
local file:.git/config core.repositoryformatversion=0
local file:.git/config core.filemode=true
local file:.git/config core.bare=false
local file:.git/config core.logallrefupdates=true
local file:.git/config core.ignorecase=true
local file:.git/config core.precomposeunicode=true
local file:.git/config user.email=ada@bookstore.example.com
Yeni repo doğrudan main ile başladı, uyarı da çıkmadı. Listede iki kapsam yan yana duruyor: global satırları ~/.gitconfig'ten, local satırları .git/config'ten geliyor. git init'in yazdığı core.* ayarları da local'de; core.ignorecase=true satırı, macOS'un dosya sisteminin büyük-küçük harfe duyarsız olmasından geliyor. Sistem seviyesinde bir ayar olsaydı listenin en başında system satırları da görünürdü. user.email iki kez var; hangisinin geçerli olduğunu soralım:
$ git config get --show-origin user.email
file:.git/config ada@bookstore.example.com
$ git config get --show-scope --all user.email
global ada@example.com
local ada@bookstore.example.com
$ git config unset user.email
$ git config get --show-origin user.email
file:/.../.gitconfig ada@example.com
get tek başına kazanan değeri ve kaynağını verir. --all bütün seviyelerdeki değerleri sırayla gösterir. Local ayarı silince global'deki değer tekrar geçerli oldu. Bir repo'da commit'lerin neden "yanlış" e-postayla atıldığını araştırırken ilk bakacağın komut bu.
Eski Biçim: --get, --global, --list
Git 2.46'dan önce git config'in alt komutları yoktu; ne yapacağını seçenekler ve argüman sayısı belirliyordu. İnternetteki yazıların, StackOverflow cevaplarının ve CI script'lerinin çoğu hâlâ bu biçimde:
$ git config --get user.email
ada@example.com
$ git config --global user.name
Ada Lovelace
$ git config --global --list
user.name=Ada Lovelace
user.email=ada@example.com
init.defaultbranch=main
core.editor=code --wait
Tek argüman verince okur, iki argüman verince yazar: git config --global user.name "Ada Lovelace" eski biçimle ayarı yazar. Git 2.46 sürüm notları bu mod seçeneklerini (--get, --list ve diğerleri) deprecated ilan etti ve yerine get, set, list, unset alt komutlarını getirdi. Eski biçim hâlâ çalışıyor; gördüğünde tanı, yeni yazdığın şeylerde alt komutları kullan. 2.46'dan eski bir Git'in olduğu bir sunucuda ise git config set çalışmaz, orada eski biçime dönersin.
Sık Düşülen Tuzaklar
İlk tuzak, Apple Git'i güncel sanmak. Homebrew ile yeni bir Git kurup terminalde hâlâ /usr/bin/git'in çalıştığını görmek sık rastlanan bir durum; PATH sırası yanlışsa yeni sürüm hiç devreye girmez. Şüphelendiğinde which -a git ve git --version ile kontrol et.
İkincisi, ayarı yanlış seviyeye yazmak. --global unutulursa ayar yalnızca o anda içinde bulunduğun repo'ya yazılır, sonraki repo'da yoktur. Tersine, repo dışında --global olmadan git config set çalıştırırsan Git fatal: not in a git directory diyerek durur.
Üçüncüsü, user.email'i GitHub'daki adresle eşleştirmemek. Commit'ler gider ama profilinde görünmez, ekip arkadaşların da yazarın kim olduğunu tahmin etmek zorunda kalır. Bu sonradan düzeltmesi zahmetli bir hata, çünkü e-posta commit'in içine yazılır ve commit'in hash'inin parçasıdır.
Dördüncüsü, core.editor için VS Code'u --wait olmadan yazmak. Git editörü açar, editör hemen "bitti" der, Git de boş mesajla karşılaşıp commit'i iptal eder.
Küçük Bir Deneme
★☆☆ git --version ve which -a git çalıştır. Hangi Git'i kullandığını ve en güncel sürümün kaç sürüm gerisinde olduğunu bul. Sonra git config list --show-origin --show-scope ile makinendeki bütün ayarları ve geldikleri dosyaları listele.
★★☆ user.name, user.email, init.defaultBranch ve core.editor ayarlarını global olarak yap. Boş bir klasörde git init çalıştırıp git branch --show-current ile branch adının main olduğunu doğrula.
★★★ Bu repo'ya yalnızca ona özel bir user.email ver. git config get --show-scope --all user.email ile iki değeri birlikte gör, sonra local ayarı silip global değerin geri geldiğini kontrol et. Aynı işlemleri bir de eski --get ve --unset biçimiyle dene.
Git hazır, kim olduğunu da biliyor. Bir sonraki yazıda bookstore repo'sunu sıfırdan kuruyoruz: git init, working tree, staging area ve repository üçlüsü, git status, git add ve ilk commit.