• Stars
    star
    7,476
  • Rank 4,870 (Top 0.1 %)
  • Language
    PHP
  • License
    BSD 3-Clause "New...
  • Created about 11 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Diff implementation

Latest Stable Version CI Status Type Coverage codecov

sebastian/diff

Diff implementation for PHP, factored out of PHPUnit into a stand-alone component.

Installation

You can add this library as a local, per-project dependency to your project using Composer:

composer require sebastian/diff

If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency:

composer require --dev sebastian/diff

Usage

Generating diff

The Differ class can be used to generate a textual representation of the difference between two strings:

<?php
use SebastianBergmann\Diff\Differ;

$differ = new Differ;
print $differ->diff('foo', 'bar');

The code above yields the output below:

--- Original
+++ New
@@ @@
-foo
+bar

There are three output builders available in this package:

UnifiedDiffOutputBuilder

This is default builder, which generates the output close to udiff and is used by PHPUnit.

<?php

use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;

$builder = new UnifiedDiffOutputBuilder(
    "--- Original\n+++ New\n", // custom header
    false                      // do not add line numbers to the diff 
);

$differ = new Differ($builder);
print $differ->diff('foo', 'bar');

StrictUnifiedDiffOutputBuilder

Generates (strict) Unified diff's (unidiffs) with hunks, similar to diff -u and compatible with patch and git apply.

<?php

use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder;

$builder = new StrictUnifiedDiffOutputBuilder([
    'collapseRanges'      => true, // ranges of length one are rendered with the trailing `,1`
    'commonLineThreshold' => 6,    // number of same lines before ending a new hunk and creating a new one (if needed)
    'contextLines'        => 3,    // like `diff:  -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3
    'fromFile'            => '',
    'fromFileDate'        => null,
    'toFile'              => '',
    'toFileDate'          => null,
]);

$differ = new Differ($builder);
print $differ->diff('foo', 'bar');

DiffOnlyOutputBuilder

Output only the lines that differ.

<?php

use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\DiffOnlyOutputBuilder;

$builder = new DiffOnlyOutputBuilder(
    "--- Original\n+++ New\n"
);

$differ = new Differ($builder);
print $differ->diff('foo', 'bar');

DiffOutputBuilderInterface

You can pass any output builder to the Differ class as longs as it implements the DiffOutputBuilderInterface.

Parsing diff

The Parser class can be used to parse a unified diff into an object graph:

use SebastianBergmann\Diff\Parser;
use SebastianBergmann\Git;

$git = new Git('/usr/local/src/money');

$diff = $git->getDiff(
  '948a1a07768d8edd10dcefa8315c1cbeffb31833',
  'c07a373d2399f3e686234c4f7f088d635eb9641b'
);

$parser = new Parser;

print_r($parser->parse($diff));

The code above yields the output below:

