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:
- Dal ucunu taşı. Her kipte yapılır.
- Hazırlık alanını hedefe eşitle.
--softdışında yapılır. - Çalışma dizinini hedefe eşitle. Yalnızca
--hardile 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 restoreyol üzerinde çalışır; tarihçeye dokunmaz.git resetbaş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.
--softiçeriği hazırlık alanında,--mixedçalışma dizininde bırakır;--hardher 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.