Rehber

Git'te branch'ler: git branch ile oluşturma, geçiş yapma ve silme

Güncellendi: · Skillaria.Top

Git'te branch, bir commit'e işaret eden hafif bir göstericidir; HEAD ise şu anda hangi branch'te olduğunuzu gösterir. git branch branch'leri listeler, oluşturur, yeniden adlandırır ve siler; git switch aralarında geçiş yapar; git switch -c ad ise branch'i oluşturup hemen ona geçer.

Git'te branch nedir?

Git'te bir branch projenin kopyası değil, tek bir commit'in hash'ini içeren küçük bir dosyadır. Branch oluşturmak saniyenin kesirleri kadar sürer ve neredeyse hiç yer kaplamaz, çünkü Git hiçbir şeyi çoğaltmaz: tüm branch'ler repository veritabanındaki aynı nesnelere işaret eder. Commit yaptığınızda geçerli branch'in göstericisi yalnızca yeni commit'e kayar.

Bu, branch'lere bakışı değiştirir. Onlardan korkmanıza veya tasarruf etmenize gerek yoktur: her görev, düzeltme veya deney için ayrı bir branch açmak normal bir pratiktir. Deney başarısız olursa branch silinir ve ana geçmiş temiz kalır.

Branch'in bir dosya olduğunu kendi gözlerinizle görebilirsiniz:

$ cat .git/refs/heads/main
8b7d4e2a9f1c0d3e5b6a7c8d9e0f1a2b3c4d5e6f

(Büyük repository'lerde referansların bir kısmı .git/packed-refs içinde paketlenir, bu yüzden dosya olmayabilir — öz değişmez.)

Git'te HEAD: şu anda neredesiniz

HEAD, çalışma dizininize şu anda neyin «çıkarıldığını» gösteren bir göstericidir. Genellikle HEAD bir commit'e değil, bir branch'e işaret eder:

$ cat .git/HEAD
ref: refs/heads/main

Zincir şöyledir: HEAD → main → commit. Yeni bir commit, HEAD'in baktığı commit'i parent olarak alır; ardından Git, HEAD'in işaret ettiği branch'i ilerletir. Commit'lerin geçerli branch'e «düşmesinin» nedeni budur.

Doğrudan bir commit'e veya tag'e geçerseniz (git switch --detach v1.0 veya git checkout 3f2a1c9), HEAD doğrudan commit'e işaret eder. Bu duruma detached HEAD denir. Bu durumda koda bakmak güvenlidir, ancak yeni commit'ler hiçbir branch'e bağlı değildir ve geçiş yaptıktan sonra kolayca kaybolur. Bir şeyler değiştirmeye başladıysanız, tam orada bir branch oluşturun: git switch -c fix-from-old-version.

İfadelerde HEAD'i başlangıç noktası olarak kullanmak pratiktir: HEAD~1 — önceki commit, HEAD~3 — üç commit önce, HEAD^2 — bir merge commit'inin ikinci parent'ı.

Branch'leri görüntüleme: git branch

git branch            # yerel branch'ler, geçerli olan * ile işaretli
git branch -v         # artı her birindeki son commit
git branch -vv        # artı upstream ve geride/önde olma durumu
git branch -r         # uzak branch'ler (origin/...)
git branch -a         # tüm branch'ler
git branch --show-current   # yalnızca geçerli branch'in adı

git branch -vv çıktısı örneği:

  feature/login 4c1e2d7 [origin/feature/login: ahead 2] Giriş formu
* main          8b7d4e2 [origin/main] README'yi güncelle
  old-spike     1a9b3c0 Önbellek denemesi

Burada feature/login'de gönderilmemiş iki commit olduğu, main'in sunucuyla aynı olduğu ve old-spike'ın sunucuda hiç karşılığı olmadığı görülüyor.

Branch'leri filtrelemek için git branch --merged (geçerli branch'e zaten merge edilmiş — silme adayları), git branch --no-merged (henüz merge edilmemiş) ve git branch --list 'feature/*' (kalıba göre) kullanılır.

Branch nasıl oluşturulur

İki yol vardır. git branch bir branch oluşturur ama sizi geçerli branch'te bırakır:

git branch feature/login            # geçerli commit'ten
git branch hotfix v1.2.0            # bir tag'den
git branch review 3f2a1c9           # belirli bir commit'ten

Çoğu zaman branch'i oluşturup hemen ona geçmek gerekir. Bunun için git switch -c (Git 2.23'te geldi) veya eski karşılığı git checkout -b vardır:

