Preskoči na vsebino

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, vrstice index ali /dev/null: obe strani sta označeni kot a/<path> in b/<path>, obseg bloka prazne strani pa je zapisan kot -1,0 ali +1,0, medtem ko git zapiše -0,0 ali +0,0.
  • Vrstica index se vedno konča z 100644, ne glede na način datoteke.
  • Spremembe samo načina (na primer chmod +x) ne ustvarijo rezultata.
  • Binarne datoteke izpišejo Binary files differ brez vrstice index, medtem ko git izpiše Binary files a/<path> and b/<path> differ.
  • Preimenovanja so prikazana kot en vnos diff --git a/<old> b/<new> z razliko v vsebini, brez vrstic similarity index, rename from ali rename to.

Operacije z razlikami

Nepripravljene spremembe (delovno drevo proti indeksu)

PHP
$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)

PHP
$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

PHP
$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

PHP
$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

PHP
$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.

PHP
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

PHP
echo $diff->format();

Ustvari poenoten izpis razlik. Pri spremenjeni besedilni datoteki se ujema z git diff:

Koda
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

PHP
if ($diff->hasChanges()) {
    // File was modified (or is binary with changes)
}

Struktura bloka

Vsak Hunk predstavlja neprekinjen odsek sprememb z vrsticami konteksta.

PHP
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.

PHP
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.

PHP
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.

PHP
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.

PHP
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).

PHP
if (MyersDiff::isBinary($content)) {
    // Binary file, skip line-level diff
}

Binarne datoteke ustvarijo DiffResult z $binary = true in praznim poljem $hunks. Oblikovani izpis je:

Koda
diff --git a/image.png b/image.png
Binary files differ

Barvni izpis

CLI za izpis v terminal uporablja ColorDiff z barvami ANSI.

PHP
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.

PHP
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.

PHP
use Pitmaster\Diff\WordDiff;

$result = WordDiff::diff('the quick fox', 'the slow fox');
// 'the [-quick-]{+slow+} fox'