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, riadokindexani/dev/null: obe strany sú označené akoa/<path>ab/<path>a rozsah bloku prázdnej strany sa zapisuje ako-1,0alebo+1,0, zatiaľ čo git zapisuje-0,0alebo+0,0. - Riadok
indexvždy končí na100644bez 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 differbez riadkuindex, zatiaľ čo git vypíšeBinary 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 riadkovsimilarity index,rename fromanirename to.
Operácie s rozdielmi
Nepripravené zmeny (pracovný strom vs. index)
$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)
$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
$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
$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
$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.
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
echo $diff->format();
Vytvorí výstup unified diff. Pri upravenom textovom súbore zodpovedá 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()
{
Kontrola zmien
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.
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.
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.
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.
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.
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).
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:
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.
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.
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.
use Pitmaster\Diff\WordDiff;
$result = WordDiff::diff('the quick fox', 'the slow fox');
// 'the [-quick-]{+slow+} fox'