Pereiti prie turinio

Skirtumas

Pitmaster apskaičiuoja git vieninguoju formatu pateikiamus skirtumus. Skirtumų modulis palaiko kelis algoritmus, vieningąjį formatavimą, dvejetainių failų aptikimą ir rekursinį palyginimą medžių lygmeniu.

Pakeistam tekstiniam failui, kurio režimas 100644, format() sukuria tuos pačius baitus kaip git diff. Kiti atvejai šiuo metu formatuojami kitaip (#3):

  • Nauji ir ištrinti failai neturi new file mode / deleted file mode eilutės, index eilutės ir /dev/null: abi pusės žymimos a/<path> ir b/<path>, o tuščios pusės hunk intervalas užrašomas kaip -1,0 arba +1,0, kai git užrašo -0,0 arba +0,0.
  • index eilutė visada baigiasi 100644, nepriklausomai nuo failo režimo.
  • Vien režimo pakeitimai (pavyzdžiui, chmod +x) nesukuria rezultato.
  • Dvejetainiai failai pateikia Binary files differ be index eilutės, o git pateikia Binary files a/<path> and b/<path> differ.
  • Pervadinimai rodomi kaip vienas diff --git a/<old> b/<new> įrašas su turinio skirtumu, be similarity index, rename from ar rename to eilučių.

Skirtumų operacijos

Nepatvirtinti pakeitimai (darbinis medis ir indeksas)

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

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

Palygina kiekvieną indekso failą su jo dabartine būsena darbiniame medyje. Aptinka pakeitimus, ištrynimus ir dvejetainius failus.

Paruošti pakeitimai (indeksas ir HEAD)

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

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

Palygina dabartinį indeksą su HEAD įrašo medžiu. Parodo, kas bus įtraukta į kitą įrašą. Ištrinti ir pridėti failai su panašiu turiniu pateikiami kaip vienas pervadintas įrašas. Prieš pirmąjį įrašą HEAD nėra, todėl rezultatas tuščias (#5).

Šiuo metu pervadinimų poravimas taip pat susieja nesusijusius vienos eilutės failus, nes pabaigos tuščia eilutė laikoma bendru turiniu (#4).

Medžių palyginimas

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

Rekursyviai palygina du medžius. Perduokite medžių ID: įrašų ID nepaverčiami jų medžiais, todėl gaunamas tuščias rezultatas. Tą patį TreeDiff modulį naudoja diffStaged(), show() ir logPath().

Filtruoti pagal kelią

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

Kelio specifikacija yra tikslus failo kelias. diffStaged() priima tą patį argumentą, bet šiuo metu jo nepaiso, todėl visada grąžina visus paruoštus failus (#5).

Pasirinkti algoritmą

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

Galiojantys pavadinimai: myers (numatytasis), patience, histogram ir minimal. Bet kuris kitas pavadinimas sukelia InvalidArgumentException.

DiffResult struktūra

Kiekvienas DiffResult atspindi vieno failo skirtumą.

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

Suformatuota išvestis

PHP
echo $diff->format();

Sukuria vieningąją skirtumų išvestį. Pakeistam tekstiniam failui ji atitinka git diff:

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

Tikrinti, ar yra pakeitimų

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

Hunk struktūra

Kiekvienas Hunk atspindi gretimą pakeitimų sritį su konteksto eilutėmis.

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

Skirtumų algoritmai

Pitmaster įgyvendina keturis skirtumų algoritmus. Numatytasis yra Myers.

Myers skirtumas

Standartinis O(ND) algoritmas, toks pat kaip numatytasis git algoritmas. Sukuria minimalius redagavimo scenarijus.

PHP
use Pitmaster\Diff\MyersDiff;

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

diff() metodas priima dvi eilutes ir grąžina Hunk objektų masyvą. Įvestį jis suskaido pagal naujas eilutes, apskaičiuoja trumpiausią redagavimo scenarijų ir sugrupuoja pakeitimus į hunk blokus su 3 konteksto eilutėmis (kaip numatyta git).

Kantrybės skirtumas

Sukuria geresnius struktūrinius kodo skirtumus. Pirmiausia sulygina unikalias eilutes, tada užpildo tarpus tarp jų.

PHP
use Pitmaster\Diff\PatienceDiff;

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

Histogramos skirtumas

Kantrybės skirtumo variantas, geriau apdorojantis pasikartojančias eilutes. Naudoja JGit ir Eclipse.

PHP
use Pitmaster\Diff\HistogramDiff;

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

Minimalus skirtumas

Sukuria mažiausią įmanomą skirtumą (su mažiausiai pakeistų eilučių), tačiau skaičiavimas užtrunka ilgiau.

PHP
use Pitmaster\Diff\MinimalDiff;

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

Dvejetainių failų aptikimas

Pitmaster turinį laiko dvejetainiu, jei tarp pirmųjų 8192 baitų yra NUL baitas (git tikrina pirmuosius 8000).

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

Dvejetainiai failai sukuria DiffResult su $binary = true ir tuščiu $hunks masyvu. Suformatuota išvestis:

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

Spalvota išvestis

CLI terminalo išvestyje naudoja ColorDiff ANSI spalvas.

PHP
use Pitmaster\Diff\ColorDiff;

$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
  • Pridėtos eilutės (+) rodomos žaliai
  • Pašalintos eilutės (-) rodomos raudonai
  • Hunk antraštės (@@) rodomos žydrai
  • Failų antraštės (diff --git, index, ---, +++) rodomos paryškintai

pitmaster diff visada nuspalvina išvestį, net kai ji perduodama per dujotiekį. pitmaster show nuspalvina tik tada, kai stdout yra terminalas.

Medžių skirtumas (vidinis)

TreeDiff klasė rekursyviai palygina du medžio objektus ir sukuria po DiffResult kiekvienam pakeistam failui.

PHP
use Pitmaster\Diff\TreeDiff;

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

Medžių skirtumo apdorojimas:

  • Pridėti failai (yra tik naujame medyje)
  • Ištrinti failai (yra tik sename medyje)
  • Pakeisti failai (tas pats kelias, skiriasi blob maiša)
  • Rekursinis poaplankių palyginimas
  • Ištrintų ir pridėtų failų poravimas pervadinimams (tiksli maiša arba bent 50% bendrų eilučių)

Įrašai, kurių maiša nepasikeitė, praleidžiami, todėl vien režimo pakeitimas rezultato nesukuria.

Žodžių skirtumas

Skirta eilučių viduje esantiems žodžių lygmens pakeitimams.

PHP
use Pitmaster\Diff\WordDiff;

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