Liigu sisu juurde

Erinevused

Pitmaster arvutab erinevused git-i ühtlustatud vormingus. Võrdlusmootor toetab mitut algoritmi, ühtlustatud erinevuste vormingut, binaarfailide tuvastamist ja rekursiivset puude võrdlust.

Muudetud tekstifaili puhul, mille režiim on 100644, toodab format() samad baidid nagu git diff. Muudel juhtudel vormindatakse tulemus praegu teisiti (#3):

  • Uutel ja kustutatud failidel puuduvad rida new file mode / deleted file mode, rida index ja /dev/null: mõlemad pooled on tähistatud kui a/<path> ja b/<path> ning tühja poole hunk'i vahemik esitatakse kujul -1,0 või +1,0, seal kus git kirjutab -0,0 või +0,0.
  • Rida index lõpeb alati märgiga 100644, olenemata failirežiimist.
  • Ainult režiimi muudatused (näiteks chmod +x) tulemust ei anna.
  • Binaarfailide puhul väljastatakse Binary files differ ilma reata index; git väljastab Binary files a/<path> and b/<path> differ.
  • Ümbernimetamised kuvatakse ühe diff --git a/<old> b/<new> kirjena koos sisu erinevustega, ilma ridadeta similarity index, rename from või rename to.

Erinevuste toimingud

Lavastamata muudatused (tööpuu vs indeks)

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

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

Võrdleb indeksi iga faili selle praeguse olekuga tööpuus. Tuvastab muudatused, kustutamised ja binaarfailid.

Lavastatud muudatused (indeks vs HEAD)

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

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

Võrdleb praegust indeksit HEAD-i sissekande puuga. Näitab, mis lisatakse järgmisse sissekandesse. Sarnase sisuga kustutatud ja lisatud failid esitatakse ühe ümbernimetatud kirjena. Enne esimest sissekannet HEAD puudub ja tulemus on tühi (#5).

Ümbernimetamiste paaride leidmine seostab praegu ka omavahel mitteseotud üherealisi faile, sest lõpus olev tühi rida loetakse ühiseks sisuks (#4).

Puudevahelised erinevused

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

Võrdleb rekursiivselt kahte puud. Edastage puude ID-d: sissekannete ID-sid nende puudeks ei lahutata ja need annavad tühja tulemuse. Sama TreeDiff mootor on aluseks toimingutele diffStaged(), show() ja logPath().

Tee järgi filtreerimine

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

Teemäärang on ühe täpse failitee jaoks. diffStaged() aktsepteerib sama argumenti, kuid eirab seda praegu, seega tagastab alati kõik lavastatud failid (#5).

Algoritmi valimine

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

Kehtivad nimed on myers (vaikimisi), patience, histogram ja minimal. Mis tahes muu nimi põhjustab vea InvalidArgumentException.

DiffResulti struktuur

Iga DiffResult tähistab ühe faili erinevusi.

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

Vormindatud väljund

PHP
echo $diff->format();

Loob ühtlustatud erinevuste väljundi. Muudetud tekstifaili korral vastab see git diff-le:

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

Muudatuste kontrollimine

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

Hunk'i struktuur

Iga Hunk tähistab muudatuste külgnevat lõiku koos kontekstiridadega.

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

Erinevuste algoritmid

Pitmaster rakendab nelja erinevuste algoritmi. Vaikimisi kasutatakse Myersit.

Myersi erinevuste algoritm

Standardne O(ND) algoritm, sama mis git-i vaikealgoritm. Loob minimaalsed muudatuste skriptid.

PHP
use Pitmaster\Diff\MyersDiff;

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

diff() meetod võtab kaks stringi ja tagastab hulga Hunk objekte. See jagab sisendi reavahetuste järgi, arvutab lühima muudatuste skripti ja koondab muudatused hunk'ideks, milles on 3 kontekstirida (git-i vaikeväärtus).

Patience'i erinevuste algoritm

Parem struktuursete erinevuste tuvastamine koodi puhul. Sobitab esmalt kordumatud read, seejärel leiab vasted nende vahele jäävatele ridadele.

PHP
use Pitmaster\Diff\PatienceDiff;

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

Histogrammi erinevuste algoritm

Patience'i erinevuste algoritmi variant, mis käsitleb korduvaid ridu paremini. Seda kasutavad JGit ja Eclipse.

PHP
use Pitmaster\Diff\HistogramDiff;

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

Minimaalsete erinevuste algoritm

Loob võimalikult väikese erinevuste väljundi (vähim arv muudetud ridu), kuid nõuab rohkem arvutustööd.

PHP
use Pitmaster\Diff\MinimalDiff;

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

Binaarfailide tuvastamine

Pitmaster käsitleb sisu binaarsena, kui selle esimese 8192 baidi seas leidub NUL-bait (git kontrollib esimest 8000 baiti).

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

Binaarfailide puhul luuakse DiffResult, millel on $binary = true ja tühi massiiv $hunks. Vormindatud väljund on järgmine:

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

Värviline väljund

CLI kasutab terminaliväljundi värvimiseks ColorDiff.

PHP
use Pitmaster\Diff\ColorDiff;

$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
  • Lisatud read (+) kuvatakse rohelisena
  • Eemaldatud read (-) kuvatakse punasena
  • Hunk'i päised (@@) kuvatakse tsüaanina
  • Failipäised (diff --git, index, ---, +++) kuvatakse paksus kirjas

pitmaster diff värvib väljundi alati, ka torusse suunamisel. pitmaster show värvib ainult siis, kui standardväljund on terminal.

Puude võrdlemine (sisemine)

Klass TreeDiff võrdleb rekursiivselt kahte puuobjekti ja loob iga muudetud faili kohta objekti DiffResult.

PHP
use Pitmaster\Diff\TreeDiff;

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

Puude võrdlemine käsitleb järgmist:

  • Lisatud failid (esinevad ainult uues puus)
  • Kustutatud failid (esinevad ainult vanas puus)
  • Muudetud failid (sama tee, erinev bloobi räsi)
  • Alamkataloogide rekursiivne võrdlemine
  • Ümbernimetamise sobitamine kustutatud ja lisatud failide vahel (täpne räsivaste või vähemalt 50% ühistest ridadest)

Muutumatu räsiga kirjed jäetakse vahele, seega ainult režiimi muutmine tulemust ei anna.

Sõnade võrdlus

Ridade sees toimuvate tekstisiseste sõnataseme muudatuste jaoks.

PHP
use Pitmaster\Diff\WordDiff;

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