Siirry sisältöön

Erot

Pitmaster laskee erot gitin yhtenäisessä muodossa. Eromoottori tukee useita algoritmeja, yhtenäistä eromuotoilua, binääritiedostojen tunnistusta ja rekursiivista puiden vertailua.

Muutetulle tekstitiedostolle, jonka tila on 100644, format() tuottaa samat tavut kuin git diff. Muut tapaukset muotoillaan tällä hetkellä eri tavoin (#3):

  • Uusilla ja poistetuilla tiedostoilla ei ole riviä new file mode / deleted file mode, riviä index eikä riviä /dev/null: molemmat puolet merkitään tunnisteilla a/<path> ja b/<path>, ja tyhjän puolen lohkoalueeksi kirjoitetaan -1,0 tai +1,0, kun git kirjoittaa -0,0 tai +0,0.
  • Rivi index päättyy aina merkkiin 100644 tiedoston tilasta riippumatta.
  • Pelkät tilamuutokset (esimerkiksi chmod +x) eivät tuota tulosta.
  • Binääritiedostoista tulostetaan Binary files differ ilman riviä index, kun git tulostaa Binary files a/<path> and b/<path> differ.
  • Uudelleennimeämiset näytetään yhtenä diff --git a/<old> b/<new>-merkintänä sisältöeroineen ilman rivejä similarity index, rename from tai rename to.

Erotoiminnot

Vaiheistamattomat muutokset (työhakemisto vs. indeksi)

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

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

Vertaa indeksin kutakin tiedostoa sen nykyiseen tilaan työhakemistossa. Tunnistaa muutokset, poistot ja binääritiedostot.

Vaiheistetut muutokset (indeksi vs. HEAD)

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

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

Vertaa nykyistä indeksiä HEAD-toimituksen puuhun. Näyttää, mitä seuraavaan toimitukseen sisällytetään. Samankaltaista sisältöä sisältävät poistetut ja lisätyt tiedostot ilmoitetaan yhtenä uudelleennimettynä merkintänä. Ennen ensimmäistä toimitusta HEADia ei ole, joten tulos on tyhjä (#5).

Uudelleennimeämisten parittaminen yhdistää tällä hetkellä myös toisiinsa liittymättömiä yksirivisiä tiedostoja, koska lopun tyhjä rivi lasketaan yhteiseksi sisällöksi (#4).

Puiden välinen ero

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

Vertaa kahta puuta rekursiivisesti. Anna puiden tunnisteet: toimitustunnisteitä ei pureta puiksi, joten tulos on tyhjä. Sama TreeDiff-moottori on myös toimintojen diffStaged(), show() ja logPath() taustalla.

Suodatus polun mukaan

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

Polkumäärite on yhden tiedoston tarkka polku. diffStaged() hyväksyy saman argumentin mutta ohittaa sen tällä hetkellä, joten se palauttaa aina kaikki vaiheistetut tiedostot (#5).

Algoritmin valinta

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

Kelvolliset nimet ovat myers (oletus), patience, histogram ja minimal. Mikä tahansa muu nimi aiheuttaa poikkeuksen InvalidArgumentException.

DiffResult-rakenne

Kukin DiffResult kuvaa yhden tiedoston eroa.

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

Muotoiltu tuloste

PHP
echo $diff->format();

Tuottaa yhtenäisen erotulosteen. Muutetun tekstitiedoston tulos vastaa git diff:

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

Muutosten tarkistus

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

Lohkon rakenne

Kukin Hunk kuvaa yhtenäistä muutosaluetta, jossa on asiayhteysrivejä.

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

Eroalgoritmit

Pitmaster toteuttaa neljä eroalgoritmia. Oletuksena käytetään Myersin algoritmia.

Myersin eroalgoritmi

Tavanomainen O(ND)-algoritmi, sama kuin gitin oletus. Tuottaa mahdollisimman lyhyet muokkaussarjat.

PHP
use Pitmaster\Diff\MyersDiff;

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

diff()-menetelmä ottaa kaksi merkkijonoa ja palauttaa joukon Hunk-olioita. Se jakaa syötteen rivinvaihtojen kohdalta, laskee lyhimmän muokkaussarjan ja ryhmittelee muutokset lohkoihin, joissa on kolme asiayhteysriviä (gitin oletuksen mukaisesti).

Patience-eroalgoritmi

Paremmat rakenteelliset erot koodille. Yhdistää ensin yksilölliset rivit ja täydentää sitten niiden välit.

PHP
use Pitmaster\Diff\PatienceDiff;

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

Histogrammieroalgoritmi

Patience-eroalgoritmin muunnelma, joka käsittelee toistuvat rivit paremmin. Käytössä toiminnoissa JGit ja Eclipse.

PHP
use Pitmaster\Diff\HistogramDiff;

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

Minimaalinen ero

Tuottaa mahdollisimman pienen eron (mahdollisimman vähän muutettuja rivejä), mutta vaatii enemmän laskentaa.

PHP
use Pitmaster\Diff\MinimalDiff;

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

Binääritiedostojen tunnistus

Pitmaster käsittelee sisältöä binäärisenä, jos ensimmäisten 8192 tavun joukossa on NUL-tavu (git tarkistaa ensimmäiset 8000 tavua).

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

Binääritiedostot tuottavat DiffResult-tuloksen, jossa on $binary = true ja tyhjä $hunks-taulukko. Muotoiltu tuloste on:

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

Värillinen tuloste

CLI käyttää ColorDiff-värejä päätetulosteessa.

PHP
use Pitmaster\Diff\ColorDiff;

$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
  • Lisätyt rivit (+) näytetään vihreinä
  • Poistetut rivit (-) näytetään punaisina
  • Lohkojen otsakkeet (@@) näytetään syaaneina
  • Tiedosto-otsakkeet (diff --git, index, ---, +++) näytetään lihavoituina

pitmaster diff lisää tulosteeseen aina värit, myös silloin kun tuloste ohjataan putkeen. pitmaster show lisää värit vain, kun vakiotuloste on pääte.

Puiden välinen ero (sisäinen)

TreeDiff-luokka vertaa kahta puuoliota rekursiivisesti ja tuottaa kullekin muutetulle tiedostolle DiffResult-olion.

PHP
use Pitmaster\Diff\TreeDiff;

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

Puiden välisten erojen käsittely kattaa seuraavat:

  • Lisätyt tiedostot (vain uudessa puussa)
  • Poistetut tiedostot (vain vanhassa puussa)
  • Muutetut tiedostot (sama polku, eri blob-tiiviste)
  • Alikansioiden rekursiivinen vertailu
  • Poistettujen ja lisättyjen tiedostojen yhdistäminen uudelleennimeämisiksi (täsmäävä tiiviste tai vähintään 50 % yhteisiä rivejä)

Merkinnät, joiden tiiviste ei ole muuttunut, ohitetaan, joten pelkkä tilan muutos ei tuota tulosta.

Sanojen välinen ero

Rivien sisäisten, sanakohtaisten muutosten tarkasteluun.

PHP
use Pitmaster\Diff\WordDiff;

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