Development/Packaging/Tools/Debian Patch Splitter

From Mandriva

Jump to: navigation, search
Debian Patch Splitter

Debian patches often come in the form of a big patch against the source, and this isn't always really useful. The script on this page allows you to split it into smaller patches.

[edit]

Wrapper and classifier script

This script will take 2 arguments, a Debian patch and a folder to store the results. The folder will contain 2 other folders, one named addition for new files created by the patch, and one called patch, which will store each patch, named file.diff, for each changed file.

#!/bin/bash
#
# script nom_paquet [ repertoire_destination ]

# TODO support of not compressed file
#      wget on debian archives
#      rewrite of this part in one script
#      more error detection

if [ $# -ne 2 ]; then

        echo "usage: " asename $0 " packet.diff.gz folder/"
        echo "packet.diff.gz is the patch proved on the ftp mirror"
        echo "folder is the folder where the splitted patch will be found"
        exit 1
fi
DIFF=$1
DOSSIER=$2

mkdir -p $DOSSIER
zcat $DIFF | ( cd $DOSSIER; split_debian.pl )

for i in ind $DOSSIER -type f -name '*.diff' -maxdepth 1; do
        FILEead -n 1 $i | sed 's/--- //' | sed 's#[^/]*/##'
        if cat $i | sed '1,3d' | grep -v -q '^[+\\]' ; then
                PREFIX="$DOSSIER/patch"
        else
                PREFIX="$DOSSIER/addition"
        fi

        mv $i  $PREFIX/$FILEame $FILE
done

for i in ind $DOSSIER/addition -type f; do
        sed -i 's/^[^+].*//' $i
        sed -i 's/^\+//' $i
done

for i in ind $DOSSIER/patch -type f; do
        mv $i $i.diff
done
[edit]

Patch splitting

This scripts split the patch in small chunks, named 1.diff, 2.diff,... It is called split_debian.pl.

#!/usr/bin/perl

$i=0;
$ligne = <STDIN>;

while(1)
{
        # if it begin by '+++ ' or '--- '
        [[PrivoxyWindowOpen]](FICH ,"> $i.diff")|| die "cannot open file $i.diff";
        $i=$i+1;
        print FICH $ligne;
        # for the +++ line
        $ligne = <STDIN>;
        print FICH $ligne;
        
        $ligne = <STDIN>;
        while ( $ligne =~ m/^@@ / )
        {
                print FICH $ligne;
                @field = split(/ /,$ligne);
                $plus = $field[2];
                $moins = $field[1];
                
                ($p = $plus ) =~ s/\+(.*\,)?//;
                ($m = $moins ) =~ s/\-(.*\,)?//;        

                while($p > 0 or $m >0)
                {
                        
                        $m-- unless ($ligne =~ m/^\+/);
                        $p-- unless ($ligne =~ m/^\-/);
                        $ligne = <STDIN>;
                        print FICH $ligne;
                }
                eof(STDIN) and  exit(0);
                $ligne = <STDIN> ;
                #TODO it may be possible to have more than one of these \ ligne
                #
                if ($ligne =~ m/^\\/)
                {
                        print FICH $ligne;
                        $ligne = <STDIN> ;
                }       
        }
}

Personal tools