diff options
Diffstat (limited to 'quilt/pop.in')
-rw-r--r-- | quilt/pop.in | 137 |
1 files changed, 119 insertions, 18 deletions
diff --git a/quilt/pop.in b/quilt/pop.in index 6f8562c..4e807b1 100644 --- a/quilt/pop.in +++ b/quilt/pop.in @@ -76,6 +76,114 @@ list_patches() fi } +files_may_have_changed() +{ + local patch=$1 file + local patch_file=$(patch_file_name $patch) + + if [ $? -ne 0 -o ! -e "$patch_file" \ + -o ! -e "$QUILT_PC/$patch/.timestamp" \ + -o "$QUILT_PC/$patch/.timestamp" -ot "$patch_file" ] + then + return 0 + fi + + local apply_ts=$(date -r "$QUILT_PC/$patch/.timestamp" '+%s') ts + for file in $(files_in_patch $patch) + do + ts=$(date -r $file '+%s' 2> /dev/null) + [ -z "$ts" ] && return 0 + [ "$ts" -gt $apply_ts ] && return 0 + done + return 1 +} + +# 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_file=$(patch_file_name $patch) + local patch_args=$(patch_args $patch) + local workdir=$(gen_tempfile -d quilt) status=0 + + if [ -d $QUILT_PC/$patch ] + then + if ! rmdir $workdir || # note that this is racey... + ! cp -rl $QUILT_PC/$patch $workdir/ + then + printf $"Failed to copy files to temporary directory\n" >&2 + 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 [ -s $patch_file ] + then + if ! cat_file $patch_file \ + | @PATCH@ -d $workdir $patch_args \ + --no-backup-if-mismatch -E \ + >/dev/null 2>/dev/null + then + if ! [ -e $QUILT_PC/$patch ] + then + printf $"Failed to patch temporary files\n" >&2 + rm -rf $workdir + return 1 + fi + fi + fi + + local remains=$(gen_tempfile) + for file in $(files_in_patch $patch) + do + diff_file $file $workdir/$file $file >> $remains + done + + if [ -s $remains ] + then + printf $"Patch %s does not remove cleanly (refresh it or enforce with -f)\n" \ + "$(print_patch $patch)" >&2 + status=1 + fi + rm -f $remains + rm -rf $workdir + + return $status +} + +remove_patch() +{ + local patch=$1 status=0 + + trap "status=1" SIGINT + if [ -z "$opt_force" ] && \ + ( [ -n "$opt_remove" ] || files_may_have_changed $patch ) + then + check_for_pending_changes $patch || status=1 + fi + + if [ $status -eq 0 ] + then + printf $"Removing patch %s\n" "$(print_patch $patch)" + rm -f "$QUILT_PC/$patch/.timestamp" + @LIB@/backup-files $silent -r -t -B $QUILT_PC/$patch/ - + status=$? + remove_from_db $patch + rm -f $QUILT_PC/$patch~refresh + fi + trap - SIGINT + return $status +} + options=`getopt -o fRqvah -- "$@"` if [ $? -ne 0 ] @@ -134,14 +242,8 @@ else [ -n "$opt_all" ] || number=1 fi -[ -n "$opt_force" ] && - rpatch_options="$rpatch_options -f" -[ -n "$opt_remove" ] && - rpatch_options="$rpatch_options -R" -[ -n "$opt_quiet" ] && - rpatch_options="$rpatch_options -q" -[ -n "$opt_verbose" ] && - rpatch_options="$rpatch_options -v" +[ -n "$opt_quiet" ] && silent=-s +[ -z "$opt_verbose" ] && silent_unless_verbose=-s if [ -n "$stop_at_patch" ] then @@ -152,6 +254,14 @@ then fi fi +top=$(top_patch) +if [ -n "$top" -a -e $QUILT_PC/$top~refresh -a -z "$opt_force" ] +then + printf $"Patch %s needs to be refreshed first.\n" \ + "$(print_patch $top)" >&2 + exit 1 +fi + if ! patches=$(list_patches) 2>&1 then exit 1 @@ -161,19 +271,10 @@ then exit 2 fi -trap "interrupted=1" SIGINT - for patch in $patches do - [ -n "$SUBDIR" ] && pushd $SUBDIR > /dev/null - if ! @SCRIPTS@/rpatch $rpatch_options $patch - then - exit 1 - fi - [ -n "$SUBDIR" ] && popd > /dev/null - if [ -n "$interrupted" ] + if ! remove_patch $patch then - printf $"Interrupted by user\n" >&2 exit 1 fi [ -z "$opt_quiet" ] && echo |