İçeriğe geç
academia.sh

Ders 12 / 15

Sıfırlama Kipleri

Dal ucunun geriye taşınması; `--soft`, `--mixed` ve `--hard` kiplerinin üç bölgeye etkisi, kaybolan içerik ve başvuru günlüğüyle kurtarma.

İçindekiler

Değiştirme, dal ucunu aynı öncüle bağlanan yeni bir işlemeye taşıyordu. Sıfırlama (reset), dal ucunu tarihçede daha geriye taşır: bir ya da daha çok işleme, dalın erişilebilir geçmişinden düşer. Sıfırlamanın üç kipi vardır ve aralarındaki fark, hangi bölgelerin etkilendiğidir.

Bu ders üç kipi aynı hata üzerinde tek tek uygular.

Hata

Terim listesi abecesel sıralanmak istenir ve genel amaçlı bir sıralama aracına verilir. Sonuç:

ağaç | tree
bağlı liste | linked list
dizi | array
karma tablosu | hash table
kuyruk | queue
küme | set
yığıt | stack
çizge | graph
öbek | heap

Sıra yanlıştır. “çizge” ve “öbek” listenin sonuna düşmüş, “küme” ise “kuyruk”tan sonra gelmiştir. Nedeni, sıralamanın Türkçe abeceye göre değil bayt değerlerine göre yapılmasıdır: Bilgisayarlar Nasıl Çalışır kursunda görüldüğü gibi, ASCII aralığı dışındaki harfler UTF-8’de birden çok baytla kodlanır ve ilk baytları tüm ASCII harflerinden büyüktür. Doğru sıra, dile duyarlı bir karşılaştırma düzeni gerektirir.

Hata fark edilmeden işlenir:

git commit -m "Terim listesini abecesel sırala"
[main d85a348] Terim listesini abecesel sırala
 1 file changed, 5 insertions(+), 5 deletions(-)

Sıfırlama Ne Yapar

Sıfırlama üç adımdan oluşur ve kip, adımların kaçının uygulanacağını belirler:

  1. Dal ucunu taşı. Her kipte yapılır.
  2. Hazırlık alanını hedefe eşitle. --soft dışında yapılır.
  3. Çalışma dizinini hedefe eşitle. Yalnızca --hard ile yapılır.

Birinci adım tarihçeye, ikinci ve üçüncü adımlar içeriğe dokunur.

--soft

git reset --soft HEAD~1
git log --oneline -n 1
18600c5 README'ye kullanım bölümü ekle

İşleme tarihçeden düştü. İçeriğe ne oldu?

git status --short
M  terimler.txt

Değişiklik hazırlık alanında duruyor. Yalnızca birinci adım uygulandı: dal ucu geriye taşındı, hazırlık alanı ve çalışma dizini olduğu gibi bırakıldı. Sonuç, “işleme hiç yazılmamış ama içerik işlenmeye hazır” durumudur.

git diff --staged --stat
 terimler.txt | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Bu kip, son işlemenin kapsamını yeniden düzenlemek için kullanılır: işleme geri alınır, içerik istenen biçimde bölünür ve yeniden işlenir.

--mixed

İşleme yeniden yazılıp bu kez varsayılan kiple sıfırlanır:

git reset HEAD~1
Unstaged changes after reset:
M	terimler.txt
git status --short
 M terimler.txt

İşaret ikinci sütuna geçti: içerik artık hazırlık alanında değil, yalnızca çalışma dizininde. Birinci ve ikinci adım uygulandı. --mixed yazılmasa da varsayılan kip budur.

Bu kip, hem işlemeyi hem de hazırlık alanındaki seçimi geri alır; hangi dosyaların birlikte işleneceğine baştan karar vermek istendiğinde kullanılır.

--hard

git reset --hard HEAD~1
HEAD is now at 18600c5 README'ye kullanım bölümü ekle
git status --short

Çıktı boştur. Terim listesi de eski hâline dönmüştür: sıralama tümüyle geri alınmıştır. Üç adım da uygulandı.

Bu kip yıkıcıdır ve iki ayrı içeriği götürür: sıfırlanan işlemelerin içeriğini ve o sırada çalışma dizininde bulunan, işlenmemiş bütün düzenlemeleri. Birincisi başvuru günlüğünden geri getirilebilir; ikincisi getirilemez. git reset --hard çalıştırmadan önce git status çıktısına bakmak, bu ikinci kaybı önlemenin tek yoludur.

Üç Kipin Karşılaştırması

Kip Dal ucu Hazırlık alanı Çalışma dizini Değişiklik nerede kalır
--soft Taşınır Dokunulmaz Dokunulmaz Hazırlık alanında
--mixed Taşınır Eşitlenir Dokunulmaz Çalışma dizininde
--hard Taşınır Eşitlenir Eşitlenir Hiçbir yerde

