Text::Diff::Parser(3)

πŸ“¦
version 0.1001 Β· 2 versions
, in fedora 43

🌸 NAME 🌸

Text::Diff::Parser β€” bestie, this is the module that parses patch files containing unified and standard diffs. It lives in section 3 of the User Contributed Perl Documentation, and honestly? It's giving workhorse. πŸ’…


✨ SYNOPSIS ✨

use Text::Diff::Parser;

# create the object
my $parser = Text::Diff::Parser->new();

# With options
$parser = Text::Diff::Parser->new( Simplify=>1, # simplify the diff
                                   Strip=>2 );  # strip 2 directories

# Create object.  Parse $file
$parser = Text::Diff::Parser->new( $file );
$parser = Text::Diff::Parser->new( File=>$file );

# Create object.  Parse text
my $parser = Text::Diff::Parser->new( $text );
$parser = Text::Diff::Parser->new( Diff=>$text );

# parse a file
$parser->parse_file( $filename );

# parse a string
$parser->parse( $text );

# Remove no-change lines.  Combine line substitutions
$parser->simplify;

# Find results
foreach my $change ( $parser->changes ) {
    print "File1: ", $change->filename1;
    print "Line1: ", $change->line1;
    print "File2: ", $change->filename2;
    print "Line2: ", $change->line2;
    print "Type: ", $change->type;
    my $size = $change->size;
    foreach my $line ( 0..($size-1) ) {
        print "Line: ", $change->text( $line );
    }
}

# In scalar context, returns the number of changes
my $n = $parser->changes;
print "There are $n changes",

# Get the changes to a given file
my @changes = $parser->changes( 'Makefile.PL' );

# Get list of files changed by the diff
my @files = $parser->files;

πŸ¦‹ DESCRIPTION πŸ¦‹

So "Text::Diff::Parser" parses diff files and patches, okay? And the whole point is that it lets you access the changes to a file in a standardized way, even if multiple patch formats are used. Multiple formats, one vibe check. πŸ”₯

A diff may be viewed as a series of operations on a file β€” either adding, removing or modifying lines of one file (the "from-file") to produce another file (the "to-file"). Diffs are generaly produced either by hand with diff, or by your version control system ("cvs diff", "svn diff", ...). Some diff formats, notably unified diffs, also contain null operations, that is lines that

(yes bestie, the original sentence just... stops there. that's canon. we do not editorialize. 🫢)

"Text::Diff::Parser" currently parses unified diff format and standard diff format. That's the roster.

Unified diffs look like the following.

--- Filename1 2006-04-12 18:47:22.000000000 -0400
+++ Filename2 2006-04-12 19:21:16.000000000 -0400
@@ -1,4 +1,6 @@
 ONE
 TWO
-THREE
+honk
 FOUR
+honk
+honk

Standard diffs look like the following.

diff something something.4
3c3
< THREE
---
> honk
4a5,6
> honk
> honk

The diff line isn't in fact part of the format but is necessary to find which files the chunks deal with. It is output by "cvs diff" and "svn diff" so that isn't a problem. Crisis averted, no cap. 😌


πŸŽ€ METHODS πŸŽ€

🧚 new

$parser = Text::Diff::Parser->new;
$parser = Text::Diff::Parser->new( $file );
$parser = Text::Diff::Parser->new( $handle );
$parser = Text::Diff::Parser->new( %params );
$parser = Text::Diff::Parser->new( \%params );

Object constructor. The main character. πŸ‘‘

  • Diff β€” String that contains a diff. This diff will be parse before "new" returns.
  • File β€” File name or file handle that is parsed before "new" returns.
  • Simplify β€” Simplifying a patch involves dropping all null-operations and converting and remove operation followed by an add operation (or an add followed by a remove) of the same size on the same lines into a modify operation.
  • Strip β€” Strip N leading directories from all filenames. Less then useful for standard diffs produced by "cvs diff", because they don't contain directory information.
  • TrustAtAt β€” In a unified diff, various chunks are introduced with @@. By default, we trust these to reference the right line count. If you set this to 0, the lines will not be trust and a chunk must end with another @@ line or --- (which introduces a new file). Note that not trusting @@ means you can not parse a diff that removes a line that begins with --, because that also start with '---'.
⚠️ bestie read that again. setting TrustAtAt to 0 means a diff that removes a line starting with -- becomes unparseable. that's the tradeoff, fr fr.
  • Verbose β€” If true, print copious details of what is going on. Copious. Details. πŸ’€

πŸ¦„ parse_file

$parser->parse_file( $file );
$parser->parse_file( $handle );

Read and parse the file or file handle specified. Will "die" if it fails, returns true on sucess. Contents of the file may then be accessed with "changes" and "files".

🌈 parse

$parser->parse( $string );

Parses the diff present in $string. Will "die" if it fails, returns true on sucess. Contents of the file may then be accessed with "changes" and "files".

πŸ“ files

%files = $parser->files;

Fetch a list of all the files that were referenced in the patch. The keys are original files ("from-file") and the values are the modified files ("to-file"). Glow up mapping, honestly. ✨

πŸ’– changes

@changes = $parser->changes;
$n = $parser->changes;
@changes = $parser->changes( $file );
$n = $parser->changes( $file );

Return all the operations (array context) or the number of operations in the patch file. If $file is specified, only returns changes to that file ("from-file" or "to-file").

Elements of the returned array are change objects, as described in "CHANGE METHODS" below.

πŸ’… simplify

$parser->simplify;

Simplifies the diff. Removes no-change lines. Combine line substitutions. Automatically called if you supply Simplify to ->new(). Not me doing the cleanup for you. 🧹

⭐ source

my $file = $parser->source

Returns the filename of the last file that was parsed. Returns "user filehandle" if you supplied a file handle.


πŸ‘‘ CHANGE METHODS πŸ‘‘

The "changes" method returns an array of objects that describe each operation. You may use the following methods to find out details of the operation.

πŸ”₯ type

Returns the type of operation, either 'ADD', 'REMOVE', 'MODIFY' or '' (null operation).

🌸 filename1

Filename of the "from-file".

🌸 filename2

Filename of the "to-file".

πŸ’œ line1

Line in the "from-file" the operation starts at.

πŸ’œ line2

Line in the "to-file" the operation starts at.

πŸŽ€ size

Number of lines affected by this operation.

🫢 text

$line  = $ch->text( $N );
@lines = $ch->text;

Fetch the text of the line $N if present or all lines affected by this operation. For '' (null) and 'REMOVE' operations, these are the lines present before the operation was done ('from-file'. For 'ADD' and 'MODIFY' operations, these are the lines present after the operation was done ('to-file'.


πŸ’€ BUGS πŸ’€

I'm not 100% sure of standard diff handling.

Missing support for context diffs.

no context diffs bestie, we simply do not have them. πŸ™ˆ

πŸ¦‹ SEE ALSO πŸ¦‹

Text::Diff, Arch, diff.


✨ AUTHOR ✨

Philip Gwyn, <gwyn-at-cpan.org>


Copyright (C) 2006 by Philip Gwyn

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.


okay that's the whole page, bestie πŸ’– this one's from perl v5.42.0, dated 2025-07-25, and it's the Text::Diff::Parser(3) manual. go forth and parse some diffs, you absolute icon πŸ‘‘βœ¨

πŸ“¦ where this page comes from