Ders 13 / 15
Devirme
Bir işlemenin etkisini tersine çeviren yeni işleme; tarihçeyi bozmadan geri alma, ağaç kimliğiyle doğrulama, işlemeden devirme ve devirmenin devrilmesi.
Yayın Güncelleme
Bu derste
- Bir işlemenin etkisini tarihçeyi yeniden yazmadan geri alır
- Devirme işlemesinin ürettiği ağacın hangi işlemeyle örtüştüğünü doğrular
- Devirme ile sıfırlama arasında duruma göre seçim yapar
İçindekiler
Sıfırlama ve değiştirme, tarihçeyi yeniden yazarak çalışır; bu yüzden paylaşılmış işlemelerde kullanılamazlar. Paylaşılmış bir işleme hatalıysa geriye tek bir yol kalır: geçmişi olduğu gibi bırakıp, hatanın etkisini tersine çeviren yeni bir işleme yazmak. Bu işleme devirme (revert) denir.
Hata
Arama betiğinin çıktısı yalnızca Türkçe sütunla sınırlandırılmak istenir ve grep çıktısı bir
süzgeçten geçirilir. Betikteki koşul satırı sed ile düzenlenir:
sed -i.bak "s/terimler.txt; then/terimler.txt | cut -d '|' -f 1; then/" ara.sh rm ara.sh.bak
Düzenlemeden sonra koşul şu hâle gelir:
{/* run: skip */}
if ! grep -i -- "$1" terimler.txt | cut -d '|' -f 1; then echo "eşleşme yok: $1" >&2 exit 2 fi
Değişiklik, tarihleri sabitlenmiş bir işlemeyle kaydedilir. Tarih değişkenleri açık oturumda tanımlıdır; yeni bir terminal açtıysanız yeniden yazın:
export GIT_AUTHOR_DATE="2024-03-11 09:30:00 +0300" export GIT_COMMITTER_DATE="2024-03-11 09:30:00 +0300" git commit -a -m "Arama çıktısını yalnızca Türkçe sütuna indir"
[main d245350] Arama çıktısını yalnızca Türkçe sütuna indir 1 file changed, 1 insertion(+), 1 deletion(-)
Değişiklik istenen çıktıyı üretir ama gizli bir kusur taşır: kabuk, boru hattının çıkış
kodunu son komuttan alır. cut her durumda başarıyla sonlandığı için grep eşleşme
bulamadığında da koşul yanlış çıkar:
./ara.sh yokboyle echo "çıkış kodu: $?"
çıkış kodu: 0
Betik hiçbir eşleşme bildirimi yazmadı ve sıfır çıkış koduyla sonlandı; oysa eşleşme yoktur ve çıkış kodu 2 olmalıdır. Kusur, çıktının kendisinde değil hata bildirimindedir; bu nedenle gözden kaçmaya elverişlidir.
İşleme paylaşılmıştır ve tarihçeden düşürülemez.
Devirme
export GIT_AUTHOR_DATE="2024-03-11 10:12:00 +0300" export GIT_COMMITTER_DATE="2024-03-11 10:12:00 +0300" git revert --no-edit HEAD
[main c497738] Revert "Arama çıktısını yalnızca Türkçe sütuna indir" Date: Mon Mar 11 10:12:00 2024 +0300 1 file changed, 1 insertion(+), 1 deletion(-)
--no-edit, hazırlanan mesajı düzenleyici açmadan kabul eder. Betik yeniden doğru çalışır:
./ara.sh yokboyle
eşleşme yok: yokboyle
git log --oneline -n 4
c497738 Revert "Arama çıktısını yalnızca Türkçe sütuna indir" d245350 Arama çıktısını yalnızca Türkçe sütuna indir 377b1f8 README'ye kullanım bölümü ekle 0e74ba9 Öbek ve dizi terimlerini ekle
Hatalı işleme tarihçede duruyor. Yanına, etkisini tersine çeviren bir işleme eklendi.
Devirme İşlemesinin İçeriği
git show HEAD
commit c49773829409f26d221a2bb5b46a58d8ca2c8327 Author: Deniz Kaya <[email protected]> Date: Mon Mar 11 10:12:00 2024 +0300 Revert "Arama çıktısını yalnızca Türkçe sütuna indir" This reverts commit d2453504d3bed0b24e4bedfaac3c3b87c508b799. diff --git a/ara.sh b/ara.sh index 64b5b70..582ddde 100755 --- a/ara.sh +++ b/ara.sh @@ -6,7 +6,7 @@ if [ $# -ne 1 ]; then exit 1 fi -if ! grep -i -- "$1" terimler.txt | cut -d '|' -f 1; then +if ! grep -i -- "$1" terimler.txt; then echo "eşleşme yok: $1" >&2 exit 2 fi
Fark, devrilen işlemenin farkının tersidir: silinen satır eklenmiş, eklenen satır silinmiştir. Otomatik oluşturulan mesaj, devrilen işlemenin tam kimliğini gövdeye yazar; bu satır sayesinde bir devirmenin neyi geri aldığı tarihçeden okunabilir.
Sonucun Doğrulanması
Devirmenin gerçekten önceki duruma döndürüp döndürmediği, ağaç kimlikleri karşılaştırılarak kesin olarak sınanır:
git log --format='%h %T %s' -n 4
c497738 961039799e5ee6f157229351478a98abb7652c82 Revert "Arama çıktısını yalnızca Türkçe sütuna indir" d245350 0f2d862b8a585d8dfc9b1a0acbdb30a221233ade Arama çıktısını yalnızca Türkçe sütuna indir 377b1f8 961039799e5ee6f157229351478a98abb7652c82 README'ye kullanım bölümü ekle 0e74ba9 c6ec3cea3b8943f818cd8bb423c65f0cb5c553ea Öbek ve dizi terimlerini ekle
Devirme işlemesinin ağacı 9610397, hatalı işlemeden önceki 377b1f8 işlemesinin ağacıyla
aynıdır. İki farklı işleme aynı ağacı gösteriyor: proje içeriği bayt düzeyinde eski hâline
dönmüştür. İçerik adresli depolamanın verdiği bu eşitlik sınaması, farkları gözle karşılaştırmaya
gerek bırakmaz.
Devirme Neden Tarihçeyi Bozmaz
Devirme yalnızca ekleme yapar: var olan hiçbir nesneye dokunmaz, hiçbir kimliği değiştirmez. Tarihçeyi daha önce almış kopyalar, ellerindeki zinciri korur ve üzerine tek bir yeni işleme alır. Sıfırlamada ortaya çıkan uyumsuzluk burada oluşmaz.
Bedeli, hatanın tarihçede görünür kalmasıdır. Bu bir kusur değil, çoğu zaman istenen davranıştır: hatalı bir değişikliğin ne zaman girdiği, ne zaman ve neden geri alındığı kaydedilmiş olur.
İşlemeden Devirmek
Devirmenin sonucu doğrudan işlenmeden incelenebilir:
git revert -n HEAD~3 git status --short
M terimler.txt
git diff --staged
diff --git a/terimler.txt b/terimler.txt index a5350ef..17af3b8 100644 --- a/terimler.txt +++ b/terimler.txt @@ -5,5 +5,3 @@ ağaç | tree karma tablosu | hash table bağlı liste | linked list küme | set -öbek | heap -dizi | array
-n seçeneği değişikliği hazırlık alanına koyar ama işlemez. Bu, birden çok işlemeyi tek bir
devirme işlemesinde toplamak ya da sonucu işlemeden önce incelemek için kullanılır. İşlem
git revert --abort ile iptal edilebilir:
git revert --abort
Komut hazırlık alanını ve çalışma dizinini devirme başlamadan önceki hâline döndürür.
Örnekte devrilen işleme, tarihçenin en son işlemesi değildi. Devirme herhangi bir işlemeye uygulanabilir; hesaplanan şey, o işlemenin farkının tersinin şu anki içeriğe uygulanmasıdır. Aradan geçen işlemeler aynı satırlara dokunmuşsa uygulama başarısız olur ve çakışma bildirilir. Çakışma çözümü Dallanma ve İşbirliği kursunun konusudur.
Devirmenin Devrilmesi
Devirme de bir işlemedir; devrilebilir. Bu, geri alınan bir değişikliği yeniden uygulamanın yoludur:
export GIT_AUTHOR_DATE="2024-03-11 15:00:00 +0300" export GIT_COMMITTER_DATE="2024-03-11 15:00:00 +0300" git revert --no-edit HEAD
[main 5bba728] Reapply "Arama çıktısını yalnızca Türkçe sütuna indir" Date: Mon Mar 11 15:00:00 2024 +0300 1 file changed, 1 insertion(+), 1 deletion(-)
Mesaj bu kez Revert değil Reapply ile başlar: bir devirmenin devrilmesi, özünde yeniden
uygulamadır.
git log --format='%h %T %s' -n 4
5bba728 0f2d862b8a585d8dfc9b1a0acbdb30a221233ade Reapply "Arama çıktısını yalnızca Türkçe sütuna indir" c497738 961039799e5ee6f157229351478a98abb7652c82 Revert "Arama çıktısını yalnızca Türkçe sütuna indir" d245350 0f2d862b8a585d8dfc9b1a0acbdb30a221233ade Arama çıktısını yalnızca Türkçe sütuna indir 377b1f8 961039799e5ee6f157229351478a98abb7652c82 README'ye kullanım bölümü ekle
Dört işleme, iki ağaç arasında dönüşümlü gidip geliyor. Örnek deponun tarihçesinde bu son adım tutulmamıştır — kusurlu değişiklik yeniden uygulanmamış, devirme yerinde bırakılmıştır. Örnek depoyu o durumda tutmak için son işleme geri sarılır:
git reset --hard HEAD~1
HEAD is now at c497738 Revert "Arama çıktısını yalnızca Türkçe sütuna indir"
Devirme mi, Sıfırlama mı
| Ölçüt | Devirme | Sıfırlama |
|---|---|---|
| Tarihçe | Korunur, yeni işleme eklenir | Yeniden yazılır |
| Paylaşılmış işlemede | Uygundur | Uygun değildir |
| Hatanın görünürlüğü | Kayıtta kalır | Silinir |
| Uygulanabildiği işleme | Herhangi biri | Dal ucundan geriye doğru |
Ölçüt tektir: işleme paylaşılmışsa devirme, paylaşılmamışsa her ikisi de kullanılabilir.
Özet
- Devirme, bir işlemenin farkının tersini uygulayan yeni bir işleme oluşturur.
- Tarihçe korunur; hiçbir nesne değişmez, yalnızca yeni bir işleme eklenir.
- Devirme işlemesinin ağacı, devrilen işlemeden önceki ağaçla aynıdır; bu eşitlik doğrulama aracıdır.
-nseçeneği sonucu işlemeden hazırlık alanına koyar;--abortişlemi iptal eder.- Bir devirme de devrilebilir; sonuç, değişikliğin yeniden uygulanmasıdır.
Sonraki Adım
Buraya kadarki araçlar tamamlanmış değişikliklerle ilgiliydi. Peki yarım kalmış bir iş varken başka bir konuya geçmek gerekirse ne yapılır? İşlemek erken, geri almak ise kayıptır. Sonraki ders, yarım kalmış işi geçici olarak saklayan zulayı ve bu saklamanın nesne modelindeki karşılığını ele alacak.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.