blob: 286ccd7d74ea8e660a625c3dd51ee6d7766af08b (
plain) (
tree)
|
|
#! @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.
# Read in library functions
if [ "$(type -t patch_file_name)" != function ]
then
if ! [ -r @SCRIPTS@/patchfns ]
then
echo "Cannot read library @SCRIPTS@/patchfns" >&2
exit 1
fi
. @SCRIPTS@/patchfns
fi
usage()
{
echo $"Usage: $0 [-fRq] patchname"
exit 1
}
verify_removal()
{
local patch=$1
local bup file status=0
local dir=$(basename $PWD) suffix=${patch//\//_}
# Check if all changes of the patch are undone
for file in $(files_in_patch $patch)
do
bup=$(backup_file_name $patch $file)
if ! [ -s $file -o -s $bup ] || \
cmp $file $bup > /dev/null 2> /dev/null
then
continue
fi
if [ $status -eq 0 ]
then
echo $"Patch does not remove changes:"
fi
@DIFF@ -Nu $QUILT_DIFF_OPTS $bup $file \
| @SED@ -e 's:^--- [^ '$'\t'']*:--- '"$dir/$file.orig"':' \
-e 's:^+++ [^ '$'\t'']*:+++ '"$dir/$file"':'
status=1
done
return $status
}
files_may_have_changed()
{
local patch=$1 file
local patch_file=$(patch_file_name $patch)
local pc_file=$(pc_file_name $patch)
if ! [ -e $pc_file ]
then
return 1
fi
local apply_ts=$(date -r $pc_file '+%s') ts
if [ -e "$patch_file" -a $pc_file -ot "$patch_file" ]
then
return 0
fi
for file in $(files_in_patch $patch)
do
if ! [ -e $file ]
then
return 0 # file is missing
fi
ts=$(date -r $file '+%s')
if [ $? -ne 0 -o $ts -gt $apply_ts ]
then
return 0 # file has changed
fi
done
return 1
}
rollback_patch()
{
local patch=$1 pc_file=$(pc_file_name $patch)
@LIB@/backup-files $silent_unless_verbose \
-f $pc_file -z ~rpatch -r
rm -f $(files_in_patch $patch | @SED@ -e 's/$/\.rej/')
}
interrupt()
{
local patch=$1
rollback_patch $patch
echo $"Interrupted by user; patch $patch was not removed."
exit 1
}
reverse_patch()
{
local patch=$1
local patch_file=$(patch_file_name $patch)
if ! [ -s $patch_file ]
then
echo $"Patch file $patch_file appears to be empty"
return 0
fi
if [ "x${patch_file:(-3)}" = "x.gz" ]
then
gzip -cd $patch_file \
| @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \
-R -E $silent
elif [ "x${patch_file:(-4)}" = "x.bz2" ]
then
bzip2 -cd $patch_file \
| @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \
-R -E $silent
else
@PATCH@ $(patch_args $patch) --no-backup-if-mismatch \
-R -E $silent -i $patch_file
fi
}
rpatch()
{
local patch=$1 pc_file=$(pc_file_name $patch)
if ! [ -e $pc_file ]
then
echo $"Patch $patch appears to be empty, removed"
remove_from_db $patch
return 0
fi
echo $"Removing $patch"
trap "" SIGINT
if [ -n "$opt_force" ] || \
( [ -z "$opt_remove" ] && ! files_may_have_changed $patch )
then
# Optimize: Force remove if the patch has not been
# modified since it was applied. (Forced remove is
# faster!)
@LIB@/backup-files $silent -f $pc_file -B .pc/$patch/ -r
status=$?
remove_from_db $patch
rm -f $pc_file~refresh
if [ $status != 0 ]
then
exit $status
fi
else
if ! @LIB@/backup-files $silent_unless_verbose \
-f $pc_file -z ~rpatch
then
echo $"Failed to create temporary files" >&2
return 1
fi
trap "interrupt $patch" SIGINT
reverse_patch $patch
status=$?
trap "" SIGINT
if [ $status -eq 0 ] && verify_removal $patch
then
@LIB@/backup-files $silent_unless_verbose \
-f $pc_file -z ~rpatch -x
@LIB@/backup-files $silent_unless_verbose \
-f $pc_file -B .pc/$patch/ -x
remove_from_db $patch
else
rollback_patch $patch
echo $"Patch $patch does not remove (enforce with -f)"
return 1
fi
fi
trap - SIGINT
}
options=`getopt -o fRqvh -- "$@"`
if [ $? -ne 0 ]
then
usage
fi
eval set -- "$options"
while true
do
case "$1" in
-f)
opt_force=1
shift ;;
-R)
opt_remove=1 # remove properly with patch -R; no tricks
unset opt_force
shift ;;
-q)
opt_quiet=1
shift ;;
-v)
opt_verbose=1
shift ;;
-h)
usage -h ;;
--)
shift
break ;;
esac
done
if [ $# -ne 1 ]
then
usage
fi
patch=$(stripit $1)
[ -n "$opt_quiet" ] && silent=-s
[ -z "$opt_verbose" ] && silent_unless_verbose=-s
top=$(top_patch)
if [ -n "$top" -a -e $(pc_file_name $top)~refresh -a -z "$opt_force" ]
then
echo $"The topmost patch $top needs to be refreshed first."
exit 1
fi
rpatch "$patch" || exit 1
### Local Variables:
### mode: shell-script
### End:
# vim:filetype=sh
|