git switch -c feature/login
git switch -c hotfix origin/main    # sunucunun güncel durumundan yeni branch

İyi bir alışkanlık: bir görev için branch oluşturmadan önce tabanı güncelleyin: git fetch, ardından git switch -c feature/x origin/main. Böylece branch, uzun süredir güncellenmemiş yerel main'inizden değil, güncel koddan başlar.

Branch'ler nasıl adlandırılır

Ekiplerde yerleşik kurallar: iş türüne göre bir önek ve tirelerle ayrılmış kısa bir açıklama — feature/user-avatar, fix/login-timeout, chore/update-deps, bazen görev numarasıyla: feature/SHOP-142-cart. Boşluk, ~ ^ : ? * [, art arda iki nokta ve .lock ile bitiş kullanılamaz.

Branch'e geçiş: git switch

git switch main             # mevcut bir branch'e geç
git switch -                # önceki branch'e dön
git switch feature/login    # yerelde yoksa ama origin/feature/login varsa,
                            # Git yerel bir branch oluşturup uzak olana bağlar

Geçiş sırasında Git, çalışma dizinindeki dosyaları hedef branch'teki sürümle değiştirir. Commit edilmemiş değişiklikler hedef branch ile çakışmıyorsa sizinle birlikte taşınır. Çakışıyorsa Git reddeder:

error: Your local changes to the following files would be overwritten by checkout:
        app.js
Please commit your changes or stash them before you switch branches.

Çözümler: commit etmek, git stash ile saklamak (sonra git stash pop ile geri almak) veya değişiklikleri bilerek merge denemesiyle taşımak: git switch -m main. --discard-changes seçeneği değişiklikleri çöpe atar — yalnızca kesinlikle gerekmediklerinden eminseniz kullanın.

Neden checkout değil de git switch? Checkout hem branch değiştirebilir hem de dosyaların üzerine yazabilir, bu yüzden hata yapmak kolaydır. Switch yalnızca tek bir şey yapar — branch'lerle çalışır, bu yüzden daha güvenlidir. checkout, switch ve restore'un ayrıntılı karşılaştırması ayrı bir makalede.

Branch nasıl yeniden adlandırılır

git branch -m new-name              # geçerli branch'i yeniden adlandır
git branch -m old-name new-name     # herhangi birini yeniden adlandır
git branch -M main                  # aynısı, mevcut branch'in üzerine yazarak

Branch zaten sunucudaysa yeniden adlandırma yalnızca yereldir. Yenisini gönderin ve eskisini silin:

git push -u origin new-name
git push origin --delete old-name

Branch nasıl silinir

git branch -d feature/login     # yalnızca branch merge edildiyse siler
git branch -D old-spike         # zorla siler
git push origin --delete feature/login   # sunucuda siler

-d iş kaybına karşı korur: branch'te geçerli branch'te (veya onun upstream'inde) olmayan commit'ler varsa Git «The branch 'x' is not fully merged» mesajıyla reddeder. -D soru sormadan siler. Geçerli branch silinemez — önce başka bir branch'e geçin.

Yanlış şeyi mi sildiniz? Commit'ler hemen kaybolmaz. Branch'in son commit'inin hash'ini git reflog'da bulun ve geri yükleyin: git branch old-spike 1a9b3c0.

Sunucuda artık bulunmayan uzak branch'lerin eskimiş kayıtlarını git fetch --prune temizler.

Yerel branch'i uzak branch'e bağlama

Yerel bir branch'in upstream'i olabilir — karşılaştırıldığı ve senkronize edildiği uzak branch. Upstream, git push ve git pull'un argümansız çalışması ve git status'un «ahead/behind» göstermesi için gereklidir.

git push -u origin feature/login                 # ilk gönderimde
git branch --set-upstream-to=origin/main main    # mevcut bir branch için
git branch --unset-upstream                      # bağlantıyı kaldır

Branch'leri birleştirme: kısaca

Branch'ler sonradan birleştirilmek için oluşturulur. İş hazır olduğunda hedef branch'e geçin ve kendi branch'inizi ona merge edin:

git switch main
git merge feature/login

Branch oluşturulduğundan beri main ilerlemediyse Git fast-forward yapar: merge commit'i olmadan main göstericisini branch'in son commit'ine taşır. Her iki branch de yeni commit'ler aldıysa three-way merge gerçekleşir: Git ortak atayı bulur, iki tarafı karşılaştırır ve iki parent'ı olan bir merge commit'i oluşturur. Ekiplerde merge genellikle sunucudaki pull request ile yapılır, yerelde ise yalnızca güncel main çekilir.

Branch kopya kağıdı

GörevKomut
Branch listesigit branch -vv
Branch oluşturgit branch ad
Oluştur ve geçgit switch -c ad
Geçiş yapgit switch ad
Geri döngit switch -
Yeniden adlandırgit branch -m eski yeni
Merge edilmişi silgit branch -d ad
Zorla silgit branch -D ad
Sunucuda silgit push origin --delete ad
Silinebilecek branch'lergit branch --merged
Silineni geri yüklegit reflog, ardından git branch ad hash

Yeni başlayanların sık yaptığı hatalar

  • Doğrudan main'de çalışmak. Commit'ler yapıldıysa ama gönderilmediyse, bulunduğunuz yerde bir branch oluşturun (git branch feature/x), ardından main'i sunucudaki haline döndürün: git reset --hard origin/main (her şeyin commit edildiğini kontrol edin).
  • Eski main'den branch açmak. Önce git fetch, branch'i origin/main'den oluşturun.
  • Detached HEAD'de commit. Geçiş yapmadan önce branch oluşturun; zaten geçtiyseniz commit'leri git reflog'da bulun.
  • Uzun ömürlü branch'ler. Bir branch ne kadar uzun süre ayrı yaşarsa merge o kadar acılı olur. main'i düzenli olarak çekin ve işi küçük parçalar halinde merge edin.

Ekip çalışmasında branch'ler

Ekiplerin süreçleri farklıdır, ama neredeyse her yerde iki şemadan biri görülür. GitHub Flow'da her zaman yayına hazır olan tek bir uzun ömürlü main branch'i ve review ile CI kontrollerinden sonra pull request ile merge edilen kısa feature branch'leri vardır. Git Flow'da bunlara develop, release branch'leri ve hotfix branch'leri eklenir; şema daha ağırdır ve seyrek, sürümlü yayınlar yapan ürünlere uygundur.

Şemadan bağımsız olarak ortak kurallar geçerlidir: bir branch — bir görev, branch aylarca değil günlerce yaşar, pull request'ten önce branch güncel main ile güncellenir, merge'den sonra branch hem yerelde hem sunucuda silinir. Ana branch repository ayarlarıyla korunur: doğrudan push ve force push yasaktır, merge yalnızca review üzerinden yapılır.

Branch geçmişi nasıl görüntülenir

Branch'lerin birbiriyle ilişkisini anlamanın en kolay yolu grafiktir: git log --oneline --graph --all tüm branch'leri ve ayrıldıkları noktaları doğrudan terminalde çizer. Bir branch'te olup henüz main'e girmemiş commit'leri görmek için git log main..feature/login, dosyalardaki farkı görmek için git diff main...feature/login kullanın (üç nokta ortak ataya göre karşılaştırır, yani yalnızca branch'in kendi değişikliklerini gösterir).

Özet

Git'te branch, bir commit'e işaret eden ucuz bir göstericidir; HEAD ise geçerli branch'e işaret eden göstericidir. git branch branch'leri yönetir (listeleme, oluşturma, yeniden adlandırma, silme), git switch aralarında geçiş yapar, git switch -c ise ikisini birden yapar. Branch'ler, HEAD, fast-forward ve three-way merge Git kursunda canlı örneklerle ele alınıyor.

Sık sorulan sorular

Git'te kaç branch oluşturulabilir?

Pratikte istediğiniz kadar: her branch birkaç on baytlık bir referanstır, bu yüzden boyut açısından bir sınır yoktur.

Branch silinince commit'ler de silinir mi?

Hemen değil. Artık hiçbir şeyin işaret etmediği commit'ler bir süre daha saklanır ve çöp toplayıcı onları silene kadar git reflog üzerinden erişilebilir (erişilemeyen reflog kayıtları için varsayılan olarak en az 30 gün).

Geçerli branch'in hangi branch'ten oluşturulduğunu nasıl öğrenirim?

Git bunu saklamaz: branch yalnızca kendi commit'ini hatırlar. main ile ortak atayı git merge-base HEAD main komutuyla bulabilirsiniz.

Branch ile tag arasındaki fark nedir?

Branch her yeni commit ile ilerler, tag ise kalıcı olarak tek bir commit'e sabitlenir ve sürümleri işaretlemek için kullanılır.

Neden master değil de main?

Bu yalnızca varsayılan branch adıdır. Birçok servis main'e geçti; yeni repository'ler için adı git config --global init.defaultBranch main ayarıyla belirleyebilirsiniz.

Bu konuyu videoyla öğrenin

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

Kursa git