{"thread":{"id":"7043","subject":"[PATCH 0/8] My set of stgit helper scripts (update)","startedAt":"2007-03-01T23:03:34Z","lastAt":"2007-03-01T23:04:15Z","messageCount":9,"participants":["Yann Dirson"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"36022","messageId":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":null,"subject":"[PATCH 0/8] My set of stgit helper scripts (update)","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:03:34Z","receivedAt":"2007-03-01T23:03:34Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"These are updated versions of the scripts already posted.  Minor\nupdates for most (notably some compatibility with 0.12), except for\nstg-cvs which got a number of fixes, as well as a huge enumeration of\nlimitations (I'll probably rewrite it as a glue to get tailor called\nfrom standard stgit commands).\n\nThis brings 2 new scripts:\n\n- stg-mdiff to display diffs of diffs (very preliminar and naive\nimplementation, needs much work)\n\n- sit-sink to bury one or more patch down the stack (eg. to commit\nthem but keep other patches under stgit control).  Catalin will love\nto learn that this is a perl script ;).  I'll rewrite it as a standard\nstgit command soon (with a slight difference as to how the --to\nargument is interpreted), but others may want to use it or just\ncomment before that.\n\nBest regards,\n-- \nYann Dirson    <ydirson@altern.org> |\nDebian-related: <dirson@debian.org> |   Support Debian GNU/Linux:\n                                    |  Freedom, Power, Stability, Gratis\n     http://ydirson.free.fr/        | Check <http://www.debian.org/>\n"},{"id":"36023","messageId":"20070301230339.32459.18579.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","subject":"[PATCH 1/8] Add contrib/stg-whatchanged: look at what would be changed by refreshing.","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:03:40Z","receivedAt":"2007-03-01T23:03:40Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\nThis script outputs a \"metadiff\" (diff of diffs, ie. diff between 2\nversions of a single patch).  This is somewhat a proof of concept, and some\nwork is indeed needed in the way to present the results.  Consider\nfiltering the output at least through colordiff.\n\nI have 2 uses for this script:\n- when simply editing a patch, provides a 3rd way to check what I've done\n  before refreshing (in addition to \"stg diff\" and \"stg diff -r //bottom\")\n- most usefully, when resolving conflicts caused by a push, to ease\n  checking of the merge result.\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n contrib/stg-whatchanged |   37 +++++++++++++++++++++++++++++++++++++\n 1 files changed, 37 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/stg-whatchanged b/contrib/stg-whatchanged\nnew file mode 100755\nindex 0000000..f80d0a1\n--- /dev/null\n+++ b/contrib/stg-whatchanged\n@@ -0,0 +1,37 @@\n+#!/bin/bash\n+set -e\n+\n+# stg-whatchanged - show a metadiff for the patch being modified,\n+# especially when resolving a merge.\n+\n+# Copyright (c) 2006-2007 Yann Dirson <ydirson@altern.org>\n+# Subject to the GNU GPL, version 2.\n+\n+# FIXME:\n+# - should only exclude hunk headers differing only in line offsets\n+# - diff coloring should show changes in context lines differently than\n+#   changes in contents\n+# - filter on ^index lines is a bit wide\n+# - we should be able to ask diff to force a new hunk on \"^@@ \" to better\n+#   handle them\n+# - we should always show the hunk header for any changes within a hunk\n+\n+# default to unified diff\n+if [ \"$#\" = 0 ]; then\n+    set -- -u\n+fi\n+\n+# Merges via \"push\" leave top=bottom so we must look at old patch\n+# in this case (unlike, eg., \"pick --fold\")\n+patchdir=\"$(git-rev-parse --git-dir)/patches/$(stg branch)/$(stg top)\"\n+if [ $(cat \"$patchdir/bottom\") = $(cat \"$patchdir/top\") ];\n+then\n+    current_cmd=\"stg show //top.old\"\n+else\n+    current_cmd=\"stg show\"\n+fi\n+\n+colordiff \"$@\" \\\n+    -I '^index [0-9a-b]*..[0-9a-b]*' \\\n+    -I '^@@ .* @@' \\\n+    <($current_cmd) <(stg diff -r//bottom) | less -RFX\n"},{"id":"36024","messageId":"20070301230345.32459.79608.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","subject":"[PATCH 2/8] Add contrib/stg-show-old: show old version of a patch.","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:03:45Z","receivedAt":"2007-03-01T23:03:45Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\n\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n contrib/stg-show-old |   13 +++++++++++++\n 1 files changed, 13 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/stg-show-old b/contrib/stg-show-old\nnew file mode 100755\nindex 0000000..acf4e7c\n--- /dev/null\n+++ b/contrib/stg-show-old\n@@ -0,0 +1,13 @@\n+#!/bin/sh\n+set -e\n+\n+# stg-show-old - mini helper to look at the previous version of a\n+# patch (current one by default)\n+\n+# Copyright (c) 2006-2007 Yann Dirson <ydirson@altern.org>\n+# Subject to the GNU GPL, version 2.\n+\n+[ \"$#\" -le 1 ] || { echo >&2 \"Usage: $(basename $0) [<patch>]\"; exit 1; }\n+patch=\"$1\"\n+\n+stg show \"${patch}//top.old\"\n"},{"id":"36025","messageId":"20070301230350.32459.10496.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","subject":"[PATCH 3/8] Add contrib/stg-fold-files-from: pick selected changes from a patch above current one","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:03:50Z","receivedAt":"2007-03-01T23:03:50Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\n\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n contrib/stg-fold-files-from |   31 +++++++++++++++++++++++++++++++\n 1 files changed, 31 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/stg-fold-files-from b/contrib/stg-fold-files-from\nnew file mode 100755\nindex 0000000..bfb4a1f\n--- /dev/null\n+++ b/contrib/stg-fold-files-from\n@@ -0,0 +1,31 @@\n+#!/bin/sh\n+set -e\n+\n+# stg-fold-files-from - picks changes to one file from another patch.\n+# Only supports picking from one file, but allows to select any range\n+# of hunks from the file, using the -# flag to filterdiff.\n+# Use together with \"filterdiff --annotate\" in your diff pager, to\n+# identify hunk numbers easily.\n+\n+# usage: stg-fold-files-from <patch> [-#<n>[-<n>][,<n>]...] <file>\n+\n+# Copyright (c) 2006-2007 Yann Dirson <ydirson@altern.org>\n+# Subject to the GNU GPL, version 2.\n+\n+PATCH=\"$1\"\n+shift\n+\n+filtercmd=cat\n+hunks=\n+foldflags=\n+while [ \"$#\" -gt 0 ]; do\n+    case \"$1\" in\n+\t-\\#*) hunks=\"$1\"; shift ;;\n+\t-t) foldflags=\"-t\"; shift ;;\n+\t-*) { echo >&2 \"unknown flag '$1'\"; exit 1; } ;;\n+\t*) break ;;\n+    esac\n+done\n+[ \"$#\" = 1 ] || { echo >&2 \"supports one file only\"; exit 1; }\n+\n+stg show \"$PATCH\" | filterdiff -p1 $hunks -i \"$1\" | stg fold $foldflags\n"},{"id":"36026","messageId":"20070301230355.32459.76241.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","subject":"[PATCH 4/8] Add contrib/stg-swallow: completely merge an unapplied patch into current one","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:03:55Z","receivedAt":"2007-03-01T23:03:55Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\n\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n contrib/stg-swallow |   19 +++++++++++++++++++\n 1 files changed, 19 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/stg-swallow b/contrib/stg-swallow\nnew file mode 100755\nindex 0000000..5014f39\n--- /dev/null\n+++ b/contrib/stg-swallow\n@@ -0,0 +1,19 @@\n+#!/bin/sh\n+set -e\n+\n+# stg-swallow - completely merge an unapplied patch into current one\n+\n+# Copyright (c) 2006-2007 Yann Dirson <ydirson@altern.org>\n+# Subject to the GNU GPL, version 2.\n+\n+# FIXME:\n+# - should provide support for conflict solving ?\n+\n+[ \"$#\" = 1 ] || { echo >&2 \"Usage: $(basename $0) <patch>\"; exit 1; }\n+patch=\"$1\"\n+\n+stg pick --fold \"$patch\"\n+stg refresh\n+stg push \"$patch\"\n+#stg clean \"$patch\"\n+stg pop; stg clean -u\n"},{"id":"36027","messageId":"20070301230400.32459.69204.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","subject":"[PATCH 5/8] Add contrib/stg-cvs: helper script to manage a mixed cvs/stgit working copy","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:04:00Z","receivedAt":"2007-03-01T23:04:00Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\nThis is an early prototype only, use with care, and be sure to read the\nLIMITATIONS section in the script comments.\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n contrib/stg-cvs |  171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 171 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/stg-cvs b/contrib/stg-cvs\nnew file mode 100755\nindex 0000000..7b968d6\n--- /dev/null\n+++ b/contrib/stg-cvs\n@@ -0,0 +1,171 @@\n+#!/bin/bash\n+set -e\n+\n+# stg-cvs - helper script to manage a mixed cvs/stgit working copy.\n+\n+# Allows quick synchronization of a cvs mirror branch (does not try to\n+# reconstruct patchsets, creates \"jumbo\" commits), and commits stgit\n+# patches to CVS.\n+\n+# Copyright (c) 2007 Yann Dirson <ydirson@altern.org>\n+# Subject to the GNU GPL, version 2.\n+\n+# NOTES\n+# - you want to add a \"CVS\" line to .git/info/exclude\n+# - you may want to add a \".git\" line to the top .cvsignore\n+\n+# LIMITATIONS\n+# - this is only a proof-of-concept prototype\n+# - lacks an \"init\" command\n+# - \"commit\" does not ensure the base is uptodate before trying to\n+#   commit (but hey, it's CVS ;)\n+# - \"commit\" can only commit a single patch\n+# - not much robustness here\n+# - still bad support for files removed in cvs (should catch \"no\n+#   longer in the repository\" message)\n+# - while fetching, if a file change was not git-update-index'd when\n+#   cvs-update'd (eg. because of a stg-cvs bug), it is not seen on further\n+#   fetches until it changes again, since we scan \"cvs update\" output.\n+#   This yields possible inconsistencies with CVS.\n+# - similarly, any conflict while cvs-updating (whether due to illegal\n+#   changes to the cvs-mirror-branch, or due to files added to cvs but\n+#   already-existing in working copy, or to directory moves inside the\n+#   cvs repository, or <fill here>) has to be dealt with by hand (although\n+#   the situation is better here: cvs sees the conflict on subsequent tries)\n+# - this only deals with CVS but could surely be extended to any other\n+#   VCS\n+# - bad/no support for cvsutils:\n+#   - stg push/pop operations confuse cvsu because of timestamp changes\n+#   - cvspurge/cvsco would nuke .git => does not make it easy to ensure\n+#     synchronisation\n+# - should use a separate workspace for cvs branch like tailor does\n+# - lacks synchronisation of .cvsignore <-> .gitignore\n+# - no support for filenames with spaces (stg lacks --zero output format)\n+# - git-commit is too chatty when it finds nothing to commit\n+# - lacks a \"quick cvs commit\" feature\n+# - confused by cvs keyword substitution\n+\n+usage()\n+{\n+    [ \"$#\" = 0 ] || echo \"ERROR: $*\"\n+    echo \"Usage: $(basename $0) <command>\"\n+    echo \" commands: $(do_commands)\"\n+    exit 1\n+}\n+\n+do_commands()\n+{\n+    echo $(grep '^[a-z-]*)' $0 | cut -d')' -f1)\n+}\n+\n+do_fetch()\n+{\n+    local return=0\n+    local path\n+\n+    local parent=\"$1\"\n+    local branch=\"$2\"\n+\n+    # record changes from cvs into index\n+    stg branch \"$parent\" || exit $?\n+    cvs -fq update -dP | grep -v '^\\? ' | tee /dev/tty | while read status path; do\n+\tif [ -e \"$path\" ]; then\n+\t    git update-index --add \"$path\" || exit $?\n+\telse\n+\t    git update-index --remove \"$path\" || exit $?\n+\tfi\n+\t# cvs update: `FELIN1_PEP/src/java/com/sagem/felin/ui/widget/PEPRifStateIcon.java' is no longer in the repository\n+    done\n+\n+    # create commit\n+    if git commit -m \"stg-cvs sync\"; then\n+\t:\n+    else\n+\treturn=$?\n+    fi\n+\n+    # back to branch\n+    stg branch \"$branch\" || exit $?\n+\n+    return $return\n+}\n+\n+cvs_add_dir()\n+{\n+    local parent=$(dirname \"$1\")\n+    if [ ! -e \"$parent/CVS\" ]; then\n+\tcvs_add_dir \"$parent\"\n+    fi\n+\n+    cvs add \"$1\"\n+}\n+\n+# get context\n+branch=$(stg branch)\n+parent=$(git-repo-config \"branch.${branch}.merge\") || \n+    usage \"no declared parent for '$branch' - set branch.${branch}.merge\"\n+\n+# extract command\n+\n+[ \"$#\" -ge 1 ] || usage\n+command=\"$1\"\n+shift\n+\n+case \"$command\" in\n+fetch)\n+    do_fetch \"$parent\" \"$branch\"\n+    ;;\n+\n+pull)\n+    if do_fetch \"$parent\" \"$branch\"; then\n+\t# update\n+\t#  --merged\n+\tstg rebase \"$parent\"\n+\tstg clean --applied\n+    fi\n+    ;;\n+\n+commit)\n+    # sanity asserts\n+    [ $(stg applied | wc -l) = 1 ] ||\n+\tusage \"you don't have exactly one patch applied\"\n+\n+    # context\n+    patch=$(stg top)\n+    \n+    # adds\n+    stg files | grep ^A | cut -c3- | while read file; do\n+\tparent=$(dirname \"$file\")\n+\tif [ ! -e \"$parent/CVS\" ]; then\n+\t    cvs_add_dir \"$parent\"\n+\tfi\n+\tcvs -f add \"$file\"\n+    done\n+\n+    # removes\n+    stg files | grep ^D | cut -c3- | xargs -r cvs -f remove\n+\n+    # commit\n+    stg files --bare | xargs -r cvs -fq commit \\\n+\t-F \".git/patches/$branch/patches/$patch/description\"\n+\n+    # sync the parent branch\n+    stg branch \"$parent\"\n+    git-cherry-pick \"patches/${branch}/${patch}\"\n+    stg branch \"${branch}\"\n+\n+    # update\n+    # --merged\n+    stg rebase \"$parent\"\n+    stg clean --applied\n+    ;;\n+\n+_commands)\n+    # hint for bash-completion people :)\n+    do_commands\n+    ;;\n+\n+*)\n+    usage \"unknown command '$command'\"\n+    ;;\n+esac\n"},{"id":"36029","messageId":"20070301230405.32459.73120.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","subject":"[PATCH 6/8] Add contrib/stg-gitk: helper script to run gitk","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:04:05Z","receivedAt":"2007-03-01T23:04:05Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\n\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n contrib/stg-gitk |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 61 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/stg-gitk b/contrib/stg-gitk\nnew file mode 100755\nindex 0000000..dd01ef0\n--- /dev/null\n+++ b/contrib/stg-gitk\n@@ -0,0 +1,61 @@\n+#!/bin/sh\n+set -e\n+\n+# stg-gitk - helper script to graphically display an StGIT stack\n+\n+# Displays given branches and stacks, without getting disturbed by\n+# patch logs.\n+\n+# LIMITATIONS:\n+# - asking gitk to \"update\" won't detect any new ref\n+# - no support for spaces in branch names\n+\n+# Copyright (c) 2007 Yann Dirson <ydirson@altern.org>\n+# Subject to the GNU GPL, version 2.\n+\n+usage()\n+{\n+    echo \"Usage: $(basename $0) [<branches>|--all]\"\n+    exit 1\n+}\n+\n+allbranches=0\n+case \"$1\" in\n+--all) allbranches=1; shift ;;\n+--*) usage ;;\n+*) break ;;\n+esac\n+\n+if [ $allbranches = 1 ] && [ \"$#\" -gt 0 ]; then\n+    usage\n+fi\n+\n+GIT_DIR=$(git-rev-parse --git-dir)\n+GIT_DIR_SPKIPLEN=$(printf \"$GIT_DIR/X\" | wc -c)\n+\n+refdirs=''\n+if [ $allbranches = 1 ]; then\n+    refdirs=\"$GIT_DIR/refs\"\n+else\n+    if [ \"$#\" = 0 ]; then\n+\tset -- \"$(stg branch)\"\n+    fi\n+\n+    for b in \"$@\"; do\n+\tif [ -e \"$GIT_DIR/refs/patches/$b\" ]; then\n+\t    # StGIT branch: show all patches\n+\t    refdirs=\"$refdirs $GIT_DIR/refs/heads/$b $GIT_DIR/refs/patches/$b\"\n+\telif [ -e \"$GIT_DIR/refs/heads/$b\" ]; then\n+\t    # other GIT branch\n+\t    refdirs=\"$refdirs $GIT_DIR/refs/heads/$b\"\n+\telif [ $(git-for-each-ref \"refs/$b\" | wc -l) != 0 ]; then\n+\t    # other ref\n+\t    refdirs=\"$refdirs $(git-for-each-ref --format=\"$GIT_DIR/%(refname)\" \"refs/$b\")\"\n+\telse\n+\t    echo >&2 \"ERROR: no such ref '$b'\"\n+\t    usage\n+\tfi\n+    done\n+fi\n+\n+gitk $(find $refdirs -type f -not -name '*.log' | cut -c${GIT_DIR_SPKIPLEN}- )\n"},{"id":"36028","messageId":"20070301230410.32459.93054.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","subject":"[PATCH 7/8] Add contrib/stg-mdiff: display diffs of diffs.","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:04:10Z","receivedAt":"2007-03-01T23:04:10Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\n\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n contrib/stg-mdiff |   23 +++++++++++++++++++++++\n 1 files changed, 23 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/stg-mdiff b/contrib/stg-mdiff\nnew file mode 100755\nindex 0000000..cd0c678\n--- /dev/null\n+++ b/contrib/stg-mdiff\n@@ -0,0 +1,23 @@\n+#!/bin/bash\n+set -e\n+\n+# stg-mdiff - display meta-diffs, ie. diffs of diffs\n+\n+# Main use: show evolutions of a patch.\n+# eg. stg-mdiff foo@stable foo\n+#     stg-mdiff foo 012345567ABCD # sha1 for \"foo\" as integrated upstream\n+\n+# Copyright (c) 2007 Yann Dirson <ydirson@altern.org>\n+# Subject to the GNU GPL, version 2.\n+\n+usage()\n+{\n+    echo \"Usage: $(basename $0) <patch1> <patch2>\"\n+    exit 1\n+}\n+\n+if [ \"$#\" != 2 ]; then\n+    usage\n+fi\n+\n+colordiff -u <(stg show \"$1\") <(stg show \"$2\") | less -RFX\n"},{"id":"36030","messageId":"20070301230415.32459.45545.stgit@gandelf.nowhere.earth","threadId":"7043","inReplyTo":"20070301225651.32459.89156.stgit@gandelf.nowhere.earth","subject":"[PATCH 8/8] Add contrib/stg-sink: sink a patch to given location (mirrors float).","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2007-03-01T23:04:15Z","receivedAt":"2007-03-01T23:04:15Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\n\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n contrib/stg-sink |   44 ++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 44 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/stg-sink b/contrib/stg-sink\nnew file mode 100755\nindex 0000000..e63eb93\n--- /dev/null\n+++ b/contrib/stg-sink\n@@ -0,0 +1,44 @@\n+#!/usr/bin/perl\n+use strict;\n+use warnings;\n+\n+sub _run {\n+  print(' >> ', @_, \"\\n\");# and 0;\n+  system(@_);\n+}\n+\n+my $dopush=1;\n+my $pop='pop -a';\n+while (@ARGV and $ARGV[0] =~ m/^-/) {\n+  if ($ARGV[0] eq '-n') {\n+    $dopush=0;\n+    shift @ARGV;\n+  }\n+  if ($ARGV[0] eq '-t') {\n+    shift @ARGV;\n+    $pop = 'goto '.shift @ARGV;\n+  }\n+}\n+\n+# default: sink current patch\n+if (@ARGV == 0) {\n+  $ARGV[0] = `stg top`;\n+}\n+\n+my @oldapplied=`stg applied`;\n+chomp (@oldapplied);\n+\n+_run('stg '.$pop) &&\n+  die \"cannot pop all patches\";\n+_run('stg push ' . join (' ', @ARGV)) &&\n+  die \"error pushing patches\";\n+\n+if ($dopush) {\n+  my @newapplied=`stg applied`;\n+  chomp (@newapplied);\n+  my @remaining=grep { my $check=$_;\n+\t\t       not grep { $check eq $_ } @newapplied;\n+\t\t     } @oldapplied;\n+  _run('stg push ' . join (' ', @remaining)) &&\n+    die \"error pushing remaining patches\";\n+}\n"}]}