quilt-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Quilt-dev] [PATCH] quilt drop command


From: Josh Boyer
Subject: [Quilt-dev] [PATCH] quilt drop command
Date: Mon, 23 May 2005 20:52:42 -0500

Ok, I've updated the "commit" patch to add a 'quilt drop' command.  The
semantics are the same as before.  See example scenarios below.

If there are no objections, please consider applying this patch.
Otherwise, let me know and I'll fixup whatever needs fixing :).

thx,
josh


The patch below adds a 'quilt drop' command.  This command basically
something similar to a 'quilt pop', but without actually removing the
applied patch from the modified files.  It also removes the patch name
from the series file and cleans up the backup files in the .pc
directory.  It should leave the actual patch file in the patches
directory however, which is handy for those "oops, I screwed up"
moments.

Often times I find myself using quilt on a project that uses a CVS, SVN,
$SCM tree to manage multiple changes until I'm ready to actually commit
them to the repository.  When I'm ready to do a $SCM checkin, I do:

quilt refresh patch-name.patch
quilt pop patch-name.patch
patch -p1 < patches/patch-name.patch
$SCM ci

By adding a commit command, users can skip the manual steps and simply
do:

quilt commit patch-name.patch
$SCM ci

It also has the benefit of cleaning up the .pc directory for them.

----

 Makefile.in   |    2 
 quilt/drop.in |  293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 294 insertions(+), 1 deletion(-)

Index: quilt/quilt/drop.in
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ quilt/quilt/drop.in 2005-05-23 20:44:50.895156360 -0500
@@ -0,0 +1,293 @@
+#! @BASH@
+
+#  This script is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License version 2 as
+#  published by the Free Software Foundation.
+#
+#  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 ]
+       then
+               echo "Cannot read library @SCRIPTS@/patchfns" >&2
+               exit 1
+       fi
+       . @SCRIPTS@/patchfns
+fi
+
+usage()
+{
+       printf $"Usage: quilt drop [-afqv] [num|patch]\n"
+       if [ x$1 = x-h ]
+       then
+               printf $"
+Commit patch(es) from the stack of applied patches.  Without options,
+the topmost patch is dropped.  When a number is specified, drop the
+specified number of patches.  When a patch name is specified, drop
+patches until the specified patch end up on top of the stack.  Patch
+names may include the patches/ prefix, which means that filename
+completion can be used.
+
+-a     Commit all applied patches.
+
+-f     Force drop.
+
+-q     Quiet operation.
+
+-v     Verbose operation.
+"
+               exit 0
+       else
+               exit 1
+       fi
+}
+
+list_patches()
+{
+       local n=0 patch
+       applied_patches \
+       | tac \
+       | if [ -n "$opt_all" ]
+       then
+               cat
+       else
+               while read patch
+               do
+                       if [ -n "$number" ]
+                       then
+                               if [ $n -eq $number ]
+                               then
+                                       break
+                               fi
+                               n=$[$n+1]
+                       fi
+                       if [ $patch = "$stop_at_patch" ]
+                       then
+                               break
+                       fi
+                       echo $patch
+               done
+       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 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 $QUILT_PATCH_OPTS \
+                              $(patch_args $patch) \
+                              --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 file failed
+       for file2 in $(files_in_patch $patch)
+       do
+               file=$workdir/$file2
+               [ -e $file  ] || file=/dev/null
+               [ -e $file2 ] || file2=/dev/null
+               @DIFF@ -q $file $file2 > /dev/null || failed=1
+       done
+
+       if [ -n "$failed" ]
+       then
+               printf $"Patch %s does not drop cleanly (refresh it or enforce 
with -f)\n" \
+                      "$(print_patch $patch)" >&2
+               status=1
+       fi
+       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 $"Committing patch %s\n" "$(print_patch $patch)"
+               rm -f "$QUILT_PC/$patch/.timestamp"
+               @LIB@/backup-files $silent -x -B $QUILT_PC/$patch/ -
+               status=$?
+               remove_from_db $patch
+               remove_from_series $patch
+               rm -f $QUILT_PC/$patch~refresh
+       fi
+       trap - SIGINT
+       return $status
+}
+
+options=`getopt -o fqvah -- "$@"`
+
+if [ $? -ne 0 ]
+then
+        usage
+fi
+
+eval set -- "$options"
+
+while true
+do
+        case "$1" in
+    -f)
+                opt_force=1
+               unset opt_remove
+               shift ;;
+    -q)
+                opt_quiet=1
+               shift ;;
+    -v)
+                opt_verbose=1
+               shift ;;
+       -a)
+               opt_all=1
+               shift ;;
+       -h)
+               usage -h ;;
+    --)
+                shift
+               break ;;
+        esac
+done
+
+if [ $# -gt 1 -o \( -n "$opt_all" -a $# -ne 0 \) ]
+then
+        usage
+fi
+
+if [ $# -eq 1 ]
+then
+       if is_numeric $1
+       then
+               number=$1
+       else
+               if ! stop_at_patch=$(find_patch $1)
+               then
+                       printf $"Patch %s is not in series\n" "$1" >&2
+                       exit 1
+               fi
+       fi
+else
+       [ -n "$opt_all" ] || number=1
+fi
+
+[ -n "$opt_quiet" ] && silent=-s
+[ -z "$opt_verbose" ] && silent_unless_verbose=-s
+
+if [ -n "$stop_at_patch" ]
+then
+       if ! is_applied $stop_at_patch
+       then
+               printf $"Patch %s is not applied\n" "$(print_patch 
$stop_at_patch)" >&2
+               exit 1
+       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
+elif [ -z "$patches" ]
+then
+        printf $"No patch removed\n" >&2
+       exit 2
+fi
+
+for patch in $patches
+do
+       if ! remove_patch $patch
+       then
+               exit 1
+       fi
+       [ -z "$opt_quiet" ] && echo
+done
+
+patch="$(top_patch)"
+if [ -z "$patch" ]
+then
+       printf $"No patches applied\n"
+else
+       # Ensure that the files in the topmost patch have a link count
+       # of one: This will automatically be the case in the usual
+       # situations, but we don't want to risk file corruption in weird
+       # corner cases such as files added to a patch but not modified.
+       @LIB@/backup-files -L -s -B $QUILT_PC/$patch/ -
+       printf $"Now at patch %s\n" "$(print_patch $patch)"
+fi
+### Local Variables:
+### mode: shell-script
+### End:
+# vim:filetype=sh
Index: quilt/Makefile.in
===================================================================
--- quilt.orig/Makefile.in      2005-05-23 20:43:45.926033168 -0500
+++ quilt/Makefile.in   2005-05-23 20:46:08.469363288 -0500
@@ -56,7 +56,7 @@ BIN :=                $(BIN_IN)
 SRC +=         $(BIN_SRC:%=bin/%)
 DIRT +=                $(BIN_IN:%=bin/%)
 
-QUILT_IN :=    add applied delete diff edit files fold fork graph grep \
+QUILT_IN :=    add applied delete diff drop edit files fold fork graph grep \
                import mail new next patches pop previous push refresh remove \
                series setup snapshot top unapplied upgrade
 






reply via email to

[Prev in Thread] Current Thread [Next in Thread]