diff options
author | Martin Quinson <mquinson@debian.org> | 2003-01-29 09:19:25 +0000 |
---|---|---|
committer | Martin Quinson <mquinson@debian.org> | 2003-01-29 09:19:25 +0000 |
commit | 9df01863feac767ebe01e99cfc597632416ca27a (patch) | |
tree | 27b023026b54e2db2a784ce86b7b075868eaf960 /lib/patchfns.in | |
parent | 55181ac1bcf951cc22cba26dfbca813fba2b0167 (diff) | |
download | quilt-9df01863feac767ebe01e99cfc597632416ca27a.tar.gz |
Version 0.21 from Andreas Gruenbacher
Diffstat (limited to 'lib/patchfns.in')
-rw-r--r-- | lib/patchfns.in | 434 |
1 files changed, 319 insertions, 115 deletions
diff --git a/lib/patchfns.in b/lib/patchfns.in index 63fae45..17c5b56 100644 --- a/lib/patchfns.in +++ b/lib/patchfns.in @@ -1,8 +1,10 @@ -debug() -{ - #echo "$@" >&2 - true -} +#!/bin/bash + +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# See the COPYING and AUTHORS files for more details. if [ -n "$PATCHSCRIPTS" ] then @@ -23,20 +25,36 @@ fi DB=".pc/applied-patches" +# Define where diffstat lives (may be missing) +DIFFSTAT=/usr/bin/diffstat + quote_re() { echo "$1" | sed -e 's:\([/.+*\[\\]\):\\\1:g' } +#basename() +#{ +# local path=${1%/} +# echo "${path/*\/}" +#} + +#dirname() +#{ +# local path=${1%/} +#} + patch_file_name() { local patch=$1 if [ -e $SERIES ] then - awk '/^'"$(quote_re $patch)"'(|\.patch|\.diff?)([ \t]|$)/ \ - { printf "'"$P"'patches/%s\n", $1; exit }' \ - $SERIES + awk '/^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \ + { printf "'"$P"'patches/%s\n", $1 + exit + } + ' $SERIES fi } @@ -47,13 +65,16 @@ patch_args() if [ -e $SERIES ] then - awk '/^'"$(quote_re $patch)"'(|\.patch|\.diff?)([ \t]|$)/ \ + awk ' + /^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \ { if (NF >= 2) for (i=2; i <= NF; i++) - print $i ; - else print "-p1" ; - exit }' \ - $SERIES + print $i + else + print "-p1" ; + exit + } + ' $SERIES fi } @@ -87,20 +108,24 @@ change_db_strip_level() if [ -e $SERIES ] then - local tmp=$(mktemp /tmp/patch-scripts.XXXXXX) - awk '/^'"$(quote_re $patch)"'(\.patch|\.diff?)([ \t]|$)/ \ - {for(i=2; i<=NF; i++) - if ($i ~ /^-p/) - {$i="'"$level"'" ; break} - if (i > NF) - $i="'"$level"'"} - {print}' \ - $SERIES > $tmp - if cmp $SERIES $tmp >/dev/null 2>/dev/null + local tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX) + awk ' + /^'"$(quote_re $patch)"'(\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \ + { for(i=2; i<=NF; i++) + if ($i ~ /^-p/) { + $i="'"$level"'" + break + } + if (i > NF) + $i="'"$level"'" + } + { print } + ' $SERIES > $tmpfile + if cmp $SERIES $tmpfile >/dev/null 2>/dev/null then - rm -f $tmp + rm -f $tmpfile else - mv -f $tmp $SERIES + mv -f $tmpfile $SERIES fi else return 1 @@ -115,7 +140,7 @@ patch_in_series() then return 1 else - grep -q '^'"$(quote_re $patch)"'\(\|\.patch\|.diff\?\)\([ \t]\|$\)' $SERIES + grep -q '^'"$(quote_re $patch)"'\(\|\.patch\|.diff\?\)\(\|\.gz\|\.bz2\)\([ \t]\|$\)' $SERIES fi } @@ -123,31 +148,54 @@ patch_in_series() insert_in_series() { local patch=$1 patch_args=$2 - local top=$(top_patch) tmp + local top=$(top_patch) tmpfile if [ -n "$patch_args" ] then patch_args=" $patch_args" fi - tmp=$(mktemp /tmp/patch-scripts.XXXXXX) || return 1 + tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX) || return 1 + mkdir -p $(dirname $SERIES) if [ -n "$top" ] then - awk ' { print } - /^'"$(quote_re $top)"'(|\.patch|\.diff?)([ \t]|$)/ \ - { print "'"$patch$patch_args"'" }' \ - < $SERIES \ - > $tmp \ - || return 1 + awk ' + { print } + /^'"$(quote_re $top)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \ + { print "'"$patch$patch_args"'" } + ' $SERIES > $tmpfile + status=$? + if [ $status -ne 0 ] + then + rm -f $tmpfile + return 1 + fi else - echo $patch$patch_args > $tmp + echo $patch$patch_args > $tmpfile if [ -e $SERIES ] then - cat $SERIES >> $tmp + cat $SERIES >> $tmpfile fi fi - mkdir -p $(dirname $SERIES) - mv -f $tmp $SERIES + mv -f $tmpfile $SERIES +} + +remove_from_series() +{ + local patch=$1 + + tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX) || return 1 + awk ' + ! /^'"$(quote_re $patch)"'(|\.patch|\.diff?)(|\.gz|\.bz2)([ \t]|$)/ \ + { print } + ' $SERIES > $tmpfile + if [ $? -eq 0 ] + then + mv -f $tmpfile $SERIES + else + rm -f $tmpfile + return 1 + fi } pc_file_name() @@ -170,34 +218,23 @@ backup_file_name() done } -__cat_series() +cat_series() { - local series=$1 - if [ -e $series ] + if [ -e $SERIES ] then sed -e '/^#/d' -e 's/^[ \t]*//' -e 's/[ \t].*//' \ - -e 's/\.patch$//' -e 's/\.diff\?//' $series + -e 's/\.gz$//' -e 's/\.bz2$//' \ + -e 's/\.patch$//' -e 's/\.diff\?$//' $SERIES else return 1 fi } -cat_series() -{ - __cat_series $SERIES -} - top_patch() { [ -e $DB ] && tail -1 $DB } -die() -{ - echo "error: $*" - exit 1 -} - is_numeric() { echo $1 | grep -q -e '^[0-9]*$' @@ -219,17 +256,30 @@ is_applied() patches_before() { local patch=$1 - cat_series \ - | awk '$0 == "'"$patch"'" { exit } - { print }' + + if [ -n "$patch" ] + then + cat_series \ + | awk ' + $0 == "'"$patch"'" { exit } + { print } + ' + fi } patches_after() { local patch=$1 - cat_series \ - | awk 'seen { print } - $0 == "'"$patch"'" { seen=1 }' + if [ -n "$patch" ] + then + cat_series \ + | awk ' + seen { print } + $0 == "'"$patch"'" { seen=1 } + ' + else + cat_series + fi } # List all patches that have been applied on top of patch $1 @@ -237,8 +287,10 @@ patches_on_top_of() { local patch=$1 [ -e $DB ] || return - awk '$0 == "'"$patch"'" { seen=1 ; next } - seen { print }' $DB + awk ' + $0 == "'"$patch"'" { seen=1 ; next } + seen { print } + ' $DB } # Print the name of the patch that modified the file $2 next after @@ -255,30 +307,106 @@ next_patch_for_file() | head -1 \ | sed -e 's:^\.pc/::' -e 's:/\.pc$::' fi + + #modified_files $file -- $patches_on_top \ + #| cut -d $'\t' -f2 \ + #| cut -d ' ' -f1 } -can_apply() +# Create a list of files and the patches that modify them. +refresh_patches_per_file() { - local silent - if [ "x$1" == "x-s" ] + local pc_files=$(pc_file_name $(cat_series)) + local ex_pc_files pc_file + + if [ -e .pc/patches-per-file ] then - silent=-s - shift + local needs_refresh + for pc_file in pc_files + do + if [ .pc/patches-per-file -ot $pc_file ] + then + needs_refresh=1 + break + fi + done + if [ -z "$needs_refresh" ] + then + return 0 + fi fi - local patch=$1 - patch -p1 --dry-run -f $silent -i $(patch_file_name $patch) < /dev/null -} -can_remove() -{ - local silent - if [ "x$1" == "x-s" ] + for pc_file in $pc_files + do + if [ -e $pc_file ] + then + ex_pc_files[${#ex_pc_files[@]}]=$pc_file + fi + done + + if [ ${#ex_pc_files[@]} -eq 0 ] then - silent=-s - shift + rm -f .pc/patches-per-file + return 0 fi - local patch=$1 - patch -R -p1 --dry-run -f $silent -i $(patch_file_name $patch) < /dev/null + + awk ' + ARGIND!=saved { sub(/^.pc\//, "", FILENAME) + sub(/\/\.pc/, "", FILENAME) + saved=ARGIND + } + { if (files[$0]) + files[$0]=files[$0] " " FILENAME + else + files[$0]=FILENAME + } + END { for (file in files) + printf "%s\t%s\n", file, files[file] + } + ' "${ex_pc_files[@]}" > .pc/patches-per-file +} + +# For a lists of patches and a list of files, compute which patches +# modify which files. Invoked as +# modified_files file ... [-- patch ...] +# +modified_files() +{ + if ! refresh_patches_per_file + then + return 1 + fi + + awk ' + BEGIN { no_files=1 + no_patches=1 + for (i=1; i<ARGC; i++) { + if (ARGV[i]=="--") + break + files[ARGV[i]]=1 + no_files=0 + } + for (i++; i<ARGC; i++) { + patches[ARGV[i]]=1 + no_patches=0 + } + split("", ARGV) # read from standard input + } + no_files || files[$1] { + if (no_patches) { + print + next + } + for (i=2; i<=NF; i++) + if ($i in patches) { + printf "%s\t%s", $1, $i + for (i++; i<=NF; i++) + if ($i in patches) + printf " %s", $i + printf "\n" + } + } + ' "$@" < .pc/patches-per-file } add_to_db() @@ -290,10 +418,13 @@ remove_from_db() { local patch=$1 local tmpfile - tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX) - grep -v "^$patch\$" $DB > $tmpfile - mv -f $tmpfile $DB - [ -s $DB ] || rm -f $DB + if tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX) + then + grep -v "^$(quote_re $patch)\$" $DB > $tmpfile + mv -f $tmpfile $DB + rm -f $tmpfile + [ -s $DB ] || rm -f $DB + fi } stripit() @@ -303,6 +434,7 @@ stripit() echo $1 | sed -e 's/^\(\.\/\)*//' \ -e 's/^'"$P"'patches\///' -e 's/^\.pc\///' \ + -e 's/\.gz$//' -e 's/\.bz2$//' \ -e 's/\.patch$//' -e 's/\.diff\?$//' fi } @@ -322,15 +454,19 @@ files_in_patch() fi } -install_file_in_patch() +touched_by_patch() { - local file=$1 patch=$2 bup_file=$(backup_file_name $patch $file) - - if ! echo $file @LIB@/backup-file -s -B .pc/$patch/ || \ - ! echo $file >> $(pc_file_name $patch) - then - return 1 - fi + local strip=$1 patch=$2 + cat_file $(patch_file_name $patch) \ + | awk ' + /^\+\+\+[ \t]/ { + sub(/^\+\+\+[ \t]/, "") + sub(/[ \t].*/, "") + sub(/^\/dev\/null/, "") + for (i=0; i<'$strip'; i++) + sub(/^[^\/]*\//, "") + print + }' } refresh_file_list() @@ -341,40 +477,103 @@ refresh_file_list() if ! [ -e "$patch_file" ] then - echo "Patch file $patch_file does not exist" - return 1 + return 0 fi - if [ ! -e $pc_file -o $pc_file -ot $patch_file ] + if [ ! -e $pc_file -o \ + $pc_file -ot $patch_file -o \ + $pc_file -ot $SERIES ] then - mkdir -p $(dirname $pc_file) - echo "touched-by-patch $(patch_strip_level $patch) $patch_file > $pc_file" >&2 - @LIB@/touched-by-patch -p$(patch_strip_level $patch) \ - $patch_file > $pc_file - if [ $? -ne 0 ] + local tmpfile status + if ! mkdir -p $(dirname $pc_file) || \ + ! tmpfile=$(mktemp /tmp/patch-scripts.XXXXXX) + then + return 1 + fi + + if [ -e $pc_file ] + then + cat $pc_file >> $tmpfile + fi + if ! touched_by_patch $(patch_strip_level $patch) \ + $patch >> $tmpfile then return 1 fi - return 2 + sort $tmpfile | uniq > $pc_file + rm $tmpfile + return 0 fi } -directory_names() +diff_file() +{ + local file=$1 suffix=$2 old_file=$3 new_file=$4 + local old_file new_file + + if [ ! -e "$old_file" -a ! -e "$new_file" ] + then + echo "File $file does not exist" >&2 + return 0 + fi + local old_hdr new_hdr + if [ $opt_strip_level -eq 0 ] + then + old_hdr=$file$suffix + new_hdr=$file + else + local dir=$(basename $PWD) + old_hdr=$dir$suffix/$file + new_hdr=$dir/$file + fi + + echo Index: $new_hdr + diff -Nu $DIFF_OPTS $old_file $new_file | + fix_diff_header $old_hdr $new_hdr +} + +fix_diff_header() { - echo "$@" \ - | awk 'BEGIN {RS=" "} - {sub(/\/?[^\/]*$/, "") ; printf "[%s]\n", $0} - {if (last != $0) - print last - last = $0} - END {print last}' + local from=$1 to=$2 + sed -e 's:^--- [^ \t]*:--- '"$from"':' \ + -e 's:^+++ [^ \t]*:+++ '"$to"':' } -need_file_there() +cat_file() { - if [ ! -e $1 ] + local filename + + for filename in "$@" + do + if [ -e "$filename" ] + then + case "$filename" in + *.gz|*.tgz) + gzip -cd "$filename" ;; + *.bz2) + bzip2 -cd "$filename" ;; + *) + cat "$filename" ;; + esac + fi + done +} + +cat_to_file() +{ + local filename="$1" + + if [ -z "$filename" ] then - echo "File $1 does not exist" - exit 1 + cat + else + case "$filename" in + *.gz|*.tgz) + gzip -c > "$filename" ;; + *.bz2) + bzip2 -c > "$filename" ;; + *) + cat > "$filename" ;; + esac fi } @@ -384,10 +583,15 @@ patch_description() if [ -e "$patch_file" ] then - awk '/^--- / {exit} - diff {print diff ; diff=""} - /^diff / {diff=$0 ; next} - {print}' \ - $patch_file + awk ' + /^--- / { exit } + diff_line { print diff_line + diff_line="" + } + /^diff / { diff_line=$0 + next + } + { print } + ' $patch_file fi } |