summaryrefslogtreecommitdiffstats
path: root/scripts/rpatch.in
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/rpatch.in')
-rwxr-xr-xscripts/rpatch.in234
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