quilt-dev
[Top][All Lists]
Advanced

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

[Quilt-dev] [patch 2/2] Add "commit" function.


From: hugo-qlt
Subject: [Quilt-dev] [patch 2/2] Add "commit" function.
Date: Thu, 26 Nov 2009 20:32:56 +0000
User-agent: quilt/0.48-1

It is useful to be able to hand off patches from the quilt stack to a
separate version control system. This new function does just that,
allowing patches that do not collide to be committed to a VCS, and
removed from the quilt stack.

Only subversion (and a "null", forgetful VCS) are implemented in this
version.

Signed-off-by: Hugo Mills <address@hidden>
Index: quilt/quilt/commit.in
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ quilt/quilt/commit.in       2009-11-26 20:23:17.000000000 +0000
@@ -0,0 +1,316 @@
+#! @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 $QUILT_DIR/scripts/patchfns ]
+       then
+               echo "Cannot read library $QUILT_DIR/scripts/patchfns" >&2
+               exit 1
+       fi
+       . $QUILT_DIR/scripts/patchfns
+fi
+
+setup_colors
+
+usage()
+{
+       printf $"Usage: quilt commit [-qv] 
[-s|--vcs={auto,svn,hg,git,null,forget}] [-A|--applied|from-patch [to-patch]]\n"
+       if [ x$1 = x-h ]
+       then
+               printf $"
+Commit patches to a version control system.  Without options, the
+current patch in the series file is applied, and then removed from the
+series.
+
+If neither [from-patch] nor [to-patch] is specified, commit the bottom
+patch on the stack.  If [from-patch] is specified, commit from the
+given patch to the current one.  If [to-patch] is specified, commit
+all patches from [from-patch] to [to-patch] inclusive.
+
+[from-patch] may be - for the first patch on the stack, or = for the
+current patch.  [to-patch] may be - for the last patch on the stack.
+
+-q     Quiet operation.
+
+-v     Verbose operation.
+
+-s, --vcs={auto,svn,hg,git,null,forget}
+       Use the given version control system. null and forget are
+       equivalent, and discard the patch from quilt, keeping the changes.
+
+-A, --applied
+       Commit all applied patches.  Equivalent to a range of - =
+"
+               exit 0
+       else
+               exit 1
+       fi
+}
+
+interrupt()
+{
+       rollback_patch $1
+       printf $"Interrupted by user; patch %s was not applied.\n" \
+              "$(print_patch $patch)" >&2
+       exit 1
+}
+
+all_paths()
+{
+       # Read a list of files from stdin, and generate all paths leading
+       # up to those
+       while read path
+       do
+               while [ -n "$path" ]
+               do
+                       echo $path
+                       newpath=${path%/*}
+                       if [ "$newpath" = "$path" ]
+                       then
+                               newpath=
+                       fi
+                       path="$newpath"
+               done
+       done
+}
+
+detect_vcs()
+{
+       # Determine the version control system in use in this source tree.
+       local found=0 vcs=""
+
+       if [ -d $QUILT_PC/../.svn ]
+       then
+               found=$(($found+1))
+               vcs="svn"
+       fi
+
+       if [ -d $QUILT_PC/../.git ]
+       then
+               found=$(($found+1))
+               vcs="git"
+       fi
+
+       if [ -d $QUILT_PC/../.hg ]
+       then
+               found=$(($found+1))
+               vcs="hg"
+       fi
+
+       if [ $found -gt 1 ]
+       then
+               echo "More than one VCS found: specify manually with --vcs" >&2
+               exit 1
+       fi
+
+       if [ $found -eq 0 ]
+       then
+               echo "No known VCS found: not supported?" >&2
+               exit 1
+       fi
+
+       echo $vcs
+}
+
+find_common_applied_files()
+{
+       # We can find all the files that are touched by some patch not
+       # this one by listing all of the unique files touched by the other
+       # patches, concatenating with all of the unique files touched by
+       # this patch, and finding duplicates.
+       local patch=$1
+       (
+               for other_patch in $(applied_patches)
+               do
+                       if [ "$other_patch" != "$patch" ]
+                       then
+                               files_in_patch $other_patch
+                       fi
+               done | sort | uniq ; \
+               files_in_patch $patch | sort | uniq
+       ) | sort | uniq -d
+}
+
+commit_patch()
+{
+       # Get the patch file
+       local patch=$1
+       local patch_file=$(patch_file_name $patch)
+
+       [ -e "$patch_file" ] || return 1
+
+       # Verify that this patch is applied
+       if ! is_applied "$patch"
+       then
+               quilt push "$patch"
+       fi
+
+       # Verify that the list of files in this patch is disjoint from the
+       # set of files in all the other currently-applied patches.
+       common_files=$(find_common_applied_files "$patch")
+       if [ -n "$common_files" ]
+       then
+               echo "Patch $patch is not independent of other applied 
patches." >&2
+               echo "Common files are:" >&2
+               echo $common_files >&2
+               return 1
+       fi
+
+       # Get the list of files to modify and check that they're all in our VCS
+       for file in $(files_in_patch $patch | all_paths | sort | uniq)
+       do
+               case "$use_vcs" in
+                       null|forget)
+                               echo "Adding file $file"
+                               ;;
+                       svn)
+                               if ! svn add -q $file
+                               then
+                                       echo "Failed to add $file to svn 
control" >&2
+                                       return 1
+                               fi
+                               ;;
+                       git)
+                               ;;
+                       hg)
+                               ;;
+                       *)
+                               echo "VCS '$vcs' not known" >&2
+                               return 1
+                               ;;
+               esac
+       done
+
+       # Check in the changes
+       case "$use_vcs" in
+               null|forget)
+                       echo "Committing: message is:"
+                       cat_file "$patch_file" | patch_header
+                       ;;
+               svn)
+                       if ! cat_file "$patch_file" \
+                               | patch_header \
+                               | svn ci -F - $(files_in_patch $patch)
+                       then
+                               return $?
+                       fi
+                       ;;
+               git)
+                       echo "git support not yet implemented" >&2
+                       ;;
+               hg)
+                       echo "mercurial support not yet implemented" >&2
+                       ;;
+       esac
+
+       # Remove the patch from the patch stack
+       remove_from_db "$patch" || return 1
+       rm -rf $QUILT_PC/$patch/
+       rm -f $QUILT_PC/$patch~refresh
+       rename_in_series "$patch" "# $patch" || return 1
+}
+
+options=`getopt -o qvhs:A --long vcs:,applied -- "$@"`
+
+if [ $? -ne 0 ]
+then
+        usage
+fi
+
+eval set -- "$options"
+
+while true
+do
+  case "$1" in
+         -q)
+                 opt_quiet=1
+                 shift ;;
+         -v)
+                 opt_verbose=1
+                 shift ;;
+         -s|--vcs)
+                 use_vcs=$2
+                 shift 2 ;;
+         -A|--applied)
+                 opt_applied=1
+                 shift ;;
+         -h)
+                 usage -h ;;
+         --)
+                 shift
+                 break ;;
+  esac
+done
+
+if [ $# -gt 2 -o \( -n "$opt_all" -a $# -ne 0 \) ]
+then
+       usage
+fi
+
+if [ -z "$use_vcs" -o "$use_vcs" = "auto" ]
+then
+       use_vcs=$(detect_vcs)
+fi
+
+if [ $# -ge 1 ]
+then
+       if [ $opt_applied -eq 1 ]
+       then
+               usage
+       fi
+       if [ "$1" = "-" ]
+       then
+               start_at_patch=$(find_first_patch) || exit 1
+       elif [ "$1" = "=" ]
+       then
+               start_at_patch=$(find_top_patch) || exit 1
+       else
+               start_at_patch=$(find_patch "$1") || exit 1
+       fi
+
+       if [ $# -eq 2 ]
+       then
+               if [ "$2" = "-" ]
+               then
+                       stop_at_patch=$(find_last_patch) || exit 1
+               else
+                       stop_at_patch=$(find_patch "$2") || exit 1
+               fi
+       else
+               stop_at_patch=$(find_top_patch) || exit 1
+       fi
+else
+       start_at_patch=$(find_first_patch) || exit 1
+       if [ $opt_applied -eq 1 ]
+       then
+               stop_at_patch=$(find_top_patch) || exit 1
+       else
+               stop_at_patch=$start_at_patch
+       fi
+fi
+
+[ -n "$opt_quiet" ] && silent=-s
+[ -z "$opt_verbose" ] && silent_unless_verbose=-s
+
+echo "Patches from $start_at_patch to $stop_at_patch"
+
+# Get the list of patches to apply (including current)
+patches=$(list_patch_range "$start_at_patch" "$stop_at_patch")
+echo $patches
+for patch in $patches
+do
+       [ -n "$opt_verbose" ] && echo "Processing patch $patch"
+       commit_patch "$patch" || exit 1
+done
+
+### Local Variables:
+### mode: shell-script
+### End:
+# vim:filetype=sh






reply via email to

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