Array
(
    [0] => SebastianBergmann\Diff\Diff Object
        (
            [from:SebastianBergmann\Diff\Diff:private] => a/tests/MoneyTest.php
            [to:SebastianBergmann\Diff\Diff:private] => b/tests/MoneyTest.php
            [chunks:SebastianBergmann\Diff\Diff:private] => Array
                (
                    [0] => SebastianBergmann\Diff\Chunk Object
                        (
                            [start:SebastianBergmann\Diff\Chunk:private] => 87
                            [startRange:SebastianBergmann\Diff\Chunk:private] => 7
                            [end:SebastianBergmann\Diff\Chunk:private] => 87
                            [endRange:SebastianBergmann\Diff\Chunk:private] => 7
                            [lines:SebastianBergmann\Diff\Chunk:private] => Array
                                (
                                    [0] => SebastianBergmann\Diff\Line Object
                                        (
                                            [type:SebastianBergmann\Diff\Line:private] => 3
                                            [content:SebastianBergmann\Diff\Line:private] =>      * @covers SebastianBergmann\Money\Money::add
                                        )

                                    [1] => SebastianBergmann\Diff\Line Object
                                        (
                                            [type:SebastianBergmann\Diff\Line:private] => 3
                                            [content:SebastianBergmann\Diff\Line:private] =>      * @covers SebastianBergmann\Money\Money::newMoney
                                        )

                                    [2] => SebastianBergmann\Diff\Line Object
                                        (
                                            [type:SebastianBergmann\Diff\Line:private] => 3
                                            [content:SebastianBergmann\Diff\Line:private] =>      */
                                        )

                                    [3] => SebastianBergmann\Diff\Line Object
                                        (
                                            [type:SebastianBergmann\Diff\Line:private] => 2
                                            [content:SebastianBergmann\Diff\Line:private] =>     public function testAnotherMoneyWithSameCurrencyObjectCanBeAdded()
                                        )

                                    [4] => SebastianBergmann\Diff\Line Object
                                        (
                                            [type:SebastianBergmann\Diff\Line:private] => 1
                                            [content:SebastianBergmann\Diff\Line:private] =>     public function testAnotherMoneyObjectWithSameCurrencyCanBeAdded()
                                        )

                                    [5] => SebastianBergmann\Diff\Line Object
                                        (
                                            [type:SebastianBergmann\Diff\Line:private] => 3
                                            [content:SebastianBergmann\Diff\Line:private] =>     {
                                        )

                                    [6] => SebastianBergmann\Diff\Line Object
                                        (
                                            [type:SebastianBergmann\Diff\Line:private] => 3
                                            [content:SebastianBergmann\Diff\Line:private] =>         $a = new Money(1, new Currency('EUR'));
                                        )

                                    [7] => SebastianBergmann\Diff\Line Object
                                        (
                                            [type:SebastianBergmann\Diff\Line:private] => 3
                                            [content:SebastianBergmann\Diff\Line:private] =>         $b = new Money(2, new Currency('EUR'));
                                        )
                                )
                        )
                )
        )
)

Note: If the chunk size is 0 lines, i.e., getStartRange() or getEndRange() return 0, the number of line returned by getStart() or getEnd() is one lower than one would expect. It is the line number after which the chunk should be inserted or deleted; in all other cases, it gives the first line number of the replaced range of lines.

More Repositories

1

phpunit

The PHP Unit Testing framework.
PHP
19,539
star
2

php-code-coverage

Library that provides collection, processing, and rendering functionality for PHP code coverage information.
PHP
8,645
star
3

php-timer

Utility class for timing
PHP
7,576
star
4

php-file-iterator

FilterIterator implementation that filters files based on a list of suffixes, prefixes, and other exclusion criteria.
PHP
7,344
star
5

php-text-template

A simple template engine.
PHP
7,292
star
6

comparator

Provides the functionality to compare PHP values for equality.
PHP
6,925
star
7

exporter

Provides the functionality to export PHP variables for visualization
PHP
6,705
star
8

environment

Provides functionality that helps writing PHP code that has runtime-specific execution paths
PHP
6,657
star
9

code-unit-reverse-lookup

Looks up which function or method a line of code belongs to
PHP
6,529
star
10

global-state

Snapshotting of global state, factored out of PHPUnit into a stand-alone component
PHP
6,493
star
11

recursion-context

Provides functionality to recursively process PHP variables
PHP
6,465
star
12

php-token-stream

Wrapper around PHP's tokenizer extension.
PHP
6,462
star
13

version

Library that helps with managing the version number of Git-hosted PHP projects
PHP
6,415
star
14

object-enumerator

Traverses array structures and object graphs to enumerate all referenced objects
PHP
6,290
star
15

resource-operations

Provides a list of PHP built-in functions that operate on resources
PHP
6,186
star
16

object-reflector

Allows reflection of object attributes, including inherited and non-public ones
PHP
6,074
star
17

phpunit-mock-objects

Mock Object library for PHPUnit
PHP
4,985
star
18

phploc

A tool for quickly measuring the size of a PHP project.
PHP
2,277
star
19

phpcpd

Copy/Paste Detector (CPD) for PHP code.
PHP
2,228
star
20

type

Collection of value objects that represent the types of the PHP type system
PHP
1,182
star
21

php-invoker

Invoke PHP callables with a timeout
PHP
1,023
star
22

complexity

Library for calculating the complexity of PHP code units
PHP
916
star
23

cli-parser

Library for parsing CLI options
PHP
862
star
24

code-unit

Collection of value objects that represent the PHP code units
PHP
860
star
25

lines-of-code

Library for counting the lines of code in PHP source code
PHP
834
star
26

money

Value Object that represents a monetary value (using a currency's smallest unit).
PHP
734
star
27

php-jenkins-template

Template for Jenkins jobs for PHP projects
522
star
28

object-graph

Provides useful operations on PHP object graphs
PHP
451
star
29

phpdcd

Dead Code Detector (DCD) for PHP code.
PHP
407
star
30

finder-facade

Convenience wrapper for Symfony's Finder component
PHP
253
star
31

state

The State design pattern. Implemented in PHP and with style.
PHP
230
star
32

dbunit

DbUnit port for PHP/PHPUnit.
PHP
223
star
33

phpcov

TextUI frontend for php-code-coverage
PHP
202
star
34

phpunit-documentation

Documentation for PHPUnit.
HTML
189
star
35

phpunit-skeleton-generator

Tool that can generate skeleton test classes from production code classes and vice versa.
PHP
159
star
36

foal

Tool to find lines eliminated by OpCache's bytecode optimizer
PHP
125
star
37

git

Simple PHP wrapper for Git
PHP
124
star
38

de-legacy-fy

Tool for dealing with legacy PHP code
PHP
76
star
39

phpunit-documentation-english

English Documentation for PHPUnit
PHP
70
star
40

container-amiga-gcc

Containerfile for AmigaOS Cross-Compiler Toolchain
PHP
54
star
41

peek-and-poke

Proxy for accessing non-public attributes and methods of an object
PHP
36
star
42

phpunit-documentation-chinese

Simplified Chinese Documentation for PHPUnit
Python
35
star
43

shaku

Tool to automatically generate type-safe Collection and CollectionIterator classes
PHP
32
star
44

csv-parser

Library for type-safe parsing of CSV files
PHP
30
star
45

uuid

Function for generating a UUID (as string)
PHP
26
star
46

docker-execute-amiga

Execute M68K/AmigaOS binary in Docker-ized FS-UAE
Shell
25
star
47

raytracer

Code written while reading the book "The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer" by Jamis Buck.
PHP
21
star
48

phar-site-generator

A tool that generates an HTML page, RSS feed, and Phive metadata for a PHAR repository
PHP
20
star
49

phpunit-documentation-russian

Russian Documentation for PHPUnit
Python
17
star
50

bugminer

Mines a source code repository for bug and churn information.
PHP
16
star
51

pdepend-process

Processor for PHP_Depend data
PHP
14
star
52

sebastianbergmann

14
star
53

phpunit-documentation-japanese

Japanese Documentation for PHPUnit
Python
13
star
54

phpunit-mink-trait

Trait that provides a minimal integration layer for using Mink in PHPUnit test cases
PHP
12
star
55

phpunit-website

https://phpunit.de/
HTML
12
star
56

phpunit-documentation-french

French Documentation for PHPUnit
Python
11
star
57

phpunit-documentation-brazilian-portuguese

Brazilian Portuguese Documentation for PHPUnit
Python
10
star
58

docker-amigaos-cross-toolchain

Dockerfile for AmigaOS Cross-Compiler Toolchain
PHP
9
star
59

phpunit-memprof-listener

Test Listener for PHPUnit that can dump memory profile information
PHP
9
star
60

phpunit-runner

Proof-of-Concept for new PHPUnit test runner
PHP
8
star
61

xdebug-trace-util

Collection of value objects, filters, etc. for working with Xdebug function traces
PHP
7
star
62

phpunit-kata-prime-factors

This is a port of Robert C. Martin's Prime Factors kata to PHP and with unit tests written using PHPUnit
PHP
6
star
63

phpunit-example-extension

Example of an extension for PHPUnit
PHP
6
star
64

die-kathedrale

PHP
6
star
65

phpunit-test-report

Generates a combined test result / code coverage report in HTML format
5
star
66

container-amitools

Containerfile for Christian Vogelgsang's amitools
PHP
4
star
67

test-mapper

A tool that visualizes the information of PHPUnit's "covers" and "uses" annotations
PHP
4
star
68

phpunit-documentation-spanish

Spanish Documentation for PHPUnit
Python
3
star
69

phptok

TextUI frontend for PHP_TokenStream
PHP
3
star