Index: lib/backup-files.c =================================================================== RCS file: /cvsroot/quilt/quilt/lib/backup-files.c,v retrieving revision 1.4 diff -u -r1.4 backup-files.c --- lib/backup-files.c 26 Oct 2003 23:26:40 -0000 1.4 +++ lib/backup-files.c 27 Oct 2003 01:50:57 -0000 @@ -99,7 +99,7 @@ } static int -link_or_copy(const char *from, const char *to) +link_or_copy(const char *from, struct stat *st, const char *to) { char buffer[4096]; int from_fd, to_fd, error = 1; @@ -117,7 +117,8 @@ perror(from); return 1; } - if ((to_fd = open(to, O_WRONLY|O_TRUNC))) { + unlink(to); /* make sure we don't inherit this file's mode. */ + if ((to_fd = creat(to, st->st_mode))) { perror(to); close(from_fd); return 1; @@ -168,7 +169,8 @@ if (!opt_silent) printf("New file %s\n", file); - if ((fd = creat(backup, 0666)) == -1) { + /* GNU patch creates new files with mode==0. */ + if ((fd = creat(backup, 0)) == -1) { perror(backup); return 1; } @@ -176,7 +178,7 @@ } else { if (!opt_silent) printf("Copying %s\n", file); - if (link_or_copy(file, backup) != 0) + if (link_or_copy(file, &st, backup) != 0) return 1; } return 0; @@ -192,8 +194,6 @@ if (unlink(file) == 0 || errno == ENOENT) { if (!opt_silent) printf("Removing %s\n", file); - unlink(backup); - remove_parents(backup); } else { perror(file); return 1; @@ -202,13 +202,20 @@ if (!opt_silent) printf("Restoring %s\n", file); unlink(file); - if (link_or_copy(backup, file) != 0) + if (link_or_copy(backup, &st, file) != 0) return 1; - unlink(backup); - remove_parents(backup); } + if (!(st.st_mode & S_IWUSR)) { + /* Change mode of backup file so that we + can later remove it. */ + chmod(backup, st.st_mode | S_IWUSR); + } + unlink(backup); + remove_parents(backup); return 0; } else if (opt_what == what_remove) { + /* Change mode of backup file so that we can remove it. */ + chmod(backup, S_IWUSR); unlink(backup); remove_parents(backup); return 0; @@ -216,7 +223,7 @@ return 1; } -int + int main(int argc, char *argv[]) { int opt, status=0; Index: po/de.po =================================================================== RCS file: /cvsroot/quilt/quilt/po/de.po,v retrieving revision 1.4 diff -u -r1.4 de.po --- po/de.po 25 Jun 2003 13:39:59 -0000 1.4 +++ po/de.po 27 Oct 2003 01:50:58 -0000 @@ -812,10 +812,6 @@ msgid "Patch file $patch_file appears to be empty" msgstr "Patch-Datei $patch_file scheint leer zu sein" -#: ../scripts/apatch.in:80 -msgid "refresh_file_list failed" -msgstr "Fehler in refresh_file_list" - #: ../scripts/apatch.in:84 msgid "Applying $patch" msgstr "Anwenden von $patch" Index: po/fr.po =================================================================== RCS file: /cvsroot/quilt/quilt/po/fr.po,v retrieving revision 1.5 diff -u -r1.5 fr.po --- po/fr.po 9 Sep 2003 06:52:45 -0000 1.5 +++ po/fr.po 27 Oct 2003 01:50:59 -0000 @@ -834,10 +834,6 @@ msgid "Patch file $patch_file appears to be empty" msgstr "Le fichier de patch $patch_file semble vide" -#: ../scripts/apatch.in:80 -msgid "refresh_file_list failed" -msgstr "refresh_file_list a échoué." - #: ../scripts/apatch.in:84 msgid "Applying $patch" msgstr "Application de $patch" Index: po/quilt.pot =================================================================== RCS file: /cvsroot/quilt/quilt/po/quilt.pot,v retrieving revision 1.8 diff -u -r1.8 quilt.pot --- po/quilt.pot 9 Sep 2003 06:55:15 -0000 1.8 +++ po/quilt.pot 27 Oct 2003 01:50:59 -0000 @@ -620,10 +620,6 @@ msgid "Patch file $patch_file appears to be empty" msgstr "" -#: ../scripts/apatch.in:80 -msgid "refresh_file_list failed" -msgstr "" - #: ../scripts/apatch.in:84 msgid "Applying $patch" msgstr "" Index: quilt/add.in =================================================================== RCS file: /cvsroot/quilt/quilt/quilt/add.in,v retrieving revision 1.12 diff -u -r1.12 add.in --- quilt/add.in 23 Oct 2003 23:07:03 -0000 1.12 +++ quilt/add.in 27 Oct 2003 01:50:59 -0000 @@ -98,8 +98,7 @@ continue fi - if ! @LIB@/backup-files -s -B .pc/$patch/ $file || \ - ! echo $file >> $(pc_file_name $patch) + if ! @LIB@/backup-files -s -B .pc/$patch/ $file then echo $"Failed to back up file $file" >&2 status=1 Index: quilt/diff.in =================================================================== RCS file: /cvsroot/quilt/quilt/quilt/diff.in,v retrieving revision 1.24 diff -u -r1.24 diff.in --- quilt/diff.in 26 Oct 2003 13:31:26 -0000 1.24 +++ quilt/diff.in 27 Oct 2003 01:50:59 -0000 @@ -223,7 +223,6 @@ if [ -n "$opt_relative" ] then patch_file=$(patch_file_name $last_patch) - pc_file=$(pc_file_name $last_patch) patch_args=$(patch_args $last_patch) workdir=$(gen_tempfile -d $PWD/quilt) pwd=$PWD @@ -238,6 +237,12 @@ echo $"Failed to copy files to temporary directory" die 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 '{}' ';' + if ! cd $workdir then echo $"Cannot change to temporary directory" @@ -255,7 +260,7 @@ # files won't succeed, either. So, ignore the error # in that particular case. - if ! [ -e $pwd/$pc_file~refresh ] + if ! [ -e $pwd/.pc/$last_patch~refresh ] then echo $"Failed to patch temporary files" die 1 Index: quilt/new.in =================================================================== RCS file: /cvsroot/quilt/quilt/quilt/new.in,v retrieving revision 1.9 diff -u -r1.9 new.in --- quilt/new.in 22 Mar 2003 11:34:14 -0000 1.9 +++ quilt/new.in 27 Oct 2003 01:51:00 -0000 @@ -68,8 +68,8 @@ exit 1 fi -mkdir -p $(dirname $(pc_file_name $patch)) -rm -f $(pc_file_name $patch) +rm -rf ".pc/$patch" +mkdir -p ".pc/$patch" if ! insert_in_series $patch_file || \ ! add_to_db $patch Index: quilt/refresh.in =================================================================== RCS file: /cvsroot/quilt/quilt/quilt/refresh.in,v retrieving revision 1.16 diff -u -r1.16 refresh.in --- quilt/refresh.in 16 Mar 2003 11:12:01 -0000 1.16 +++ quilt/refresh.in 27 Oct 2003 01:51:00 -0000 @@ -193,7 +193,7 @@ die 1 fi -rm -f $(pc_file_name $patch)~refresh +rm -f .pc/$patch~refresh echo $"Refreshed patch $patch" if ! change_db_strip_level -p$opt_strip_level $patch then Index: quilt/remove.in =================================================================== RCS file: /cvsroot/quilt/quilt/quilt/remove.in,v retrieving revision 1.11 diff -u -r1.11 remove.in --- quilt/remove.in 16 Feb 2003 20:32:43 -0000 1.11 +++ quilt/remove.in 27 Oct 2003 01:51:00 -0000 @@ -107,12 +107,6 @@ continue fi - pc_file=$(pc_file_name $patch) - tmpfile=$(gen_tempfile) - grep -v -E '^'"$(quote_re $file)"'$' $pc_file > $tmpfile - mv -f $tmpfile $pc_file - rm -f $tmpfile - echo $"File $file removed from patch $patch" done exit $status Index: quilt/snapshot.in =================================================================== RCS file: /cvsroot/quilt/quilt/quilt/snapshot.in,v retrieving revision 1.2 diff -u -r1.2 snapshot.in --- quilt/snapshot.in 26 Oct 2003 13:31:26 -0000 1.2 +++ quilt/snapshot.in 27 Oct 2003 01:51:00 -0000 @@ -63,11 +63,11 @@ usage fi -snap_dir=.pc/.snap +snap_subdir=.snap # Clean up from previous snapshot -rm -rf $snap_dir -mkdir -p $snap_dir +rm -rf .pc/$snap_subdir +mkdir -p .pc/$snap_subdir if [ -n "$opt_remove" ] then @@ -79,18 +79,24 @@ do for file in $(files_in_patch $patch) do - if ! [ -e "$snap_dir/$file" ] + if ! [ -e ".pc/$snap_subdir/$file" ] then - mkdir -p "$snap_dir/$(dirname $file)" + mkdir -p ".pc/$snap_subdir/$(dirname $file)" if [ -e "$file" ] then - ln "$file" "$snap_dir/$file" + ln "$file" ".pc/$snap_subdir/$file" else - touch "$snap_dir/$file" + touch ".pc/$snap_subdir/$file" fi fi done done + +# 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 .pc/$snap_subdir -type f -size 0 -exec rm '{}' ';' ### Local Variables: ### mode: shell-script Index: scripts/apatch.in =================================================================== RCS file: /cvsroot/quilt/quilt/scripts/apatch.in,v retrieving revision 1.6 diff -u -r1.6 apatch.in --- scripts/apatch.in 23 Apr 2003 13:53:35 -0000 1.6 +++ scripts/apatch.in 27 Oct 2003 01:51:00 -0000 @@ -25,13 +25,16 @@ rollback_patch() { - local patch=$1 pc_file=$(pc_file_name $patch) - @LIB@/backup-files $silent_unless_verbose \ - -f $pc_file -B .pc/$patch/ -r + local patch=$1 pc_file=$(gen_tempfile) + + # FIXME backup_files should scan the directory hierarchy itself. + files_in_patch $patch > $pc_file + @LIB@/backup-files $silent_unless_verbose -f $pc_file -B .pc/$patch/ -r if [ -z "$opt_leave_rejects" ] then - rm -f $(files_in_patch $patch | @SED@ -e 's/$/\.rej/') + @SED@ -e 's/$/\.rej/' $pc_file | xargs rm -f fi + rm -f $pc_file } interrupt() @@ -55,15 +58,15 @@ if [ "x${patch_file:(-3)}" = "x.gz" ] then gzip -cd $patch_file \ - | @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + | @PATCH@ $(patch_args $patch) --backup --prefix=".pc/$patch/" \ -E $silent $force_apply elif [ "x${patch_file:(-4)}" = "x.bz2" ] then bzip2 -cd $patch_file \ - | @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + | @PATCH@ $(patch_args $patch) --backup --prefix=".pc/$patch/" \ -E $silent $force_apply else - @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + @PATCH@ $(patch_args $patch) --backup --prefix=".pc/$patch/" \ -E $silent -i $patch_file $force_apply fi } @@ -71,39 +74,9 @@ apatch() { local patch=$(stripit $1) - local pc_file=$(pc_file_name $patch) local file status - trap "" SIGINT - if ! refresh_file_list $patch - then - echo $"refresh_file_list failed" - return 1 - fi - echo $"Applying $patch" - if ! [ -e $pc_file ] - then - echo $"Patch $patch appears to be empty, applied" - add_to_db $patch - return 0 - fi - - status=$? - if [ $status -eq 2 ] - then - [ -z "$opt_quiet" ] && echo $"Recreated file list for $patch" - elif [ $status -ne 0 ] - then - return 1 - fi - - if ! @LIB@/backup-files $silent_unless_verbose \ - -f $pc_file -B .pc/$patch/ - then - exit 1 - fi - trap "interrupt $patch" SIGINT apply_patch $patch @@ -111,18 +84,20 @@ trap "" SIGINT - # Remember date/time of applying so that pop can - # avoid reverse applying the patch in the usual cases. - touch $pc_file - if [ $status -eq 0 -o -n "$opt_force" ] then add_to_db $patch if [ $status -eq 0 ] then - rm -f $pc_file~refresh + rm -f .pc/$patch~refresh else - touch $pc_file~refresh + touch .pc/$patch~refresh + fi + if [ "$(shopt -s nullglob ; echo .pc/$patch/*)" = "" ] + then + echo $"Patch $patch appears to be empty, applied" + elif [ $status -ne 0 ] + then echo $"Applied $patch (forced; needs refresh)" fi else @@ -181,7 +156,7 @@ patch=$(stripit $1) top=$(top_patch) -if [ -n "$top" -a -e $(pc_file_name $top)~refresh ] +if [ -n "$top" -a -e .pc/$top~refresh ] then echo $"The topmost patch $top needs to be refreshed first." exit 1 Index: scripts/patchfns.in =================================================================== RCS file: /cvsroot/quilt/quilt/scripts/patchfns.in,v retrieving revision 1.24 diff -u -r1.24 patchfns.in --- scripts/patchfns.in 26 Oct 2003 16:36:55 -0000 1.24 +++ scripts/patchfns.in 27 Oct 2003 01:51:00 -0000 @@ -239,16 +239,6 @@ rm -f $tmpfile } -pc_file_name() -{ - while [ $# -gt 0 ] - do - echo ".pc/$1/.pc" - shift - done - -} - backup_file_name() { local patch=$1 @@ -362,10 +352,14 @@ if [ -n "$patches_on_top" ] then - grep -l -E "^$(quote_re $file)\$" \ - $(pc_file_name $patches_on_top) \ - | head -n 1 \ - | @SED@ -e 's:^\.pc/::' -e 's:/\.pc$::' + for patch in $patches_on_top + do + if [ -f $(backup_file_name $patch $file) ] + then + echo $patch + break + fi + done fi } @@ -402,16 +396,19 @@ file_in_patch() { local file=$1 patch=$2 - files_in_patch $patch \ - | grep -q -E "^$(quote_re $file)\$" + [ -f ".pc/$patch/$file" ] } files_in_patch() { - local pc_file=$(pc_file_name $1) - if [ -e "$pc_file" ] - then - cat $pc_file + local patch="$1" + local path=".pc/$patch" + if [ -d "$path" ] + then + for file in $(find "$path" -type f) + do + echo "${file:${#path}+1}" + done fi } @@ -428,47 +425,6 @@ sub(/^[^\/]*\//, "") print }' -} - -refresh_file_list() -{ - local patch=$1 - local pc_file=$(pc_file_name $patch) - local patch_file=$(patch_file_name $patch) - - if ! [ -e "$patch_file" ] - then - return 0 - fi - if [ ! -e $pc_file -o \ - $pc_file -ot $patch_file -o \ - $pc_file -ot $SERIES ] - then - local tmpfile status - if ! mkdir -p $(dirname $pc_file) || \ - ! tmpfile=$(gen_tempfile) - then - return 1 - fi - - # Do not reorder files in the file list... - - if [ -e $pc_file ] - then - cat $pc_file >> $tmpfile - fi - if ! touched_by_patch $(patch_strip_level $patch) \ - $patch >> $tmpfile - then - return 1 - fi - @AWK@ ' { if (seen[$0]) next - seen[$0]=1 - print - }' $tmpfile > $pc_file - rm $tmpfile - return 0 - fi } fix_diff_header() Index: scripts/rpatch.in =================================================================== RCS file: /cvsroot/quilt/quilt/scripts/rpatch.in,v retrieving revision 1.6 diff -u -r1.6 rpatch.in --- scripts/rpatch.in 16 May 2003 18:47:29 -0000 1.6 +++ scripts/rpatch.in 27 Oct 2003 01:51:00 -0000 @@ -57,16 +57,10 @@ { 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 + 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 @@ -89,10 +83,9 @@ 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/') + local patch=$1 pc_file=$2 + @LIB@/backup-files $silent_unless_verbose -f $pc_file -z ~rpatch -r + @SED@ -e 's/$/\.rej/' $pc_file | xargs rm -f } interrupt() @@ -117,24 +110,26 @@ if [ "x${patch_file:(-3)}" = "x.gz" ] then gzip -cd $patch_file \ - | @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + | @PATCH@ $(patch_args $patch) --backup --suffix="~rpatch" \ -R -E $silent elif [ "x${patch_file:(-4)}" = "x.bz2" ] then bzip2 -cd $patch_file \ - | @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + | @PATCH@ $(patch_args $patch) --backup --suffix="~rpatch" \ -R -E $silent else - @PATCH@ $(patch_args $patch) --no-backup-if-mismatch \ + @PATCH@ $(patch_args $patch) --backup --suffix="~rpatch" \ -R -E $silent -i $patch_file fi } rpatch() { - local patch=$1 pc_file=$(pc_file_name $patch) + local patch=$1 pc_file=$(gen_tempfile) - if ! [ -e $pc_file ] + # 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 @@ -153,19 +148,12 @@ @LIB@/backup-files $silent -f $pc_file -B .pc/$patch/ -r status=$? remove_from_db $patch - rm -f $pc_file~refresh + rm -f .pc/$patch~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 @@ -182,11 +170,12 @@ remove_from_db $patch else - rollback_patch $patch + rollback_patch $patch $pc_file echo $"Patch $patch does not remove (enforce with -f)" return 1 fi fi + rm -f $pc_file trap - SIGINT } @@ -233,7 +222,7 @@ [ -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 Index: test/one.test =================================================================== RCS file: /cvsroot/quilt/quilt/test/one.test,v retrieving revision 1.5 diff -u -r1.5 one.test --- test/one.test 9 Apr 2003 02:03:18 -0000 1.5 +++ test/one.test 27 Oct 2003 01:51:00 -0000 @@ -5,6 +5,8 @@ (To run, type `./run one.test' in this directory.) + $ mkdir d + $ cd d $ mkdir dir $ echo "This is file one." > dir/file1 $ quilt new patch1.diff @@ -27,18 +29,18 @@ $ echo "This is file two." > file2 $ quilt diff | sed -e "s/\\t.*//" - > Index: test/file2 + > Index: d/file2 > =================================================================== - > --- test.orig/file2 - > +++ test/file2 + > --- d.orig/file2 + > +++ d/file2 > @@ -0,0 +1 @@ > +This is file two. $ quilt diff -z | sed -e "s/\\t.*//" - > Index: test/file2 + > Index: d/file2 > =================================================================== - > --- test.orig/file2 - > +++ test/file2 + > --- d.orig/file2 + > +++ d/file2 > @@ -0,0 +1 @@ > +This is file two. @@ -48,10 +50,10 @@ $ quilt diff -z $ echo "Another line has been added." >> dir/file1 $ quilt diff -z | sed -e "s/\\t.*//" - > Index: test/dir/file1 + > Index: d/dir/file1 > =================================================================== - > --- test.orig/dir/file1 - > +++ test/dir/file1 + > --- d.orig/dir/file1 + > +++ d/dir/file1 > @@ -1 +1,2 @@ > This is file one. > +Another line has been added. @@ -99,10 +101,10 @@ $ rm file4 $ quilt diff | sed -e "s/\\t.*//" - > Index: test/file4 + > Index: d/file4 > =================================================================== - > --- test.orig/file4 - > +++ test/file4 + > --- d.orig/file4 + > +++ d/file4 > @@ -1 +0,0 @@ > -This is file 4. @@ -118,10 +120,10 @@ $ echo "Another line added." >> file2 $ quilt diff -z -P patch1 | sed -e "s/\\t.*//" - > Index: test/file2 + > Index: d/file2 > =================================================================== - > --- test.orig/file2 - > +++ test/file2 + > --- d.orig/file2 + > +++ d/file2 > @@ -1 +1,2 @@ > This is file two. > +Another line added. @@ -148,4 +150,5 @@ > Removing patch1 > No patches applied - $ rm -r dir patches + $ cd .. + $ rm -rf d