Preskočiť na obsah

Rozdiely

Pitmaster vypočítava rozdiely vo formáte unified git. Nástroj na výpočet rozdielov podporuje viacero algoritmov, formátovanie unified diff, detekciu binárnych súborov a rekurzívne porovnávanie na úrovni stromov.

Pri upravenom textovom súbore s režimom 100644 vytvára format() rovnaké bajty ako git diff. Ostatné prípady sa momentálne formátujú odlišne (#3):

  • Nové a odstránené súbory nemajú riadok new file mode / deleted file mode, riadok index ani /dev/null: obe strany sú označené ako a/<path> a b/<path> a rozsah bloku prázdnej strany sa zapisuje ako -1,0 alebo +1,0, zatiaľ čo git zapisuje -0,0 alebo +0,0.
  • Riadok index vždy končí na 100644 bez ohľadu na režim súboru.
  • Zmeny iba režimu (napríklad chmod +x) nevytvárajú žiadny výsledok.
  • Binárne súbory vypíšu Binary files differ bez riadku index, zatiaľ čo git vypíše Binary files a/<path> and b/<path> differ.
  • Premenovania sa zobrazujú ako jedna položka diff --git a/<old> b/<new> s rozdielom v obsahu, bez riadkov similarity index, rename from ani rename to.

Operácie s rozdielmi

Nepripravené zmeny (pracovný strom vs. index)

PHP
$diffs = $repo->diff();

foreach ($diffs as $diff) {
    echo $diff->format();
}

Porovná každý súbor v indexe s jeho aktuálnym stavom v pracovnom strome. Zisťuje úpravy, odstránenia a binárne súbory.

Pripravené zmeny (index vs. HEAD)

PHP
$diffs = $repo->diffStaged();

foreach ($diffs as $diff) {
    echo $diff->format();
}

Porovnáva aktuálny index so stromom commitu HEAD. Zobrazuje, čo sa zahrnie do nasledujúceho commitu. Odstránené a pridané súbory s podobným obsahom sa vykážu ako jedna premenovaná položka. Pred prvým commitom HEAD neexistuje a výsledok je prázdny (#5).

Párovanie premenovaní momentálne rozpozná aj nesúvisiace jednoradkové súbory, pretože koncový prázdny riadok sa počíta ako zdieľaný obsah (#4).

Rozdiel medzi stromami

PHP
$a = $repo->readObject($repo->resolve('HEAD~1')->hex)->tree;
$b = $repo->head()->tree;
$diffs = $repo->diffTree($a, $b);

Rekurzívne porovnáva dva stromy. Zadajte ID stromov: ID commitov sa neprevádzajú na ich stromy a výsledkom je prázdny výstup. Rovnaký nástroj TreeDiff používa aj diffStaged(), show() a logPath().

Filtrovanie podľa cesty

PHP
$diffs = $repo->diff('src/specific-file.php');

Špecifikácia cesty predstavuje presnú cestu k súboru. diffStaged() prijíma rovnaký argument, ale momentálne ho ignoruje, takže vždy vráti všetky pripravené súbory (#5).

Výber algoritmu

PHP
$diffs = $repo->diff(null, 'patience');
$diffs = $repo->diffStaged(null, 'histogram');
$diffs = $repo->diffTree($a, $b, 'minimal');

Platné názvy sú myers (predvolený), patience, histogram a minimal. Každý iný názov vyvolá InvalidArgumentException.

Štruktúra DiffResult

Každý DiffResult predstavuje rozdiely pre jeden súbor.

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'
        }
    }
}

Formátovaný výstup

PHP
echo $diff->format();

Vytvorí výstup unified diff. Pri upravenom textovom súbore zodpovedá git diff:

Kód
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()
     {

Kontrola zmien

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

Štruktúra bloku

Každý Hunk predstavuje súvislú oblasť zmien s kontextovými riadkami.

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 @@"

Algoritmy na výpočet rozdielov

Pitmaster implementuje štyri algoritmy na výpočet rozdielov. Predvolený je Myers.

Rozdiely Myers

Štandardný algoritmus O(ND), rovnaký ako predvolený algoritmus v git. Vytvára minimálne skripty úprav.

PHP
use Pitmaster\Diff\MyersDiff;

$hunks = MyersDiff::diff($oldContent, $newContent);

Metóda diff() prijíma dva reťazce a vracia pole objektov Hunk. Rozdelí vstup podľa nových riadkov, vypočíta najkratší skript úprav a zoskupí zmeny do blokov s 3 kontextovými riadkami (zhoduje sa s predvoleným nastavením v git).

Rozdiely Patience

Vytvára štrukturálne prehľadnejšie rozdiely v kóde. Najprv spáruje jedinečné riadky a potom doplní zvyšok medzi nimi.

PHP
use Pitmaster\Diff\PatienceDiff;

$hunks = PatienceDiff::diff($oldContent, $newContent);

Rozdiely Histogram

Variant rozdielov Patience, ktorý lepšie spracúva opakované riadky. Používajú ho JGit a Eclipse.

PHP
use Pitmaster\Diff\HistogramDiff;

$hunks = HistogramDiff::diff($oldContent, $newContent);

Minimálne rozdiely

Vytvára čo najmenšie rozdiely (s najmenším počtom zmenených riadkov) za cenu dlhšieho výpočtu.

PHP
use Pitmaster\Diff\MinimalDiff;

$hunks = MinimalDiff::diff($oldContent, $newContent);

Rozpoznávanie binárnych súborov

Pitmaster považuje obsah za binárny, ak obsahuje bajt NUL v prvých 8192 bajtoch (git kontroluje prvých 8000).

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

Binárne súbory vytvoria DiffResult s $binary = true a prázdnym poľom $hunks. Formátovaný výstup:

Kód
diff --git a/image.png b/image.png
Binary files differ

Farebný výstup

CLI používa ColorDiff na výstup v termináli s farbami ANSI.

PHP
use Pitmaster\Diff\ColorDiff;

$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
  • Pridané riadky (+) sa zobrazujú zelenou farbou
  • Odstránené riadky (-) sa zobrazujú červenou farbou
  • Hlavičky blokov (@@) sa zobrazujú azúrovou farbou
  • Hlavičky súborov (diff --git, index, ---, +++) sa zobrazujú tučným písmom

pitmaster diff vždy pridáva farby, aj keď je jeho výstup presmerovaný do rúry. pitmaster show pridáva farby, iba keď je stdout terminál.

Rozdiely stromov (interné)

Trieda TreeDiff rekurzívne porovnáva dva objekty stromu a vytvára DiffResult pre každý zmenený súbor.

PHP
use Pitmaster\Diff\TreeDiff;

$treeDiff = new TreeDiff($repo->objectDatabase());
$diffs = $treeDiff->diff($oldTreeId, $newTreeId);

Rozdiely stromov spracúvajú:

  • Pridané súbory (iba v novom strome)
  • Odstránené súbory (iba v starom strome)
  • Upravené súbory (rovnaká cesta, iný hash objektu blob)
  • Rekurzívne porovnávanie podadresárov
  • Párovanie premenovaných súborov medzi odstránenými a pridanými súbormi (presná zhoda hashov alebo aspoň 50 % spoločných riadkov)

Položky s nezmeneným hashom sa preskočia, takže samotná zmena režimu nevytvorí výsledok.

Rozdiely slov

Na zmeny jednotlivých slov priamo v riadkoch.

PHP
use Pitmaster\Diff\WordDiff;

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