diff options
Diffstat (limited to 'scripts/rpatch.in')
-rwxr-xr-x | scripts/rpatch.in | 234 |
1 files changed, 97 insertions, 137 deletions
diff --git a/scripts/rpatch.in b/scripts/rpatch.in index 0dd7a72..cccd741 100755 --- a/scripts/rpatch.in +++ b/scripts/rpatch.in @@ -6,6 +6,7 @@ # # 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 ] @@ -22,71 +23,18 @@ usage() 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 - - if [ -z $patch_file ] - then - echo "Waring: Can not find the $patch in your series file, the series file may changed" - return 0 #can not find the patch in series - fi - local apply_ts=$(date -r $pc_file '+%s') ts - for file in $(files_in_patch $patch) - do - if ! [ -e .pc/$patch/$file ] - then - echo "Warning: the backup files .pc/$patch/$file do not exist" - echo "Check your backup files in .pc/$patch" - echo "If pop did not success, please touch a empty .pc/$patch/$file and try again" - touch .pc/$patch/$file - return 1 # backup files is missing, we can not remove it with force - fi - done + local apply_ts=$(date -r ".pc/$patch" '+%s') ts - if [ -e "$patch_file" -a $pc_file -ot "$patch_file" ] + + if [ -e "$patch_file" -a ".pc/$patch" -ot "$patch_file" ] then return 0 fi - for file in $(files_in_patch $patch) do if ! [ -e $file ] @@ -99,113 +47,125 @@ files_may_have_changed() 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 +return 1 } -reverse_patch() +# Check if all changes have been folded back into the patch (quilt refresh), +# and report any pending changes. +check_for_pending_changes() { - local patch=$1 + local patch=$1 pc_file=$2 local patch_file=$(patch_file_name $patch) + local patch_args=$(patch_args $patch) + local workdir=$(gen_tempfile -d quilt) status=0 - if ! [ -s $patch_file ] + if [ -d .pc/$patch ] then - echo $"Patch file $patch_file appears to be empty" - return 0 + if ! rmdir $workdir || # note that this is racey... + ! cp -rl .pc/$patch $workdir/ + then + echo $"Failed to copy files to temporary directory" + rm -rf $workdir + return 1 + fi + + # Now we may have some zero-size files that have no + # permissions (which represent files that the patch + # creates). Those may have been created in the meantime, + # but patch would refuse to touch them: We must remove + # them here. + find $workdir -type f -size 0 -exec rm -f '{}' ';' + fi - if [ "x${patch_file:(-3)}" = "x.gz" ] + if [ -s $patch_file ] then - gzip -cd $patch_file \ - | @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ - -R -E $silent - elif [ "x${patch_file:(-4)}" = "x.bz2" ] + if ! cat_file $patch_file \ + | @PATCH@ -d $workdir $patch_args \ + --no-backup-if-mismatch -E \ + >/dev/null 2>/dev/null + then + # If a patch was force applied (and therefore needs + # refreshing), we know that patching the temporary + # files won't succeed, either. So, ignore the error + # in that particular case. + + if ! [ -e .pc/$patch ] + then + echo $"Failed to patch temporary files" + rm -rf $workdir + return 1 + fi + fi + fi + + local remains=$(gen_tempfile) + while read file + do + diff_file $file $workdir/$file $file >> $remains + done < $pc_file + + if [ -s $remains ] 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 + echo $"Patch $patch does not remove cleanly (enforce with -f)." + status=1 fi + rm -f $remains + rm -rf $workdir + + return $status } rpatch() { - local patch=$1 pc_file=$(pc_file_name $patch) - if ! [ -e $pc_file ] + local patch=$1 pc_file=$(gen_tempfile) status=0 + + # FIXME backup-files should scan the directory tree itself. + files_in_patch $patch > $pc_file + if ! [ -s $pc_file ] then echo $"Patch $patch appears to be empty, removed" remove_from_db $patch return 0 fi - echo $"Removing $patch" trap "" SIGINT - - files_may_have_changed $patch - patch_may_changed=$? - - if [ "$opt_force" -eq 1 ] || \ - ( [ "$opt_remove" -eq 0 ] && [ $patch_may_changed -eq 0 ] ) + if [ -z "$opt_force" ] then - # Optimize: Force remove if the patch has not been - # modified since it was applied. (Forced remove is - # faster!) + for file in $(touched_by_patch $(patch_strip_level $patch) $patch) + do + if ! [ -e ".pc/$patch/$file" ] + then + echo "$file touched by $patch_file" + echo "but no backup files for $file" + echo "Please Make sure your $patch_file is right" + echo "otherwise, quilt push $patch will be failed" + echo "Please quilt pop with -f option" + echo "Suggestion: If you have done make distclean" + echo "in kernel src, it will delete 0 size file" + echo "Maybe you should delete those new created files" + return 0 + fi + done + fi + if [ -z "$opt_force" ] && \ + ( [ -n "$opt_remove" ] || files_may_have_changed $patch ) + then + check_for_pending_changes $patch $pc_file || status=1 + fi + + if [ $status -eq 0 ] + then + echo $"Removing $patch" @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 + rm -f .pc/$patch~refresh fi + rm -f $pc_file trap - SIGINT + return $status } options=`getopt -o fRqvh -- "$@"` @@ -214,8 +174,8 @@ if [ $? -ne 0 ] then usage fi -opt_force=0 -opt_remove=0 +#opt_force=0 +#opt_remove=0 eval set -- "$options" while true @@ -252,7 +212,7 @@ patch=$(stripit $1) [ -z "$opt_verbose" ] && silent_unless_verbose=-s top=$(top_patch) -if [ -n "$top" -a -e $(pc_file_name $top)~refresh -a -z "$opt_force" ] +if [ -n "$top" -a -e .pc/$top~refresh -a -z "$opt_force" ] then echo $"The topmost patch $top needs to be refreshed first." exit 1 |