· kaynak dev.to (home feed)
Bağımsız test, Git 2.56 history-drop komutunu rebase'in 6 katı hızlı buldu, 40-77 katı değil
Git 2.56'nın deneysel history-drop komutu bağımsız bir testte rebase'ten 6 kat hızlı çıktı; ilk benchmark'taki 40-77 katı değil — çünkü komut iki makinede de aynı sürede tamamlanırken rebase'in temel süreleri farklı.

28 Eylül'de yayımlanan Git 2.56, kendisinden türeyen her şeyi yeniden oynatarak geçmişten bir commit'i silen yeni bir deneysel komutla geliyor: git history drop. Alex Georgiev'in 13 Kasım'da yayımladığı bir benchmark, komutu eşdeğer bir git rebase --onto işleminden 40 ila 77 kat daha hızlı bulmuştu. Bir gün sonra dev.to'da bir yazar, Git 2.56'yı kaynaktan derleyip aynı testi tekrarladı ve 6 katlık bir hızlanma ölçtü — ve bu iki sayı arasındaki fark, hikâyenin en faydalı kısmı.
Ne ölçüldü
dev.to yazarı, sonuçların yan yana konabilmesi için Georgiev'in yöntemini birebir kopyaladı. Her test taze bir repository oluşturuyor: bir kök commit, silinecek bir hedef commit, ardından her biri paylaşılan bir dosyaya ve kendine ait bir dosyaya dokunan bir dizi türeyen commit — böylece yeniden oynatma gerçek diff işi içeriyor. Repository iki kez bare olarak klonlanıyor ki her iki yaklaşım da bayt bayt aynı geçmişle başlasın.
Eski yol, bare repository'ye bağlı bir worktree ekleyip hedef commit'i atlamak için git rebase --onto çalıştırıyor. Yeni yol ise git history drop komutunu doğrudan bare repository üzerinde, hiç worktree olmadan çalıştırıyor. Her boyut üç kez çalıştırıldı ve her çalışmadan sonra ana dalın tree hash'i iki yöntem arasında karşılaştırıldı. Dokuz karşıştırmanın tamamı eşleşti; yani yeniden yazma her iki yolla da özdeş sonuçlar üretti.
Sayılar yan yana
| Commit | Rebase (Georgiev) | Drop (Georgiev) | Hızlanma | Rebase (dev.to) | Drop (dev.to) | Hızlanma |
|---|---|---|---|---|---|---|
| 20 | 1.418s | 0.035s | 40.7x | 0.193s | 0.034s | 5.6x |
| 100 | 7.121s | 0.092s | 77.5x | 0.810s | 0.139s | 5.8x |
| 400 | 26.525s | 0.362s | 73.2x | 2.258s | 0.325s | 6.9x |
Önce drop sütunlarına bakın: 400 commit için iki farklı makinede 0.362s ve 0.325s. Rebase'in temel süresi ise kabaca on kat farklı — 26.5 saniye karşı 2.3. Büyüklüklere yansıyan oran, rebase'in belirli bir makinede tesadüfen ne kadar yavaş olduğunu ölçüyor; komutun sabit bir özelliğini değil. dev.to yazarı, Georgiev'in kurulumunu göremediğini ve daha yavaş temel süreyi disk, dosya sistemi mi yoksa arka plan yükünün mü açıkladığı konusunda tahmin yürütmeyi reddediyor.
Neden daha hızlı
Georgiev'in kendi çözümlemesine göre, başta şüphelendiği worktree kurulumu, kabaca 25 saniyelik bir çalışmanın yalnızca 26 milisaniyesini oluşturuyor. Sürenin çoğu, rebase'in commit'leri tek tek cherry-pick etmesine ve her birinden sonra index ile working tree'yi güncellemesine gidiyor — oysa kimsin bu ara durumları incelediği yok. git history drop working tree'ye hiç dokunmuyor; doğrudan altta yatan nesneler üzerinde çalışıyor. Bu mekanizma her iki makinede de geçerliydi. Rebase'in zaten hızlı olduğu yerde 6 katlık, olmadığı yerde kabaca 70 katlık kazanç sağlıyor.
Hız dışındaki davranış
Georgiev, dev.to yazarının aktardığı ama yeniden test etmediği iki davranışsal farkı da doğruladı. Tek bir history drop, atılan commit'ten türeyen tüm dalları güncelliyor; düz bir rebase ise yalnızca geçerli dalı yeniden yazıyor. Ayrıca komut hook çalıştırmıyor: rebase altında anında tetiklenen bir post-rewrite hook, drop sırasında hiç tetiklenmedi. Man sayfası hook'ların "şu anki noktada" çalıştırılmadığını belirtiyor; bu da bir garantiye değil, bunun değişebileceğine dair bir uyarı gibi okunuyor.
Hatalar da temiz. Kök commit'in veya bir merge commit'in atılması net bir hatayla anında başarısız oluyor ve yeniden oynatma sırasında çakışma yaratacak bir drop, hep ya da hiç şeklinde başarısız oluyor — yarım kalmış bir durum yok, çakışma işaretleri yok, temizlenecek bir şey yok. Aynı çakışmayla karşılaşan interaktif bir rebase, kirli bir working tree ile dizinin ortasında duruyor. Man sayfası bunu, geçmiş yeniden yazmalarının durumlü işlemler olması amaçlanmadığı gerekçesiyle bir tasarım sınırlaması olarak nitelendiriyor.
Geçmeden önce uyarılar
Man sayfası komutun tamamını deneysel olarak işaretliyor: "THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE." Komutun dört alt komutu var — drop, fixup, reword ve split — ve burada yalnızca drop test edildi. Git 2.56 dağıtım repository'lerine henüz ulaşmadı; yani denemek kaynaktan derlemek demek. dev.to yazarının derlemesi, eksik libcurl başlık dosyalarını ve Rust araç zincirini atlamak için NO_CURL=1 ve NO_RUST=1 bayraklarına ihtiyaç duydu; bu yerel testler için sorun değil ama HTTP konuşamayan bir ikili dosya üretiyor. Rust, Git 3.0'a kadar Git'in derlemesinde isteğe bağlı kalıyor ve history komutunun kendisi düz C.
Neden önemli
Komutun hedeflediği iş için — bare bir repository'den commit atmak, paylaşılan repo'larda ya da uzun ömürlü entegrasyon dallarında yapılan türden bir temizlik — mutlak sayılar belirleyici: 400 türeyen commit'i yeniden oynatmak yaklaşık saniyenin üçte biri sürüyor, tree hash'ler özdeş, atılacak klon ya da worktree dansı yok ve tüm türeyen dallar tek geçişte güncelleniyor. Benchmark dersi de önemli: bir hızlanma oranı, temel aldığı ölçüm kadar güvenilirdir ve bunun boyutunu tahmin etmenin sağlam yolu, kendi repository'nizde rebase süresini ölçmektir. Yeni komutu betiklerine dahil etmek isteyen herkes önce hook bağımlılıklarını kontrol etmeli, çünkü post-rewrite hook'ları sessizce tetiklenmemeye başlıyor.
- #git
- #version-control
- #benchmarks
- #developer-tools
- #open-source