Skip to content
A parser for unified diffs
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


A parser for unified diff files, returning a hydrated object graph.

Uses __toString() to serialize back into unified diff format.

Build Status Code Coverage Scrutinizer Quality Score Latest Stable Version


Either from the console:

    $ composer require ptlis/diff-parser:"~0.6"

Or by Editing composer.json:

        "require": {
            "ptlis/diff-parser": "~0.6",

Followed by a composer update:

    $ composer update


Build a Changeset

Both public methods of the ptlis\DiffParser\Parser class return a changeset representation of the diff:

Get a changeset from a file:

    use ptlis\DiffParser\Parser;
    $parser = new Parser();
    $changeset = $parser->parseFile('path/to/svn/diff', Parser::VCS_SVN);

Get a changeset from string array:

    use ptlis\DiffParser\Parser;
    $lineList = ...    // the array of diff lines is created/retrieved somehow 
    $parser = new Parser();
    $changeset = $parser->parseLines($lineList, Parser::VCS_SVN);


All of the value classes implement the __toString() method to support direct serialization of that component back to unified diff format.

For example, serialization of a changeset back to a file is as simple as:

    $file = fopen('my.patch', 'w');
    fwrite($file, $changeset);

The Object Graph

The tree built to store changesets is very simple, in essence:

  • A Changeset is the root node & contains Files
  • A File contain Hunks
  • A Hunk contain Lines
  • Lines are the leaf nodes.


The Changeset class provides a single method to retrieve a list of files that have changed:

    $fileList = $changeset->getChangedFiles();  // Array of ptlis\DiffParser\File instances.


    $file = $fileList[0];           // Get the first changed file

Get the original and new filenames:

    $file->getOriginalFilename();   // Eg '' or '' (empty) on create
    $file->getNewFilename();        // EG '' or '' (empty) on delete

Get the operation that was performed (create, delete or change):

    $file->getOperation();          // One of File::CREATED, File::CHANGED, File::DELETED  

Get the changed hunks for the file:

    $hunkList = $file->getHunks();  // Array of ptlis\DiffParser\Hunk instances.  


    $hunk = $hunkList[0];           // Get the first hunk for this file

Get the hunk metadata:

    $hunk->getOriginalStart();      // Eg '0'
    $hunk->getOriginalCount();      // Eg '5'
    $hunk->getNewStart();           // Eg '0'
    $hunk->getNewCount();           // Eg '7'

Get the changed lines:

    $lineList = $hunk->getLines();  // Array of ptlis\DiffParser\Line instances.  


    $line = $lineList[0];           // Get the first line for this hunk

Get the original and new line numbers:

    $line->getOriginalLineNo();     // Eg '7' or '-1' on create
    $line->getNewLineNo();          // Eg '7' or '-1' on delete

Get the operation:

    $line->getOperation();          // One of Line::ADDED, Line::REMOVED, Line::UNCHANGED

Get the value of the line:

    $line->getContent();              // Eg ' $foo = bar;'


You can contribute by submitting an Issue to the issue tracker, improving the documentation or submitting a pull request. For pull requests i'd prefer that the code style and test coverage is maintained, but I am happy to work through any minor issues that may arise so that the request can be merged.


  • Add more tests for robustness - being generated, in theory diffs should be reliable, but we still need to gracefully fail when this assumption is false.
You can’t perform that action at this time.