Razlike
Pitmaster izračuna razlike v poenoteni obliki git. Pogon za izračun razlik podpira več algoritmov, oblikovanje poenotenih razlik, zaznavanje binarnih datotek in rekurzivno primerjavo na ravni dreves.
Za spremenjeno besedilno datoteko z načinom 100644 ustvari format() enake bajte kot git diff. Drugi primeri so trenutno oblikovani drugače (#3):
- Nove in izbrisane datoteke nimajo vrstice
new file mode/deleted file mode, vrsticeindexali/dev/null: obe strani sta označeni kota/<path>inb/<path>, obseg bloka prazne strani pa je zapisan kot-1,0ali+1,0, medtem ko git zapiše-0,0ali+0,0. - Vrstica
indexse vedno konča z100644, ne glede na način datoteke. - Spremembe samo načina (na primer
chmod +x) ne ustvarijo rezultata. - Binarne datoteke izpišejo
Binary files differbrez vrsticeindex, medtem ko git izpišeBinary files a/<path> and b/<path> differ. - Preimenovanja so prikazana kot en vnos
diff --git a/<old> b/<new>z razliko v vsebini, brez vrsticsimilarity index,rename fromalirename to.
Operacije z razlikami
Nepripravljene spremembe (delovno drevo proti indeksu)
$diffs = $repo->diff();
foreach ($diffs as $diff) {
echo $diff->format();
}
Primerja vsako datoteko v indeksu z njenim trenutnim stanjem v delovnem drevesu. Zazna spremembe, izbrise in binarne datoteke.
Pripravljene spremembe (indeks proti HEAD)
$diffs = $repo->diffStaged();
foreach ($diffs as $diff) {
echo $diff->format();
}
Primerja trenutni indeks z drevesom potrditve HEAD. Prikaže, kaj bo vključeno v naslednjo potrditev. Izbrisane in dodane datoteke s podobno vsebino se prikažejo kot en preimenovani vnos. Pred prvo potrditvijo HEAD ne obstaja, zato je rezultat prazen (#5).
Povezovanje preimenovanj trenutno poveže tudi nepovezane enovrstične datoteke, saj se zaključna prazna vrstica šteje kot skupna vsebina (#4).
Primerjava dreves
$a = $repo->readObject($repo->resolve('HEAD~1')->hex)->tree;
$b = $repo->head()->tree;
$diffs = $repo->diffTree($a, $b);
Rekurzivno primerja dve drevesi. Podajte ID-je dreves: ID-ji potrditev se ne pretvorijo v njihova drevesa, zato je rezultat prazen. Isti pogon TreeDiff poganja diffStaged(), show() in logPath().
Filtriranje po poti
$diffs = $repo->diff('src/specific-file.php');
Specifikacija poti je ena natančna pot do datoteke. diffStaged() sprejme isti argument, vendar ga trenutno prezre, zato vedno vrne vse pripravljene datoteke (#5).
Izbira algoritma
$diffs = $repo->diff(null, 'patience');
$diffs = $repo->diffStaged(null, 'histogram');
$diffs = $repo->diffTree($a, $b, 'minimal');
Veljavna imena so myers (privzeto), patience, histogram in minimal. Vsako drugo ime sproži InvalidArgumentException.
Struktura DiffResult
Vsak DiffResult predstavlja razliko za eno datoteko.
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'
}
}
}
Oblikovani izpis
echo $diff->format();
Ustvari poenoten izpis razlik. Pri spremenjeni besedilni datoteki se ujema z git diff:
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()
{
Preverjanje sprememb
if ($diff->hasChanges()) {
// File was modified (or is binary with changes)
}
Struktura bloka
Vsak Hunk predstavlja neprekinjen odsek sprememb z vrsticami konteksta.
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 @@"
Algoritmi za izračun razlik
Pitmaster izvaja štiri algoritme za izračun razlik. Privzeti je Myers.
Razlike po Myersu
Standardni algoritem O(ND), enak privzetemu algoritmu v git. Ustvari minimalne zapise urejanja.
use Pitmaster\Diff\MyersDiff;
$hunks = MyersDiff::diff($oldContent, $newContent);
Metoda diff() sprejme dva niza in vrne polje objektov Hunk. Vhod razdeli po novih vrsticah, izračuna najkrajši zapis urejanja in združi spremembe v bloke s 3 vrsticami konteksta (kot pri privzeti nastavitvi v git).
Razlike po metodi patience
Ustvari boljše strukturne razlike za kodo. Najprej poveže enolične vrstice, nato zapolni prostor med njimi.
use Pitmaster\Diff\PatienceDiff;
$hunks = PatienceDiff::diff($oldContent, $newContent);
Histogram razlik
Različica metode patience, ki bolje obravnava ponovljene vrstice. Uporabljata jo JGit in Eclipse.
use Pitmaster\Diff\HistogramDiff;
$hunks = HistogramDiff::diff($oldContent, $newContent);
Minimalne razlike
Ustvari najmanjšo možno razliko (z najmanj spremenjenimi vrsticami), a zahteva več računanja.
use Pitmaster\Diff\MinimalDiff;
$hunks = MinimalDiff::diff($oldContent, $newContent);
Zaznavanje binarnih datotek
Pitmaster obravnava vsebino kot binarno, če je v prvih 8192 bajtih bajt NUL (git preveri prvih 8000).
if (MyersDiff::isBinary($content)) {
// Binary file, skip line-level diff
}
Binarne datoteke ustvarijo DiffResult z $binary = true in praznim poljem $hunks. Oblikovani izpis je:
diff --git a/image.png b/image.png
Binary files differ
Barvni izpis
CLI za izpis v terminal uporablja ColorDiff z barvami ANSI.
use Pitmaster\Diff\ColorDiff;
$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
- Dodane vrstice (
+) so prikazane zeleno - Odstranjene vrstice (
-) so prikazane rdeče - Glave blokov (
@@) so prikazane cian - Glave datotek (
diff --git,index,---,+++) so prikazane krepko
pitmaster diff vedno uporablja barve, tudi ko je njegov izhod preusmerjen. pitmaster show uporablja barve samo, kadar je stdout terminal.
Primerjava dreves (notranje)
Razred TreeDiff rekurzivno primerja dva drevesna objekta in ustvari DiffResult za vsako spremenjeno datoteko.
use Pitmaster\Diff\TreeDiff;
$treeDiff = new TreeDiff($repo->objectDatabase());
$diffs = $treeDiff->diff($oldTreeId, $newTreeId);
Primerjava dreves obravnava:
- Dodane datoteke (prisotne samo v novem drevesu)
- Izbrisane datoteke (prisotne samo v starem drevesu)
- Spremenjene datoteke (ista pot, drugačna zgoščena vrednost vsebine)
- Rekurzivno primerjavo podimenikov
- Povezovanje preimenovanj med izbrisanimi in dodanimi datotekami (natančno ujemanje zgoščene vrednosti ali vsaj 50 % skupnih vrstic)
Vnosi z nespremenjeno zgoščeno vrednostjo so preskočeni, zato sprememba načina sama po sebi ne ustvari rezultata.
Razlike na ravni besed
Za spremembe posameznih besed znotraj vrstic.
use Pitmaster\Diff\WordDiff;
$result = WordDiff::diff('the quick fox', 'the slow fox');
// 'the [-quick-]{+slow+} fox'