“Farklılıklar” değişimin ortak dilidir. Bir şeyin iki versiyonu arasında neyin hareket ettiğini size anlatan kompakt anlatılardır — kaynak kodu, düzyazı, bir veri kümesi — her şeyi yeniden okumak zorunda bırakmadan. Bu birkaç sembolün (+, -, @@) arkasında, optimallik, hız ve insan anlayışını dengeleyen derin bir algoritma, sezgisel yöntem ve biçim yığını yaşar. Bu makale, farklılıkların pratik, algoritmalardan iş akışlarına bir turudur: nasıl hesaplandıkları, nasıl biçimlendirildikleri, birleştirme araçlarının onları nasıl kullandığı ve daha iyi incelemeler için nasıl ayarlanacağı. Yol boyunca, iddiaları birincil kaynaklara ve resmi belgelere dayandıracağız — çünkü boşlukların sayılıp sayılmadığı gibi küçük ayrıntılar gerçekten önemlidir.
Resmi olarak, bir fark, eklemeler ve silmeler kullanarak “eski” bir diziyi “yeni” bir diziye dönüştürmek için en kısa düzenleme betiğini (SES) tanımlar (ve bazen silme+ekleme olarak modellenebilen değiştirmeler). Pratikte, programcıya yönelik çoğu farksatır odaklıdır ve daha sonra okunabilirlik için isteğe bağlı olarak kelimelere veya karakterlere inceltilir. Kanonik çıktılar bağlam ve birleşik formatlarıdır; ikincisi — genellikle kod incelemesinde gördüğünüz — çıktıyı kısa bir başlık ve “hunk”larla sıkıştırır, her biri değişikliklerin etrafındaki bir bağlam mahallesini gösterir. Birleşik format-u/--unified aracılığıyla seçilir ve yama için fiili standarttır; patch genellikle bağlam satırlarından yararlanır değişiklikleri sağlam bir şekilde uygulamak için.
GNU diff kılavuzu, daha az gürültü ve daha fazla sinyal istediğinizde başvurduğunuz anahtarları kataloglar — boşlukları yoksaymak, hizalama için sekmeleri genişletmek veya daha yavaş olsa bile “minimal” bir düzenleme betiği istemek (seçenekler referansı). Bu seçenekler, iki dosyanın farklı olmasının ne anlama geldiğini değiştirmez; algoritmanın daha küçük betikleri ne kadar agresif aradığını ve sonucun insanlara nasıl sunulduğunu değiştirir.
Çoğu metin farkı, En Uzun Ortak Altdizi (LCS) soyutlamasına dayanır. Klasik dinamik programlama, LCS'yi O(mn) zaman ve uzayda çözer, ancak bu, büyük dosyalar için çok yavaş ve bellek yoğundur. Hirschberg'in algoritması , böl ve yönet kullanarak doğrusal uzayda (hala O(mn) zaman) optimal hizalamaların nasıl hesaplanacağını gösterdi, bu da pratik fark uygulamalarını etkileyen temel bir yerden tasarruf tekniğidir.
Hız ve kalite için atılım, Eugene W. Myers'ın 1986 tarihli algoritmasıydı, bu algoritma bir SES'i O(ND) zamanda (N ≈ toplam satır, D ≈ düzenleme mesafesi) ve neredeyse doğrusal uzayda bulur. Myers, düzenlemeleri bir “düzenleme grafiğinde” modeller veen uzağa ulaşan sınırlar boyunca ilerler, bu da satır farkı ayarında hem hızlı hem de minimale yakın sonuçlar verir. Bu yüzden “Myers” birçok araçta varsayılan olarak kalır.
Ayrıca, az sayıda pozisyon eşleştiğinde LCS'yi hızlandıran (eşleşmeleri önceden indeksleyerek ve artan altdizileri takip ederek) ve tarihsel olarak erken diff varyantlarıyla bağlantılı olan Hunt–Szymanski ailesi de vardır. Bu algoritmalar ödünleşimleri aydınlatır: seyrek eşleşmeli girdilerde, alt-kuadratik olarak çalışabilirler. Teori ve uygulamayı birleştiren bir uygulayıcı genel bakışı için, bkz. Neil Fraser'ın notları.
Myers minimal düzenleme betiklerini hedefler, ancak “minimal” ≠ “en okunabilir”. Yeniden sıralanmış veya kopyalanmış büyük bloklar, saf bir SES algoritmasını garip hizalamalara kandırabilir. Bram Cohen'e atfedilen sabır farkı'na girin: hizalamaları stabilize etmek için benzersiz, düşük frekanslı satırlara demir atar, genellikle insanların daha temiz bulduğu farklar üretir — özellikle taşınmış fonksiyonlar veya yeniden düzenlenmiş bloklar içeren kodda. Birçok araç bunu bir “sabır” seçeneği aracılığıyla sunar (örneğin,diff.algorithm).
Histogram farkı , düşük oluşumlu öğeleri daha iyi işlemek için bir frekans histogramı ile sabrı genişletirken hızlı kalır ( JGit'te popülerleştirilmiştir). Gürültülü dosyalar için --histogram'ın daha net hunklar ürettiğini hiç fark ettiyseniz, bu tasarım gereğidir. Modern Git'te, algoritmayı genel olarak veya çağrı başına seçebilirsiniz:git config diff.algorithm myers|patience|histogram veya git diff --patience.
Satır farkları özlüdür ancak küçük düzenlemeleri gizleyebilir. Kelime düzeyinde farklar (--word-diff), incelemeyi tüm satır eklemeleri/silmeleriyle boğmadan satır içi değişiklikleri renklendirir — düzyazı, uzun dizeler veya tek satırlıklar için harikadır.
Yeniden biçimlendirmeden sonra boşluklar farkları doldurabilir. Hem Git hem de GNU diff, boşluk değişikliklerini yoksaymanıza farklı derecelerde izin verir ve GNU diff'in boşluk seçenekleri (-b, -w, -B) bir biçimlendirici çalıştığında yardımcı olur; hizalama gürültüsü yerine mantıksal düzenlemeler görürsünüz.
Kod toptan taşındığında, Git taşınan blokları vurgulayabilir --color-moved ile, “taşınmış”ı “değiştirilmiş”ten görsel olarak ayırarak, bu da incelemecilerin bir taşımanın istenmeyen düzenlemeleri gizlemediğini denetlemesine yardımcı olur. diff.colorMovedaracılığıyla kalıcı hale getirin.
diff3Bir iki yönlü fark tam olarak iki versiyonu karşılaştırır; her iki tarafın da aynı temel satırı düzenleyip düzenlemediğini söyleyemez, bu yüzden genellikle aşırı çakışır. Üç yönlü birleştirme (modern VCS'ler tarafından kullanılır), her bir tarafa ortak bir atadan farkları hesaplar ve ardından iki değişiklik kümesini uzlaştırır. Bu, sahte çakışmaları önemli ölçüde azaltır ve daha iyi bağlam sağlar. Buradaki klasik algoritmik çekirdek, diff3'tür, bu da “O” (temel)den “A”ya ve “B”ye değişiklikleri birleştirir ve gerektiğinde çakışmaları işaretler.
Akademik ve endüstriyel çalışmalar, birleştirme doğruluğunu resmileştirmeye ve iyileştirmeye devam etmektedir; örneğin, doğrulanmış üç yönlü birleştirmeler, çakışma özgürlüğünün anlamsal nosyonlarını önerir. Günlük Git'te, modern ort birleştirme stratejisi , daha az sürprizle birleştirmeler üretmek için fark alma ve yeniden adlandırma algılamasına dayanır. Kullanıcılar için anahtar ipuçları şunlardır: çakışmalarda temel satırları merge.conflictStyle=diff3ile gösterin ve farkların küçük kalması için sık sık entegre edin.
Geleneksel farklar, içerik adresleme dosyaları blob olarak ele aldığı için yeniden adlandırmaları “göremez”; sadece bir silme ve bir ekleme görürler. Yeniden adlandırma algılama sezgiselleri , eklenen/kaldırılan çiftler arasındaki benzerliği karşılaştırarak bu boşluğu doldurur. Git'te, -M/--find-renames[=<n>] (varsayılan ~%50 benzerlik) aracılığıyla etkinleştirin veya ayarlayın. Daha gürültülü taşımalar için düşürün. aday karşılaştırmalarını sınırlayabilirsiniz diff.renameLimit ile (ve birleştirmeler sırasında merge.renameLimit ). Yeniden adlandırmalar arasında geçmişi takip etmek için, git log --follow -- <path>kullanın. Son Git ayrıca, birleştirmeler sırasında klasör taşımalarını yaymak için dizin yeniden adlandırma algılaması gerçekleştirir.
Değişen tek şey metin değildir. İkililer için genellikle delta kodlaması istersiniz — bir hedefin bir kaynaktan yeniden oluşturulması için kopyala/ekle talimatları yayınlayın. rsync algoritması , bant genişliğini en aza indirerek bir ağ üzerinden blokları hizalamak için yuvarlanan sağlama toplamları kullanarak verimli uzaktan fark alma konusunda öncülük etti.
IETF, ADD, COPY ve RUN'dan oluşan bir bayt kodunu tanımlayan genel bir delta formatı olan VCDIFF (RFC 3284)'yi standartlaştırdı, xdelta3 gibi uygulamalar bunu ikili yama için kullanır. Yürütülebilir dosyalardaki kompakt yamalar için, bsdiff genellikle sonek dizileri ve sıkıştırma yoluyla çok küçük deltalar üretir; yama boyutu baskın olduğunda ve üretim çevrimdışı gerçekleşebildiğinde onu seçin.
Eşzamanlı düzenlemeler veya biraz yanlış hizalanmış bağlamlar karşısında sağlam yamaya ihtiyacınız olduğunda — editörleri veya işbirlikçi sistemleri düşünün — diff-match-patch'i düşünün. Myers tarzı fark almayı Bitap bulanık eşleştirme ile birleştirerek yakın eşleşmeleri bulur ve yamaları “en iyi çaba” olarak uygular, ayrıca daha güzel bir insan çıktısı için biraz minimalizmden ödün veren ön-fark hızlandırmaları ve son-fark temizlemeleri. Sürekli senkronizasyon döngülerinde fark ve bulanık yamayı nasıl birleştireceğiniz hakkında, Fraser'ın Diferansiyel Senkronizasyon'una bakın.
CSV/TSV'deki satır farkları kırılgandır çünkü tek hücrelik bir değişiklik tüm satır düzenlemesi gibi görünebilir. Tabloya duyarlı fark araçları (daff) verileri satırlar/sütunlar olarak ele alır, belirli hücreleri hedefleyen yamalar yayınlar ve eklemeleri, silmeleri ve değişiklikleri açıkça gösteren görselleştirmeler oluşturur (bkz. R vinyeti). Hızlı kontroller için, özel CSV farkları hücre bazında değişiklikleri ve tür kaymalarını vurgulayabilir; algoritmik olarak egzotik değillerdir, ancak gerçekten önemsediğiniz yapıyı karşılaştırarak inceleme sinyalini artırırlar.
--patience 'ı deneyin veya tekrarlayan metinlerde hızlı, okunabilir farklar için --histogram 'ı deneyin. git config diff.algorithm …ile bir varsayılan ayarlayın.-b, -w, --ignore-blank-lines). Git dışında, bkz. GNU diff'in boşluk kontrolleri.--word-diff uzun satırlar ve düzyazı için yardımcı olur.--color-moved (veya diff.colorMoved) “taşınmış”ı “değiştirilmiş”ten ayırır.-M ekleyin veya benzerlik e şiğini ayarlayın (-M90%, -M30%); varsayılanın yaklaşık %50 olduğunu unutmayın. Derin ağaçlar için, diff.renameLimit'i ayarlayın.git log --follow -- <path>.Bir birleştirme iki fark hesaplar (BASE→BİZİM, BASE→ONLARIN) ve her ikisini de BASE'e uygulamaya çalışır. ort gibi stratejiler bunu ölçekte düzenler, yeniden adlandırma algılamasını (dizin ölçeğinde taşımalar dahil) ve çakışmaları en aza indirmek için sezgisel yöntemleri içerir. Çakışmalar olduğunda, --conflict=diff3 işaretçileri, niyeti anlamak için paha biçilmez olan temel bağlamla zenginleştirir. Pro Git'in Gelişmiş Birleştirme bölümü çözüm desenlerini anlatır ve Git'in belgeleri -X ours ve -X theirsgibi düğmeleri listeler. Tekrarlayan çakışmalarda zaman kazanmak için, çözümlerinizi kaydetmek ve yeniden oynatmak için rerere 'yi etkinleştirin.
Bir ağ üzerinden büyük varlıkları senkronize ediyorsanız, yerel diff'ten çok rsync dünyasına daha yakınsınız. Rsync, eşleşen blokları uzaktan keşfetmek için yuvarlanan sağlama toplamları hesaplar, sonra sadece gerekli olanı aktarır. Paketlenmiş deltalar için, VCDIFF/xdelta size standart bir bayt kodu ve olgun araçlar sunar; hem kodlayıcıyı hem de kod çözücüyü kontrol ettiğinizde onu seçin. Ve yama boyutu her şeyden önemliyse (örneğin, kablosuz aygıt yazılımı), bsdiff , çok küçük yamalar için derleme zamanında CPU/bellek takası yapar.
diff-match-patch gibi kütüphaneler, gerçek dünyada, yamaladığınız dosyanın kaymış olabileceğini kabul eder. Sağlam bir farkı (genellikle Myers) bulanık eşleştirme (Bitap) ve yapılandırılabilir temizleme kurallarıyla birleştirerek, bir yamayı uygulamak için doğru yeri bulabilir ve farkı daha okunaklı hale getirebilirler — işbirlikçi düzenleme ve senkronizasyon için kritik.
-u/-U<n>) kompakt ve yama dostudur; kod incelemesi ve CI'nin beklediği şey budur (referans).git diff belgeleri; GNU boşluk seçenekleri).diff3 stiliyle üç yönlü daha az kafa karıştırıcıdır; ort artı yeniden adlandırma algılama, çalkantıyı azaltır; rerere zaman kazandırır.Çünkü kas hafızası önemlidir:
# Ekstra bağlamla standart bir birleşik fark göster
git diff -U5
diff -u -U5 a b
# Uzun satırlar veya düzyazı için kelime düzeyinde netlik elde et
git diff --word-diff
# Yeniden biçimlendirmeden sonra boşluk gürültüsünü yoksay
git diff -b -w --ignore-blank-lines
diff -b -w -B a b
# İnceleme sırasında taşınan kodu vurgula
git diff --color-moved
git config --global diff.colorMoved default
# Yeniden adlandırma algılamasıyla yeniden düzenlemeleri evcilleştirin ve yeniden adlandırmalar arasında geçmişi takip edin
git diff -M
git log --follow -- <file>
# Okunabilirlik için algoritmayı tercih et
git diff --patience
git diff --histogram
git config --global diff.algorithm patience
# Çakışma işaretçilerinde temel satırları gör
git config --global merge.conflictStyle diff3Harika farklar, minimalizmi kanıtlamaktan çok, minimum bilişsel maliyetle incelemeci anlayışını en üst düzeye çıkarmakla ilgilidir. Bu yüzden ekosistem birden fazla algoritma (Myers, sabır, histogram), birden fazla sunum (birleşik, kelime farkı, renkli taşınma) ve alana duyarlı araçlar (tablolar için daff, ikililer için xdelta/bsdiff) geliştirdi. Ödünleşimleri öğrenin, düğmeleri ayarlayın ve kırmızı ve yeşil satırlardan bağlamı yeniden birleştirmek için daha az zaman harcayıp niyet hakkında akıl yürütmek için daha fazla zaman harcayacaksınız.
diff3 • boşluk seçenekleriBir diff, versiyon kontrol sistemlerinde kullanılan ve bir dosyanın iki versiyonu ya da hali arasındaki farkları vurgulamak için kullanılan bir araç veya işlevselliğidir. Genellikle, dosyada zaman içinde yapılan değişiklikleri veya güncellemeleri izlemek için kullanılır.
Bir diff, iki dosyayı satır satır karşılaştırır. İlk dosyadaki her bir satırı ikinci dosyadaki karşılığıyla tarar ve eşleştirir, eklemeleri, silmeleri veya değişiklikleri gibi önemli farklılıkları not alır.
Bir yama, diff arac ı tarafından üretilen iki dosya arasındaki farkları içeren bir dosyadır. 'Yama' komutuyla bir dosyanın versiyonuna uygulanabilir ve bu dosyayı daha yeni bir versiyona güncelleyebilir.
Birleşik diff’ler, bir dosyanın değişikliklerini metin dosyaları için uygun bir dosya formatında sunan bir diff dosya formatı türüdür. Orijinal dosyadan yapılan silmeler '-' ile, orijinal dosyaya yapılan eklemeler '+' ile başlar.
Diffler, versiyon kontrol sistemlerinde önemlidir çünkü ekiplerin bir dosyada zaman içinde yapılan değişiklikleri izlemelerini sağlarlar. Bu izleme, tutarlılığın korunmasını, işlerin çoğaltılmasını önlemenin, hataları ya da tutarsızlıkları belirlemenin ve birden çok dosya versiyonunu etkin bir şekilde yönetmenin kolaylaşmasına yardımcı olur.
Uzun Ortak Alt Dizi (LCS) algoritması, diff araçlarında sıklıkla kullanılan ve orijinal ve değiştirilmiş dosyalardaki karakterlerin en uzun sırasını bulmak için kullanılan bir metottur. Bu algoritma, iki dosya arasındaki ana benzerlikleri ve farklılıkları belirlemeye yardımcı olur.
En basit diff araçları genellikle sadece metin dosyalarını karşılaştırabilir. Ancak, farkları okunabilir bir formatda göstermek üzere tasarlanmış özel diff araçları, ikili dosyaları karşılaştırabilir.
En popüler diff araçlarından bazıları GNU diff, DiffMerge, KDiff3, WinMerge (Windows) ve FileMerge (Mac)’dir. Birçok Tümleşik Geliştirme Ortamı (IDE) da yerleşik diff yardımcı programlarına sahiptir.
Git’te, `git diff` komutunu kullanarak ve karşılaştırmak istediğiniz dosyaların iki versiyonunu izleyerek bir diff oluşturabilirsiniz. Çıktı, iki dosya arasındaki farkları gösterecektir.
Evet, birçok diff aracı, tek tek dosyaları karşılaştırmanın yanı sıra dizinleri de karşılaştırma yeteneğine sahiptir. Bu özellik, birden çok dosyayı içeren büyük bir projenin versiyonlarını karşılaştırırken özellikle yararlı olabilir.