Diff
Pitmaster beregner forskelle i gits samlede format. Diff-motoren understøtter flere algoritmer, formatering af samlede forskelle, registrering af binære filer og rekursiv sammenligning på træniveau.
For en ændret tekstfil med tilstanden 100644 producerer format() de samme bytes som git diff. Andre tilfælde formateres i øjeblikket anderledes (#3):
- Nye og slettede filer har ingen
new file mode/deleted file mode-linje, ingenindex-linje og intet/dev/null: begge sider mærkesa/<path>ogb/<path>, og den tomme sides hunk-interval skrives som-1,0eller+1,0, hvor git skriver-0,0eller+0,0. index-linjen slutter altid med100644, uanset filtilstanden.- Ændringer kun af tilstanden (f.eks.
chmod +x) giver intet resultat. - Binære filer viser
Binary files differuden enindex-linje, hvor git viserBinary files a/<path> and b/<path> differ. - Omdøbninger vises som én
diff --git a/<old> b/<new>-post med en indholdsdiff uden linjernesimilarity index,rename fromellerrename to.
Diff-handlinger
Ikke-indekserede ændringer (arbejdsmappe vs. indeks)
$diffs = $repo->diff();
foreach ($diffs as $diff) {
echo $diff->format();
}
Sammenligner hver fil i indekset med dens aktuelle tilstand i arbejdsområdet. Registrerer ændringer, sletninger og binære filer.
Indekserede ændringer (indeks vs. HEAD)
$diffs = $repo->diffStaged();
foreach ($diffs as $diff) {
echo $diff->format();
}
Sammenligner det aktuelle indeks med træet i HEAD-committen. Viser, hvad der kommer med i den næste commit. Slettede og tilføjede filer med lignende indhold rapporteres som én post for en omdøbt fil. Før den første commit findes der ingen HEAD, og resultatet er tomt (#5).
Parringen af omdøbninger matcher i øjeblikket også ikke-relaterede filer på én linje, fordi den afsluttende tomme linje tæller som fælles indhold (#4).
Træ-til-træ-diff
$a = $repo->readObject($repo->resolve('HEAD~1')->hex)->tree;
$b = $repo->head()->tree;
$diffs = $repo->diffTree($a, $b);
Sammenligner to træer rekursivt. Angiv træ-id'er: commit-id'er foldes ikke ud til deres træer og giver et tomt resultat. Den samme TreeDiff-motor ligger til grund for diffStaged(), show() og logPath().
Filtrér efter sti
$diffs = $repo->diff('src/specific-file.php');
Stispecifikationen er én præcis filsti. diffStaged() accepterer det samme argument, men ignorerer det i øjeblikket, så den altid returnerer alle indekserede filer (#5).
Vælg en algoritme
$diffs = $repo->diff(null, 'patience');
$diffs = $repo->diffStaged(null, 'histogram');
$diffs = $repo->diffTree($a, $b, 'minimal');
Gyldige navne er myers (standard), patience, histogram og minimal. Ethvert andet navn kaster InvalidArgumentException.
DiffResult-struktur
Hver DiffResult repræsenterer forskellen for én enkelt fil.
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'
}
}
}
Formateret output
echo $diff->format();
Producerer output med forenede forskelle. For en ændret tekstfil svarer det til 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()
{
Kontrollér for ændringer
if ($diff->hasChanges()) {
// File was modified (or is binary with changes)
}
Hunk-struktur
Hver Hunk repræsenterer et sammenhængende ændringsområde med kontekstlinjer.
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 @@"
Diff-algoritmer
Pitmaster implementerer fire diff-algoritmer. Standardalgoritmen er Myers.
Myers-diff
Standardalgoritmen O(ND), den samme som gits standardalgoritme. Giver minimale redigeringsscripts.
use Pitmaster\Diff\MyersDiff;
$hunks = MyersDiff::diff($oldContent, $newContent);
Metoden diff() tager to strenge og returnerer et array af Hunk-objekter. Den opdeler inputtet ved linjeskift, beregner det korteste redigeringsscript og grupperer ændringer i hunks med 3 kontekstlinjer (som git gør som standard).
Tålmodig diff
Bedre strukturelle diff'er for kode. Matcher først unikke linjer og udfylder derefter mellemrummene.
use Pitmaster\Diff\PatienceDiff;
$hunks = PatienceDiff::diff($oldContent, $newContent);
Histogram-diff
En variant af tålmodig diff, der håndterer gentagne linjer bedre. Bruges af JGit og Eclipse.
use Pitmaster\Diff\HistogramDiff;
$hunks = HistogramDiff::diff($oldContent, $newContent);
Minimal diff
Producerer den mindst mulige diff (færrest ændrede linjer) på bekostning af mere beregning.
use Pitmaster\Diff\MinimalDiff;
$hunks = MinimalDiff::diff($oldContent, $newContent);
Registrering af binærfiler
Pitmaster behandler indhold som binært, hvis det indeholder en NUL-byte blandt de første 8192 bytes (git kontrollerer de første 8000).
if (MyersDiff::isBinary($content)) {
// Binary file, skip line-level diff
}
Binære filer giver en DiffResult med $binary = true og et tomt $hunks-array. Det formaterede output er:
diff --git a/image.png b/image.png
Binary files differ
Farvelagt output
CLI bruger ColorDiff til terminaloutput med ANSI-farver.
use Pitmaster\Diff\ColorDiff;
$colorized = ColorDiff::colorize($diff->format());
echo $colorized;
- Tilføjede linjer (
+) vises med grønt - Fjernede linjer (
-) vises med rødt - Hunk-headere (
@@) vises med cyan - Filheadere (
diff --git,index,---,+++) vises med fed skrift
pitmaster diff farvelægger altid output, også når det sendes gennem en pipe. pitmaster show farvelægger kun, når stdout er en terminal.
Tree-diff (intern)
Klassen TreeDiff sammenligner to tree-objekter rekursivt og producerer en DiffResult for hver ændret fil.
use Pitmaster\Diff\TreeDiff;
$treeDiff = new TreeDiff($repo->objectDatabase());
$diffs = $treeDiff->diff($oldTreeId, $newTreeId);
Tree-diff håndterer:
- Tilføjede filer (findes kun i det nye tree)
- Slettede filer (findes kun i det gamle tree)
- Ændrede filer (samme sti, forskellig blob-hash)
- Rekursiv sammenligning af undermapper
- Parring af omdøbninger mellem slettede og tilføjede filer (præcist hash-match eller mindst 50 % fælles linjer)
Poster med uændret hash springes over, så en ændring af tilstanden alene ikke giver et resultat.
Orddiff
Til ændringer på ordniveau inde i linjer.
use Pitmaster\Diff\WordDiff;
$result = WordDiff::diff('the quick fox', 'the slow fox');
// 'the [-quick-]{+slow+} fox'