When restoring all files, batch the first steps (directory creation
and target file removal) and last steps (optional touch and backup
file removal). This makes the typical restore case (quilt pop) much,
much faster.

Note: a similar optimization would be possible for the removal
function (-x), but quilt doesn't use this function at the moment.

Signed-off-by: Jean Delvare <[email protected]>
Reviewed-by: Raphael Hertzog <[email protected]>
---
 configure.ac                  |   39 +++++++++++++++++++++++++++++++++++++
 quilt/scripts/backup-files.in |   44 ++++++++++++++++++++++++++++++++++++++++++
 test/delete.test              |    2 -
 3 files changed, 84 insertions(+), 1 deletion(-)

--- a/quilt/scripts/backup-files.in
+++ b/quilt/scripts/backup-files.in
@@ -83,6 +83,26 @@ backup() {
        fi
 }
 
+# Same as restore, but assume that required directories are already
+# created, target files are already removed, and don't bother removing
+# the backup files or touching target files after restoration.
+restore_fast()
+{
+       local file="$1"
+       local backup="${OPT_PREFIX}${file}"
+
+       if [ ! -s "$backup" ]; then
+               $ECHO "Removing $file"
+       else
+               $ECHO "Restoring $file"
+               if [ -n "$OPT_NOLINKS" ]; then
+                       cp -p "$backup" "$file"
+               else
+                       ln "$backup" "$file" 2> /dev/null || cp -p "$backup" 
"$file"
+               fi
+       fi
+}
+
 restore()
 {
        local file="$1"
@@ -194,6 +214,19 @@ if [ -n "$OPT_FILE" ]; then
 fi
 
 if [ "$1" = - ]; then
+       if [ "$OPT_WHAT" = restore ]; then
+               OPT_WHAT=restore_fast
+
+               (cd "$OPT_PREFIX" && find . -type d -print0) \
+               | xargs -0 mkdir -p
+               if [ ${PIPESTATUS[0]} != 0 ]; then
+                       exit 1
+               fi
+
+               (cd "$OPT_PREFIX" && find . -type f -print0) \
+               | xargs -0 -r rm -f
+       fi
+
        find "$OPT_PREFIX" -type f -print \
        | while read
        do
@@ -202,6 +235,17 @@ if [ "$1" = - ]; then
        if [ ${PIPESTATUS[0]} != 0 ]; then
                exit 1
        fi
+
+       if [ "$OPT_WHAT" = restore_fast ]; then
+               if [ -n "$OPT_TOUCH" ]; then
+                       (cd "$OPT_PREFIX" && find . -type f -size +0 -print0) \
+                       | xargs -0 -r touch
+               fi
+
+               if [ -z "$OPT_KEEP_BACKUP" ]; then
+                       rm -rf "$OPT_PREFIX"
+               fi
+       fi
        exit
 fi
 
--- a/configure.ac
+++ b/configure.ac
@@ -305,8 +305,47 @@ does understand -path, you can supply it
 ])
 fi
 
+AC_MSG_CHECKING([whether $FIND -print0 works])
+if $FIND . -path '*' -print0 >/dev/null 2>&1; then
+       AC_MSG_RESULT(yes)
+else
+       AC_MSG_RESULT(no)
+       AC_MSG_ERROR([
+Sorry, you have a version of find which doesn't understand -print0.
+$PACKAGE_NAME needs it.  If you have access to a version of find which
+does understand -print0, you can supply its path with the
+'--with-find=' option.
+])
+fi
+
 QUILT_COMPAT_PROG_PATH(XARGS, xargs)
 
+AC_MSG_CHECKING([whether $XARGS -r works])
+if echo | $XARGS -r echo >/dev/null 2>&1; then
+       AC_MSG_RESULT(yes)
+else
+       AC_MSG_RESULT(no)
+       AC_MSG_ERROR([
+Sorry, you have a version of xargs which doesn't understand -r.
+$PACKAGE_NAME needs it.  If you have access to a version of xargs which
+does understand -r, you can supply its path with the
+'--with-xargs=' option.
+])
+fi
+
+AC_MSG_CHECKING([whether $XARGS -0 works])
+if echo | $XARGS -0 echo >/dev/null 2>&1; then
+       AC_MSG_RESULT(yes)
+else
+       AC_MSG_RESULT(no)
+       AC_MSG_ERROR([
+Sorry, you have a version of xargs which doesn't understand -0.
+$PACKAGE_NAME needs it.  If you have access to a version of xargs which
+does understand -0, you can supply its path with the
+'--with-xargs=' option.
+])
+fi
+
 QUILT_COMPAT_PROG_PATH_OPT(DIFFSTAT, diffstat)
 
 if test "$DIFFSTAT" != "diffstat"; then
--- a/test/delete.test
+++ b/test/delete.test
@@ -77,7 +77,7 @@ Test the delete command.
 
        $ quilt delete "test3"
        > Removing patch %{P}test3
-       >~ find: `?\.pc/test3/dir'?: Permission denied
+       >~ find: `?\./dir'?: Permission denied
 
        $ chmod a+rx .pc/test3/dir
 


_______________________________________________
Quilt-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/quilt-dev

Reply via email to