İki dosyayı karşılaştırın
Özel ve güvenli
Her şey tarayıcınızda gerçekleşir. Dosyalarınız sunucularımıza asla dokunmaz.
Çok hızlı
Yükleme yok, bekleme yok. Bir dosyayı bıraktığınız anda dönüştürün.
Gerçekten ücretsiz
Hesap gerekmez. Gizli maliyet yok. Dosya boyutu hilesi yok.
“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.
Bir “fark” aslında nedir
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.
LCS'den Myers'a: farklılıklar nasıl hesaplanır
Ç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ı.
“Optimal” okunabilir olmadığında: sabır ve histogram stratejileri
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.
Kelime düzeyinde netlik, boşluk kontrolü ve taşınan kod vurgulama
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.
Birleştirmelerin hizmetindeki farklar: iki yönlü ve üç yönlü ve diff3
Bir 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.
Yeniden adlandırma algılama ve eşikleri
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.
İkili ve delta farkları: rsync, VCDIFF/xdelta, bsdiff
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.
Kaynak kodunun ötesinde metin farkları: bulanık eşleştirme ve yama
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.
Yapılandırılmış veri farkları: tablolar ve ağaçlar
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.
Pratik Git fark ayarı: bir incelemecinin kontrol listesi
- Doğru algoritmayı seçin: Myers (varsayılan) ile başlayın, yeniden sıralamalar veya gürültülü bloklar çıktıyı karıştırırsa
--patience'ı deneyin veya tekrarlayan metinlerde hızlı, okunabilir farklar için--histogram'