Diff
Pitmaster, git'in birleşik biçiminde farkları hesaplar. Fark motoru birden fazla algoritmayı, birleşik diff biçimlendirmesini, ikili dosya algılamayı ve ağaç düzeyinde özyinelemeli karşılaştırmayı destekler.
100644 kipine sahip değiştirilmiş bir metin dosyası için format(), git diff ile aynı baytları üretir. Diğer durumlar şu anda farklı biçimlendirilir (#3):
- Yeni ve silinmiş dosyalarda
new file mode/deleted file modesatırı,indexsatırı ve/dev/nullbulunmaz: her iki taraf daa/<path>veb/<path>olarak etiketlenir; boş tarafın hunk aralığı, git'in-0,0veya+0,0yazdığı yerde-1,0ya da+1,0olarak yazılır. - Dosya kipi ne olursa olsun
indexsatırı daima100644ile biter. - Yalnızca kip değişiklikleri (örneğin
chmod +x) sonuç üretmez. - İkili dosyalar, git'in
Binary files a/<path> and b/<path> differyazdığı yerdeBinary files differbilgisiniindexsatırı olmadan yazdırır. - Yeniden adlandırmalar, içerik farkıyla birlikte tek bir
diff --git a/<old> b/<new>girdisi olarak gösterilir;similarity index,rename fromveyarename tosatırları bulunmaz.
Diff işlemleri
Hazırlanmamış değişiklikler (çalışma ağacı ile dizin karşılaştırması)
$diffs = $repo->diff();
foreach ($diffs as $diff) {
echo $diff->format();
}
Dizindeki her dosyayı çalışma ağacındaki mevcut durumuyla karşılaştırır. Değişiklikleri, silmeleri ve ikili dosyaları algılar.
Hazırlanmış değişiklikler (dizin ile HEAD karşılaştırması)
$diffs = $repo->diffStaged();
foreach ($diffs as $diff) {
echo $diff->format();
}
Geçerli dizini HEAD kaydının ağacıyla karşılaştırır. Bir sonraki kayda nelerin ekleneceğini gösterir. İçerikleri benzer olan silinmiş ve eklenmiş dosyalar, yeniden adlandırılmış tek bir girdi olarak bildirilir. İlk kayıttan önce HEAD yoktur ve sonuç boştur (#5).
Yeniden adlandırma eşleştirme işlemi şu anda ilgisiz tek satırlık dosyaları da eşleştiriyor; çünkü sondaki boş satır ortak içerik olarak sayılıyor (#4).
Ağaçtan ağaca diff
$a = $repo->readObject($repo->resolve('HEAD~1')->hex)->tree;
$b = $repo->head()->tree;
$diffs = $repo->diffTree($a, $b);
İki ağacı özyinelemeli olarak karşılaştırır. Ağaç kimlikleri verin: kayıt kimlikleri ağaçlarına dönüştürülmez ve boş sonuç verir. Aynı TreeDiff motoru diffStaged(), show() ve logPath() işlemlerini destekler.
Yola göre filtreleme
$diffs = $repo->diff('src/specific-file.php');
Yol belirtimi, tek bir tam dosya yoludur. diffStaged() aynı bağımsız değişkeni kabul eder ancak şimdilik yok sayar; bu nedenle hazırlanmış tüm dosyaları döndürür (#5).
Algoritma seçme
$diffs = $repo->diff(null, 'patience');
$diffs = $repo->diffStaged(null, 'histogram');
$diffs = $repo->diffTree($a, $b, 'minimal');
Geçerli adlar myers (varsayılan), patience, histogram ve minimal şeklindedir. Diğer adlar InvalidArgumentException fırlatır.
DiffResult yapısı
Her DiffResult, tek bir dosyanın diff'ini temsil eder.
use Pitmaster\Diff\DiffResult;
foreach ($diffs as $diff) {
echo $diff->oldPath; // Path in the old tree
echo $diff->newPath; // Path in the new tree
echo $diff->binary; // true for binary files
echo $diff->oldHash; // Hex hash of the old blob (null for added files)
echo $diff->newHash; // Hex hash of the new blob (null for deleted files)
foreach ($diff->hunks as $hunk) {
echo $hunk->header(); // @@ -1,5 +1,7 @@
foreach ($hunk->lines as $line) {
echo $line . "\n"; // ' context', '+added', '-removed'
}
}
}
Biçimlendirilmiş çıktı
echo $diff->format();
Birleşik diff çıktısı üretir. Değiştirilmiş bir metin dosyasında git diff ile eşleşir:
diff --git a/src/File.php b/src/File.php
index abc1234..def5678 100644
--- a/src/File.php
+++ b/src/File.php
@@ -10,6 +10,8 @@ class File
private string $name;
+ private int $count;
+
public function __construct()
{
Değişiklikleri denetleme
if ($diff->hasChanges()) {
// File was modified (or is binary with changes)
}
Hunk yapısı
Her Hunk, bağlam satırlarıyla birlikte bitişik bir değişiklik bölgesini temsil eder.
use Pitmaster\Diff\Hunk;
$hunk->oldStart; // Starting line in old file
$hunk->oldCount; // Number of lines from old file
$hunk->newStart; // Starting line in new file
$hunk->newCount; // Number of lines in new file
$hunk->lines; // Array of diff lines (prefixed with ' ', '+', or '-')
$hunk->header(); // "@@ -10,6 +10,8 @@"
Diff algoritmaları
Pitmaster dört diff algoritması uygular. Varsayılan algoritma Myers'tır.
Myers diff
Standart O(ND) algoritmasıdır ve git'in varsayılanıyla aynıdır. En küçük düzenleme betiklerini üretir.
use Pitmaster\Diff\MyersDiff;
$hunks = MyersDiff::diff($oldContent, $newContent);
diff() yöntemi iki dize alır ve bir Hunk nesne dizisi döndürür. Girdiyi yeni satırlara göre böler, en kısa düzenleme betiğini hesaplar ve değişiklikleri 3 bağlam satırlı hunk'lar halinde gruplandırır (git varsayılanıyla eşleşir).
Patience diff
Kod için yapısal olarak daha iyi farklar sunar. Önce benzersiz satırları eşleştirir, ardından aradaki bölümleri doldurur.
use Pitmaster\Diff\PatienceDiff;
$hunks = PatienceDiff::diff($oldContent, $newContent);
Histogram diff
Tekrarlanan satırları daha iyi işleyen bir patience diff çeşididir. JGit ve Eclipse tarafından kullanılır.
use Pitmaster\Diff\HistogramDiff;
$hunks = HistogramDiff::diff($oldContent, $newContent);
Minimal diff
Daha fazla hesaplama gerektirmesi karşılığında mümkün olan en küçük diff'i (en az değişen satırı) üretir.
use Pitmaster\Diff\MinimalDiff;
$hunks = MinimalDiff::diff($oldContent, $newContent);
İkili dosya algılama
Pitmaster, ilk 8192 bayt içinde NUL baytı varsa içeriği ikili veri olarak değerlendirir (git ilk 8000 baytı denetler).
if (MyersDiff::isBinary($content)) {
// Binary file, skip line-level diff
}
İkili dosyalar, $binary = true ve boş bir $hunks dizisi içeren bir DiffResult üretir. Biçimlendirilmiş çıktı şöyledir:
diff --git a/image.png b/image.png
Binary files differ
Renkli çıktı
CLI, ANSI renkleriyle terminal çıktısı için ColorDiff kullanır.
use Pitmaster\Diff\ColorDiff;
$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
- Eklenen satırlar (
+) yeşil gösterilir - Kaldırılan satırlar (
-) kırmızı gösterilir - Hunk başlıkları (
@@) camgöbeği gösterilir - Dosya başlıkları (
diff --git,index,---,+++) kalın gösterilir
pitmaster diff, çıktısı bir kanala yönlendirildiğinde bile her zaman renklendirir. pitmaster show yalnızca standart çıktı bir terminal olduğunda renklendirir.
Ağaç diff'i (dahili)
TreeDiff sınıfı iki ağaç nesnesini özyinelemeli olarak karşılaştırır ve değiştirilen her dosya için bir DiffResult üretir.
use Pitmaster\Diff\TreeDiff;
$treeDiff = new TreeDiff($repo->objectDatabase());
$diffs = $treeDiff->diff($oldTreeId, $newTreeId);
Ağaç diff'i şunları işler:
- Eklenen dosyalar (yalnızca yeni ağaçta bulunur)
- Silinen dosyalar (yalnızca eski ağaçta bulunur)
- Değiştirilen dosyalar (aynı yol, farklı blob özeti)
- Alt dizinlerin özyinelemeli karşılaştırması
- Silinen ve eklenen dosyalar arasında yeniden adlandırma eşleştirmesi (tam özet eşleşmesi veya en az %50 ortak satır)
Özeti değişmeyen girdiler atlanır; bu nedenle yalnızca kip değişikliği sonuç üretmez.
Sözcük diff'i
Satır içindeki sözcük düzeyindeki değişiklikler için.
use Pitmaster\Diff\WordDiff;
$result = WordDiff::diff('the quick fox', 'the slow fox');
// 'the [-quick-]{+slow+} fox'