Diff
Az Pitmaster a git egységes formátumában számítja ki a különbségeket. A diffmotor több algoritmust, egységes diffformázást, binárisfájl-felismerést és rekurzív, faszintű összehasonlítást támogat.
100644 módú módosított szövegfájl esetén az format() ugyanazokat a bájtokat állítja elő, mint az git diff. A többi eset formázása jelenleg eltér (#3):
- Az új és törölt fájlokban nincs
new file mode/deleted file modesor,indexsor és/dev/nullsem: mindkét oldal címkéjea/<path>ésb/<path>, az üres oldal hunk-tartománya pedig-1,0vagy+1,0alakban szerepel ott, ahol a git-0,0vagy+0,0formát használ. - Az
indexsor mindig100644végződik, a fájl módjától függetlenül. - A csak módot érintő módosítások (például
chmod +x) nem adnak eredményt. - A bináris fájlok
Binary files differformában jelennek megindexsor nélkül, míg a gitBinary files a/<path> and b/<path> differformát használ. - Az átnevezéseket egyetlen
diff --git a/<old> b/<new>bejegyzésként jeleníti meg tartalmi diffel,similarity index,rename fromésrename tosorok nélkül.
Diffműveletek
Nem előkészített módosítások (munkakönyvtár az indexhez képest)
$diffs = $repo->diff();
foreach ($diffs as $diff) {
echo $diff->format();
}
Az indexben lévő minden fájlt összehasonlít az aktuális munkakönyvtári állapotával. Felismeri a módosításokat, törléseket és bináris fájlokat.
Előkészített módosítások (index a HEAD-hez képest)
$diffs = $repo->diffStaged();
foreach ($diffs as $diff) {
echo $diff->format();
}
Az aktuális indexet összehasonlítja a HEAD commit fájafájával. Megmutatja, mi kerül bele a következő commitba. A hasonló tartalmú törölt és hozzáadott fájlokat egy átnevezett bejegyzésként jelenti. Az első commit előtt nincs HEAD, ezért az eredmény üres (#5).
Az átnevezések párosítása jelenleg egymástól független, egysoros fájlokat is összepárosít, mert a záró üres sort közös tartalomnak veszi (#4).
Fák összehasonlítása
$a = $repo->readObject($repo->resolve('HEAD~1')->hex)->tree;
$b = $repo->head()->tree;
$diffs = $repo->diffTree($a, $b);
Két fát hasonlít össze rekurzívan. Faazonosítókat adjon meg: a commitazonosítókat nem bontja fel fáikra, így üres eredményt adnak. Ugyanaz az TreeDiff motor szolgál az diffStaged(), az show() és az logPath() működésének alapjául.
Szűrés elérési út alapján
$diffs = $repo->diff('src/specific-file.php');
A pathspec egy pontos fájlelérési út. Az diffStaged() ugyanilyen argumentumot fogad, de jelenleg figyelmen kívül hagyja, ezért minden előkészített fájlt visszaad (#5).
Algoritmus kiválasztása
$diffs = $repo->diff(null, 'patience');
$diffs = $repo->diffStaged(null, 'histogram');
$diffs = $repo->diffTree($a, $b, 'minimal');
Érvényes nevek: myers (alapértelmezett), patience, histogram és minimal. Más név esetén InvalidArgumentException kivétel keletkezik.
A DiffResult felépítése
Minden DiffResult egyetlen fájl diffjét képviseli.
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'
}
}
}
Formázott kimenet
echo $diff->format();
Egységes formátumú diffkimenetet állít elő. Módosított szövegfájl esetén megegyezik az git diff eredményével:
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()
{
Változások ellenőrzése
if ($diff->hasChanges()) {
// File was modified (or is binary with changes)
}
Hunkok felépítése
Minden Hunk a módosítások összefüggő, kontextussorokat tartalmazó szakaszát jelenti.
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 @@"
Diffalgoritmusok
Az Pitmaster négy diffalgoritmust valósít meg. Az alapértelmezett a Myers-algoritmus.
Myers-féle diff
A szabványos O(ND) algoritmus, ugyanaz, mint a git alapértelmezettje. Minimális módosítási szkripteket állít elő.
use Pitmaster\Diff\MyersDiff;
$hunks = MyersDiff::diff($oldContent, $newContent);
Az diff() metódus két karakterláncot fogad, és Hunk objektumok tömbjét adja vissza. A bemenetet sortörések mentén részekre bontja, kiszámítja a legrövidebb módosítási szkriptet, majd a változásokat 3 kontextussort tartalmazó hunkokba csoportosítja (a git alapértelmezett működését követve).
Patience diff
Jobb szerkezetű diffet ad a kódhoz. Először az egyedi sorokat párosítja, majd kitölti a közöttük lévő részeket.
use Pitmaster\Diff\PatienceDiff;
$hunks = PatienceDiff::diff($oldContent, $newContent);
Hisztogram diff
A patience diff egyik változata, amely jobban kezeli az ismétlődő sorokat. Az JGit és az Eclipse használja.
use Pitmaster\Diff\HistogramDiff;
$hunks = HistogramDiff::diff($oldContent, $newContent);
Minimális diff
A lehető legkisebb diffet állítja elő (a lehető legkevesebb módosított sorral), több számítás árán.
use Pitmaster\Diff\MinimalDiff;
$hunks = MinimalDiff::diff($oldContent, $newContent);
Bináris fájlok felismerése
Az Pitmaster akkor kezeli binárisként a tartalmat, ha annak első 8192 bájtja között NUL bájt található (a git az első 8000 bájtot ellenőrzi).
if (MyersDiff::isBinary($content)) {
// Binary file, skip line-level diff
}
A bináris fájlok olyan DiffResult értéket adnak, amelyben az $binary = true szerepel, az $hunks tömb pedig üres. A formázott kimenet:
diff --git a/image.png b/image.png
Binary files differ
Színezett kimenet
Az CLI az ColorDiff használatával, ANSI-színekkel jeleníti meg a terminálkimenetet.
use Pitmaster\Diff\ColorDiff;
$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
- A hozzáadott sorok (
+) zölden jelennek meg - A törölt sorok (
-) pirosan jelennek meg - A hunkfejlécek (
@@) cián színűek - A fájlfejlécek (
diff --git,index,---,+++) félkövéren jelennek meg
pitmaster diff mindig színez, akkor is, ha a kimenete át van irányítva. pitmaster show csak akkor színez, ha a szabványos kimenet terminálra mutat.
Fák összehasonlítása (belső)
Az TreeDiff osztály rekurzívan hasonlít össze két faobjektumot, és minden módosult fájlhoz létrehoz egy DiffResult elemet.
use Pitmaster\Diff\TreeDiff;
$treeDiff = new TreeDiff($repo->objectDatabase());
$diffs = $treeDiff->diff($oldTreeId, $newTreeId);
A fák összehasonlítása a következőket kezeli:
- Hozzáadott fájlok (csak az új fában szerepelnek)
- Törölt fájlok (csak a régi fában szerepelnek)
- Módosított fájlok (azonos útvonal, eltérő blobhash)
- Alkönyvtárak rekurzív összehasonlítása
- Törölt és hozzáadott fájlok párosítása átnevezésként (azonos hash esetén, vagy ha a sorok legalább 50%-a közös)
A változatlan hashű bejegyzéseket kihagyja, ezért önmagában egy módváltozás nem eredményez kimenetet.
Szavak összehasonlítása
Sorokon belüli, szószintű változásokhoz.
use Pitmaster\Diff\WordDiff;
$result = WordDiff::diff('the quick fox', 'the slow fox');
// 'the [-quick-]{+slow+} fox'