Tablo tek bir cümleye indirgenebilir: kip sertleştikçe geri alma daha derine iner. Seçim, işlemenin içeriğinin korunup korunmayacağına göre yapılır.

Kurtarma

Sıfırlanan işleme nesne veritabanında durur ve başvuru günlüğünden bulunabilir:

git reflog -n 6
18600c5 HEAD@{0}: reset: moving to HEAD~1
d85a348 HEAD@{1}: commit: Terim listesini abecesel sırala
18600c5 HEAD@{2}: reset: moving to HEAD~1
d85a348 HEAD@{3}: commit: Terim listesini abecesel sırala
18600c5 HEAD@{4}: reset: moving to HEAD~1
d85a348 HEAD@{5}: commit: Terim listesini abecesel sırala

Günlük, üç kipin denendiği sırayı olduğu gibi kaydetmiştir. İşleme kimliğinin her seferinde d85a348 çıkması rastlantı değildir: içerik, mesaj, yazar ve tarih aynı olduğu sürece kimlik de aynıdır. İçerik adresli depolamanın doğrudan sonucudur.

Dal ucu istenen kimliğe geri taşınır:

git reset --hard d85a348
HEAD is now at d85a348 Terim listesini abecesel sırala

İşleme tarihçeye döndü. Bu örnekte sıralama gerçekten yanlış olduğu için son karar onu düşürmektir:

git reset --hard HEAD~1
HEAD is now at 18600c5 README'ye kullanım bölümü ekle

Yol Verilen Biçim

git reset komutuna bir yol verildiğinde davranış tümüyle değişir: dal ucu taşınmaz, yalnızca o yolun hazırlık alanındaki kaydı hedefteki hâline döndürülür.

git add terimler.txt
git status --short
M  terimler.txt
git reset terimler.txt
Unstaged changes after reset:
M	terimler.txt
git status --short
 M terimler.txt

Bu, önceki derste git restore --staged ile yapılan işin eski yazımıdır. Aynı komut adının yol verildiğinde ve verilmediğinde farklı işler yapması, git restore komutunun neden ayrı adlandırıldığını açıklar.

ORIG_HEAD

Sıfırlama, dal ucunu taşımadan önce eski değeri ORIG_HEAD adlı bir dosyaya yazar:

cat .git/ORIG_HEAD
2aff8c57391d20c90c05be4eb3f9a385fd140cf2

Bu ad bir başvuru gibi kullanılabilir; yanlışlıkla yapılan bir sıfırlamayı geri almanın en kısa yolu, başvuru günlüğünü okumadan ORIG_HEAD hedefine dönmektir:

git reset --hard ORIG_HEAD

Dosya yalnızca son işlemi kaydeder; art arda yapılan sıfırlamalarda üzerine yazılır. Daha geriye gitmek için başvuru günlüğü gerekir.

Sıfırlama ile Dosya Geri Yükleme Farkı

İki komut karıştırılır çünkü ikisi de “geri alma” olarak adlandırılır. Ayrım nettir:

  • git restore yol üzerinde çalışır; tarihçeye dokunmaz.
  • git reset başvuru üzerinde çalışır; dal ucunu taşır.

Bir dosyayı eski hâline döndürmek istiyorsanız git restore, bir işlemeyi tarihçeden düşürmek istiyorsanız git reset kullanılır.

Sıfırlamanın kendisi de paylaşılmış tarihçede sorunludur: dal ucunu geriye taşımak, o işlemeleri almış kopyalarla uyumsuzluk yaratır. Önceki dersteki kural burada da geçerlidir — paylaşılmış tarihçe geriye alınmaz.

Özet

  • Sıfırlama dal ucunu taşır; kip, hazırlık alanı ile çalışma dizininin de eşitlenip eşitlenmeyeceğini belirler.
  • --soft içeriği hazırlık alanında, --mixed çalışma dizininde bırakır; --hard her ikisini de hedefe eşitler.
  • --hard, işlenmemiş düzenlemeleri geri getirilemez biçimde siler.
  • Sıfırlanan işlemeler nesne veritabanında kalır; başvuru günlüğünden bulunup geri getirilebilir.
  • Aynı içerik, mesaj, yazar ve tarih her zaman aynı işleme kimliğini üretir.

Sonraki Adım

Sıfırlama ve değiştirme, tarihçeyi yeniden yazarak çalışıyor ve bu nedenle paylaşılmış işlemelerde kullanılamıyor. Peki paylaşılmış bir işleme hatalıysa ne yapılır? Sonraki ders, tarihçeyi bozmadan bir işlemenin etkisini tersine çeviren aracı — devirmeyi — ele alacak.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat