Pāriet uz saturu

Atšķirības

Pitmaster aprēķina atšķirības git vienotajā formātā. Atšķirību dzinējs atbalsta vairākus algoritmus, vienoto atšķirību formatējumu, bināro failu noteikšanu un rekursīvu salīdzināšanu koku līmenī.

Modificētam teksta failam ar režīmu 100644 format() ģenerē tos pašus baitus, ko git diff. Pašlaik citi gadījumi tiek formatēti atšķirīgi (#3):

  • Jauniem un dzēstiem failiem nav new file mode / deleted file mode rindas, index rindas un /dev/null: abas puses ir marķētas ar a/<path> un b/<path>, bet tukšās puses bloka diapazons tiek norādīts kā -1,0 vai +1,0, kamēr git norāda -0,0 vai +0,0.
  • index rinda vienmēr beidzas ar 100644 neatkarīgi no faila režīma.
  • Režīma izmaiņas vien nerada rezultātu (piemēram, chmod +x).
  • Binārajos failos tiek izvadīts Binary files differ bez index rindas, kamēr git izvada Binary files a/<path> and b/<path> differ.
  • Pārdēvēšana tiek attēlota kā viens diff --git a/<old> b/<new> ieraksts ar satura atšķirībām, bez similarity index, rename from vai rename to rindām.

Atšķirību darbības

Nepievienotās izmaiņas (darba koks pret indeksu)

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

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

Salīdzina katru indeksā esošo failu ar tā pašreizējo stāvokli darba kokā. Nosaka izmaiņas, dzēstos failus un bināros failus.

Pievienotās izmaiņas (indekss pret HEAD)

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

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

Salīdzina pašreizējo indeksu ar HEAD komita koku. Parāda, kas tiks iekļauts nākamajā commit. Dzēsti un pievienoti faili ar līdzīgu saturu tiek uzrādīti kā viens pārdēvēts ieraksts. Pirms pirmā commit HEAD nav, un rezultāts ir tukšs (#5).

Pārdēvēšanas sasaistīšana pašlaik atbilst arī nesaistītiem vienas rindas failiem, jo beigu tukšā rinda tiek skaitīta kā kopīgs saturs (#4).

Koku salīdzinājums

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

Rekursīvi salīdzina divus kokus. Nododiet koku ID: komitu ID netiek pārveidoti par to kokiem, tāpēc rezultāts ir tukšs. Tas pats TreeDiff dzinējs darbina diffStaged(), show() un logPath().

Filtrēšana pēc ceļa

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

Ceļa specifikācija ir viens precīzs faila ceļš. diffStaged() pieņem to pašu argumentu, bet pašlaik to ignorē, tāpēc vienmēr atgriež visus pievienotos failus (#5).

Algoritma izvēle

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

Derīgie nosaukumi ir myers (noklusējuma), patience, histogram un minimal. Jebkurš cits nosaukums izraisa InvalidArgumentException.

DiffResult struktūra

Katrs DiffResult attēlo viena faila atšķirības.

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

Formatēta izvade

PHP
echo $diff->format();

Ģenerē vienotā formāta atšķirību izvadi. Modificētam teksta failam tā atbilst git diff:

Kods
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()
     {

Izmaiņu pārbaude

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

Bloka struktūra

Katrs Hunk attēlo nepārtrauktu izmaiņu apgabalu ar konteksta rindām.

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

Atšķirību algoritmi

Pitmaster īsteno četrus atšķirību algoritmus. Noklusējuma algoritms ir Myers.

Myers atšķirības

Standarta O(ND) algoritms, tāds pats kā git noklusējuma algoritms. Ģenerē minimālus rediģēšanas skriptus.

PHP
use Pitmaster\Diff\MyersDiff;

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

Metode diff() pieņem divas virknes un atgriež Hunk objektu masīvu. Tā sadala ievadi pēc jaunajām rindām, aprēķina īsāko rediģēšanas skriptu un grupē izmaiņas blokos ar 3 konteksta rindām (kā git noklusējuma iestatījumā).

Pacietīgās atšķirības

Strukturāli labākas koda atšķirības. Vispirms salīdzina unikālās rindas, pēc tam aizpilda atstarpes starp tām.

PHP
use Pitmaster\Diff\PatienceDiff;

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

Histogrammas atšķirības

Pacietīgo atšķirību variants, kas labāk apstrādā atkārtotas rindas. To izmanto JGit un Eclipse.

PHP
use Pitmaster\Diff\HistogramDiff;

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

Minimālās atšķirības

Ģenerē pēc iespējas mazāku atšķirību izvadi (ar vismazāk mainītajām rindām), taču prasa vairāk aprēķinu.

PHP
use Pitmaster\Diff\MinimalDiff;

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

Bināro failu noteikšana

Pitmaster uzskata saturu par bināru, ja tā pirmajos 8192 baitos ir NUL baits (git pārbauda pirmos 8000).

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

Binārie faili veido DiffResult ar $binary = true un tukšu $hunks masīvu. Formatētā izvade ir šāda:

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

Krāsaina izvade

CLI izmanto ColorDiff termināļa izvadei ar ANSI krāsām.

PHP
use Pitmaster\Diff\ColorDiff;

$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
  • Pievienotās rindas (+) tiek rādītas zaļā krāsā
  • Noņemtās rindas (-) tiek rādītas sarkanā krāsā
  • Bloku virsraksti (@@) tiek rādīti ciāna krāsā
  • Failu virsraksti (diff --git, index, ---, +++) tiek rādīti treknrakstā

pitmaster diff vienmēr iekrāso izvadi, arī tad, ja tā tiek novirzīta uz citu procesu. pitmaster show iekrāso izvadi tikai tad, ja stdout ir terminālis.

Koku atšķirības (iekšēji)

Klase TreeDiff rekursīvi salīdzina divus koka objektus un katram mainītajam failam izveido DiffResult.

PHP
use Pitmaster\Diff\TreeDiff;

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

Koku atšķirību apstrāde:

  • Pievienoti faili (ir tikai jaunajā kokā)
  • Dzēsti faili (ir tikai vecajā kokā)
  • Modificēti faili (tas pats ceļš, atšķirīga blob jaucējvērtība)
  • Rekursīva apakšdirektoriju salīdzināšana
  • Pārdēvēšanas sasaistīšana starp dzēstiem un pievienotiem failiem (precīza jaucējvērtības sakritība vai vismaz 50% kopīgu rindu)

Ieraksti ar nemainīgu jaucējvērtību tiek izlaisti, tāpēc režīma maiņa vien rezultātu nerada.

Vārdu atšķirības

Iekļautām vārdu līmeņa izmaiņām rindās.

PHP
use Pitmaster\Diff\WordDiff;

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