| 148 |
lars |
1 |
# sebastian/diff
|
|
|
2 |
|
|
|
3 |
[](https://github.com/sebastianbergmann/diff/actions)
|
|
|
4 |
[](https://shepherd.dev/github/sebastianbergmann/diff)
|
|
|
5 |
|
|
|
6 |
Diff implementation for PHP, factored out of PHPUnit into a stand-alone component.
|
|
|
7 |
|
|
|
8 |
## Installation
|
|
|
9 |
|
|
|
10 |
You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/):
|
|
|
11 |
|
|
|
12 |
```
|
|
|
13 |
composer require sebastian/diff
|
|
|
14 |
```
|
|
|
15 |
|
|
|
16 |
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:
|
|
|
17 |
|
|
|
18 |
```
|
|
|
19 |
composer require --dev sebastian/diff
|
|
|
20 |
```
|
|
|
21 |
|
|
|
22 |
### Usage
|
|
|
23 |
|
|
|
24 |
#### Generating diff
|
|
|
25 |
|
|
|
26 |
The `Differ` class can be used to generate a textual representation of the difference between two strings:
|
|
|
27 |
|
|
|
28 |
```php
|
|
|
29 |
<?php
|
|
|
30 |
use SebastianBergmann\Diff\Differ;
|
|
|
31 |
|
|
|
32 |
$differ = new Differ;
|
|
|
33 |
print $differ->diff('foo', 'bar');
|
|
|
34 |
```
|
|
|
35 |
|
|
|
36 |
The code above yields the output below:
|
|
|
37 |
```diff
|
|
|
38 |
--- Original
|
|
|
39 |
+++ New
|
|
|
40 |
@@ @@
|
|
|
41 |
-foo
|
|
|
42 |
+bar
|
|
|
43 |
```
|
|
|
44 |
|
|
|
45 |
There are three output builders available in this package:
|
|
|
46 |
|
|
|
47 |
#### UnifiedDiffOutputBuilder
|
|
|
48 |
|
|
|
49 |
This is default builder, which generates the output close to udiff and is used by PHPUnit.
|
|
|
50 |
|
|
|
51 |
```php
|
|
|
52 |
<?php
|
|
|
53 |
|
|
|
54 |
use SebastianBergmann\Diff\Differ;
|
|
|
55 |
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
|
|
|
56 |
|
|
|
57 |
$builder = new UnifiedDiffOutputBuilder(
|
|
|
58 |
"--- Original\n+++ New\n", // custom header
|
|
|
59 |
false // do not add line numbers to the diff
|
|
|
60 |
);
|
|
|
61 |
|
|
|
62 |
$differ = new Differ($builder);
|
|
|
63 |
print $differ->diff('foo', 'bar');
|
|
|
64 |
```
|
|
|
65 |
|
|
|
66 |
#### StrictUnifiedDiffOutputBuilder
|
|
|
67 |
|
|
|
68 |
Generates (strict) Unified diff's (unidiffs) with hunks,
|
|
|
69 |
similar to `diff -u` and compatible with `patch` and `git apply`.
|
|
|
70 |
|
|
|
71 |
```php
|
|
|
72 |
<?php
|
|
|
73 |
|
|
|
74 |
use SebastianBergmann\Diff\Differ;
|
|
|
75 |
use SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder;
|
|
|
76 |
|
|
|
77 |
$builder = new StrictUnifiedDiffOutputBuilder([
|
|
|
78 |
'collapseRanges' => true, // ranges of length one are rendered with the trailing `,1`
|
|
|
79 |
'commonLineThreshold' => 6, // number of same lines before ending a new hunk and creating a new one (if needed)
|
|
|
80 |
'contextLines' => 3, // like `diff: -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3
|
|
|
81 |
'fromFile' => null,
|
|
|
82 |
'fromFileDate' => null,
|
|
|
83 |
'toFile' => null,
|
|
|
84 |
'toFileDate' => null,
|
|
|
85 |
]);
|
|
|
86 |
|
|
|
87 |
$differ = new Differ($builder);
|
|
|
88 |
print $differ->diff('foo', 'bar');
|
|
|
89 |
```
|
|
|
90 |
|
|
|
91 |
#### DiffOnlyOutputBuilder
|
|
|
92 |
|
|
|
93 |
Output only the lines that differ.
|
|
|
94 |
|
|
|
95 |
```php
|
|
|
96 |
<?php
|
|
|
97 |
|
|
|
98 |
use SebastianBergmann\Diff\Differ;
|
|
|
99 |
use SebastianBergmann\Diff\Output\DiffOnlyOutputBuilder;
|
|
|
100 |
|
|
|
101 |
$builder = new DiffOnlyOutputBuilder(
|
|
|
102 |
"--- Original\n+++ New\n"
|
|
|
103 |
);
|
|
|
104 |
|
|
|
105 |
$differ = new Differ($builder);
|
|
|
106 |
print $differ->diff('foo', 'bar');
|
|
|
107 |
```
|
|
|
108 |
|
|
|
109 |
#### DiffOutputBuilderInterface
|
|
|
110 |
|
|
|
111 |
You can pass any output builder to the `Differ` class as longs as it implements the `DiffOutputBuilderInterface`.
|
|
|
112 |
|
|
|
113 |
#### Parsing diff
|
|
|
114 |
|
|
|
115 |
The `Parser` class can be used to parse a unified diff into an object graph:
|
|
|
116 |
|
|
|
117 |
```php
|
|
|
118 |
use SebastianBergmann\Diff\Parser;
|
|
|
119 |
use SebastianBergmann\Git;
|
|
|
120 |
|
|
|
121 |
$git = new Git('/usr/local/src/money');
|
|
|
122 |
|
|
|
123 |
$diff = $git->getDiff(
|
|
|
124 |
'948a1a07768d8edd10dcefa8315c1cbeffb31833',
|
|
|
125 |
'c07a373d2399f3e686234c4f7f088d635eb9641b'
|
|
|
126 |
);
|
|
|
127 |
|
|
|
128 |
$parser = new Parser;
|
|
|
129 |
|
|
|
130 |
print_r($parser->parse($diff));
|
|
|
131 |
```
|
|
|
132 |
|
|
|
133 |
The code above yields the output below:
|
|
|
134 |
|
|
|
135 |
Array
|
|
|
136 |
(
|
|
|
137 |
[0] => SebastianBergmann\Diff\Diff Object
|
|
|
138 |
(
|
|
|
139 |
[from:SebastianBergmann\Diff\Diff:private] => a/tests/MoneyTest.php
|
|
|
140 |
[to:SebastianBergmann\Diff\Diff:private] => b/tests/MoneyTest.php
|
|
|
141 |
[chunks:SebastianBergmann\Diff\Diff:private] => Array
|
|
|
142 |
(
|
|
|
143 |
[0] => SebastianBergmann\Diff\Chunk Object
|
|
|
144 |
(
|
|
|
145 |
[start:SebastianBergmann\Diff\Chunk:private] => 87
|
|
|
146 |
[startRange:SebastianBergmann\Diff\Chunk:private] => 7
|
|
|
147 |
[end:SebastianBergmann\Diff\Chunk:private] => 87
|
|
|
148 |
[endRange:SebastianBergmann\Diff\Chunk:private] => 7
|
|
|
149 |
[lines:SebastianBergmann\Diff\Chunk:private] => Array
|
|
|
150 |
(
|
|
|
151 |
[0] => SebastianBergmann\Diff\Line Object
|
|
|
152 |
(
|
|
|
153 |
[type:SebastianBergmann\Diff\Line:private] => 3
|
|
|
154 |
[content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::add
|
|
|
155 |
)
|
|
|
156 |
|
|
|
157 |
[1] => SebastianBergmann\Diff\Line Object
|
|
|
158 |
(
|
|
|
159 |
[type:SebastianBergmann\Diff\Line:private] => 3
|
|
|
160 |
[content:SebastianBergmann\Diff\Line:private] => * @covers SebastianBergmann\Money\Money::newMoney
|
|
|
161 |
)
|
|
|
162 |
|
|
|
163 |
[2] => SebastianBergmann\Diff\Line Object
|
|
|
164 |
(
|
|
|
165 |
[type:SebastianBergmann\Diff\Line:private] => 3
|
|
|
166 |
[content:SebastianBergmann\Diff\Line:private] => */
|
|
|
167 |
)
|
|
|
168 |
|
|
|
169 |
[3] => SebastianBergmann\Diff\Line Object
|
|
|
170 |
(
|
|
|
171 |
[type:SebastianBergmann\Diff\Line:private] => 2
|
|
|
172 |
[content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyWithSameCurrencyObjectCanBeAdded()
|
|
|
173 |
)
|
|
|
174 |
|
|
|
175 |
[4] => SebastianBergmann\Diff\Line Object
|
|
|
176 |
(
|
|
|
177 |
[type:SebastianBergmann\Diff\Line:private] => 1
|
|
|
178 |
[content:SebastianBergmann\Diff\Line:private] => public function testAnotherMoneyObjectWithSameCurrencyCanBeAdded()
|
|
|
179 |
)
|
|
|
180 |
|
|
|
181 |
[5] => SebastianBergmann\Diff\Line Object
|
|
|
182 |
(
|
|
|
183 |
[type:SebastianBergmann\Diff\Line:private] => 3
|
|
|
184 |
[content:SebastianBergmann\Diff\Line:private] => {
|
|
|
185 |
)
|
|
|
186 |
|
|
|
187 |
[6] => SebastianBergmann\Diff\Line Object
|
|
|
188 |
(
|
|
|
189 |
[type:SebastianBergmann\Diff\Line:private] => 3
|
|
|
190 |
[content:SebastianBergmann\Diff\Line:private] => $a = new Money(1, new Currency('EUR'));
|
|
|
191 |
)
|
|
|
192 |
|
|
|
193 |
[7] => SebastianBergmann\Diff\Line Object
|
|
|
194 |
(
|
|
|
195 |
[type:SebastianBergmann\Diff\Line:private] => 3
|
|
|
196 |
[content:SebastianBergmann\Diff\Line:private] => $b = new Money(2, new Currency('EUR'));
|
|
|
197 |
)
|
|
|
198 |
)
|
|
|
199 |
)
|
|
|
200 |
)
|
|
|
201 |
)
|
|
|
202 |
)
|