{"thread":{"id":"9321","subject":"[GUILT PATCH 1/5] get_series: Remove comments from end of series lines","startedAt":"2007-07-31T03:11:16Z","lastAt":"2007-08-09T13:47:15Z","messageCount":16,"participants":["Eric Lesh","Josef Sipek","David Kastrup","Thomas Adam"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"49186","messageId":"1185851481190-git-send-email-eclesh@ucla.edu","threadId":"9321","inReplyTo":null,"subject":"[GUILT PATCH v2 0/5] Add guards to guilt","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-31T03:11:16Z","receivedAt":"2007-07-31T03:11:16Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"\nChanges in v2\n        - get_series returns guarded series, get_full_series gives\n          full series.  Most commands want the guarded series anyway.\n        - more options for guilt-select (better hg compatability)\n        - rename guilt-guards to guilt-guard (better hg compatability)\n        - a couple bug fixes\n        - an extra patch that adds a test suite\n\nThis series adds Mercurial Queues-like guards to guilt.  It allows you\nto assign guards to related patches in the series file to selectively\npush patches.\n\nSee Chapter 13 of the HG Book for more info.\n(http://hgbook.red-bean.com/hgbookch13.html)\n\nGuards are appended as \"#+foo\" or \"#-foo\" to the end of the patch name\nin the series file, so they are compatible with quilt. The\nguard setting and unsetting functions also respect comments on the\npatch line, so they aren't mangled when you use guards.\n\nThis changes `get_series` to return the guarded series of patches that\nwill be actually be applied.  `get_full_series` returns the full\nseries file.\n\nIf you change guards on a patch or select a different guard while\npatches are applied, some commands might get confused.  See\n`guilt-select --pop` and `guilt-select --reapply` to avoid having to\n`guilt-pop -a` yourself.\n\nI did everything (maybe?) you suggested except implement a\nsafe_sed wrapper and a validate_guards function.  The sed stuff is\nmaybe better for a later patch that covers most sed usage in guilt,\nand the validate_guards isn't really necessary given the small number\nof times it's called.  If you would prefer either of those to get\ndone, let me know.\n\n[PATCH 1/5] get_series: Remove comments from end of series lines\n       This just strips everything but the patch name from get_series,\n       to hide comments or guards on the line.\n\n[PATCH 2/5] guilt-guard: Assign guards to patches in series\n       This adds the guilt-guard command and utility functions to\n       guilt.  Introduces get_guarded_series, which is removed in\n       patch 4.\n\n[PATCH 3/5] guilt-select: Select guards to apply when pushing patches\n       This puts selected guards in .git/patch/$branch/guards, and\n       adds a $guards_file variable to guilt.\n\n[PATCH 4/5] get_series: return guarded patches only\n       Actually distinguish between guarded and non-guarded patches in\n       a number of commands by making get_series return the guarded\n       series, and introducing get_full_series to return the unguarded\n       series.  Lots of changes.\n       If anything breaks, it's in this patch.  Hopefully.\n\n[PATCH 5/5] Guards test suite\n       Test stuff that uses get_series or get_full_series.\n"},{"id":"49181","messageId":"11858514812742-git-send-email-eclesh@ucla.edu","threadId":"9321","inReplyTo":"1185851481190-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 1/5] get_series: Remove comments from end of series lines","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-31T03:11:17Z","receivedAt":"2007-07-31T03:11:17Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"Also make sure that series_remove_patch and series_rename_patch do the\nright thing if there are comments on the line.\n\nSigned-off-by: Eric Lesh <eclesh@ucla.edu>\n---\n guilt                    |   15 ++++++++++++---\n regression/050-series.sh |    2 +-\n 2 files changed, 13 insertions(+), 4 deletions(-)\n\ndiff --git a/guilt b/guilt\nindex 7f2b93c..700c167 100755\n--- a/guilt\n+++ b/guilt\n@@ -178,7 +178,13 @@ get_series()\n \t#\t- whitespace only\n \t#\t- optional whitespace followed by '#' followed by more\n \t#\t  optional whitespace\n-\tgrep -ve '^[[:space:]]*\\(#.*\\)*$' \"$series\"\n+\t# also remove comments from end of lines\n+\tsed -n -e \"/^[[:space:]]*\\(#.*\\)*\\$/ ! {\n+\t\ts/[[:space:]]*#.*\\$//\n+\n+\t\tp\n+\t\t}\n+\t\t\" $series\n }\n \n # usage: do_make_header <hash>\n@@ -290,14 +296,17 @@ series_insert_patch()\n # usage: series_remove_patch <patchname>\n series_remove_patch()\n {\n-\tgrep -v \"^$1\\$\" < \"$series\" > \"$series.tmp\"\n+\tgrep -v \"^$1[[:space:]]*#*\" < \"$series\" > \"$series.tmp\"\n \tmv \"$series.tmp\" \"$series\"\n }\n \n # usage: series_rename_patch <oldname> <newname>\n series_rename_patch()\n {\n-\tawk -v old=\"$1\" -v new=\"$2\" \\\n+\t# Rename the patch, but preserve comments on the line\n+\told=$(grep -e \"^$1[[:space:]]*\" $series)\n+\tnew=$(echo \"$old\" | sed -e \"s,^$1,$2,\")\n+\tawk -v old=\"$old\" -v new=\"$new\" \\\n \t\t'{ if ($0 == old) print new; else print $0 }' \\\n \t\t\"$series\" > \"$series.tmp\"\n \ndiff --git a/regression/050-series.sh b/regression/050-series.sh\nindex eb23540..4c47e9d 100755\n--- a/regression/050-series.sh\n+++ b/regression/050-series.sh\n@@ -26,7 +26,7 @@ modify\n add\n \n remove\n-mode\n+mode # and text\n #sure\n DONE\n }\n-- \n1.5.2\n"},{"id":"49184","messageId":"1185851481271-git-send-email-eclesh@ucla.edu","threadId":"9321","inReplyTo":"1185851481190-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-31T03:11:18Z","receivedAt":"2007-07-31T03:11:18Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"guilt-guard will assign guards to a patch.  They work so that:\n\n    * Patches with no guards are always pushed.\n\n    * Patches with positive guards (i.e. +foo) are pushed *only if* the\n      guard is selected.\n\n    * Patches with negative guards (i.e. -foo) are pushed *unless* the\n      guard is selected.\n\nThis also introduces a number of guard-related utility functions into\nguilt.  get_guarded_series is used to get the list of patches that are\napplicable given the current guard status.  It replaces get_series in\na later patch.\n\nSigned-off-by: Eric Lesh <eclesh@ucla.edu>\n---\n Documentation/guilt-guard.txt |   40 +++++++++++++++++++++++\n guilt                         |   66 +++++++++++++++++++++++++++++++++++++++\n guilt-guard                   |   69 +++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 175 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/guilt-guard.txt\n create mode 100755 guilt-guard\n\ndiff --git a/Documentation/guilt-guard.txt b/Documentation/guilt-guard.txt\nnew file mode 100644\nindex 0000000..6290bf7\n--- /dev/null\n+++ b/Documentation/guilt-guard.txt\n@@ -0,0 +1,40 @@\n+guilt-guard(1)\n+===============\n+\n+NAME\n+----\n+guilt-guard - Assign guards to patches\n+\n+SYNOPSIS\n+--------\n+include::usage-guilt-guard.txt[]\n+\n+DESCRIPTION\n+-----------\n+Assign guards to the specified patch, or to the patch on top of the\n+stack if no patch is given on the command line.\n+\n+An unguarded patch is always pushed.\n+\n+A positive guard begins with a +. A patch with a positive guard is\n+pushed *only if* the guard is selected.\n+\n+A negative guard begins with a -. A patch with a negative guard is\n+always pushed, *unless* the guard is selected.\n+\n+OPTIONS\n+-------\n+-l|--list::\n+        List all patches and their guards\n+-n|--none::\n+        Remove all guards from a patch\n+\n+Author\n+------\n+Written by Eric Lesh <eclesh@ucla.edu>\n+\n+Documentation\n+-------------\n+Documentation by Eric Lesh <eclesh@ucla.edu>\n+\n+include::footer.txt[]\ndiff --git a/guilt b/guilt\nindex 700c167..6af590c 100755\n--- a/guilt\n+++ b/guilt\n@@ -187,6 +187,72 @@ get_series()\n \t\t\" $series\n }\n \n+get_guarded_series()\n+{\n+\tget_series | while read p\n+\tdo\n+\t\tcheck_guards \"$p\" && echo \"$p\"\n+\tdone\n+}\n+\n+# usage: check_guards <patch>\n+# Returns 0 if the patch should be pushed\n+check_guards()\n+{\n+\tget_guards \"$1\" | while read guard\n+\tdo\n+\t\tpos=`printf %s $guard | grep -e \"^+\"`\n+\t\tguard=`printf %s $guard | sed -e 's/^[+-]//'`\n+\t\tif [ \"$pos\" ]; then\n+\t\t\t# Push +guard *only if* guard selected\n+\t\t\tpush=`grep -e \"^$guard\\$\" \"$guards_file\" >/dev/null 2>/dev/null; echo $?`\n+\t\t\t[ $push -ne 0 ] && return 1\n+\t\telse\n+\t\t\t# Push -guard *unless* guard selected\n+\t\t\tpush=`grep -e \"^$guard\\$\" \"$guards_file\" >/dev/null 2>/dev/null; echo $?`\n+\t\t\t[ $push -eq 0 ] && return 1\n+\t\tfi\n+\t\treturn 0\n+\tdone\n+\treturn $?\n+}\n+\n+# usage: get_guards <patch>\n+get_guards()\n+{\n+\tsed -n -e \"\\,^$1[[:space:]]*#, {\n+\t\ts,^$1[[:space:]]*,,\n+\t\ts,#[^+-]*,,g\n+\n+\t\tp\n+\t\t}\n+\t\t\" $series\n+}\n+\n+# usage: set_guards <patch> <guards...>\n+set_guards()\n+{\n+\tp=\"$1\"\n+\tshift\n+\tfor x in \"$@\"; do\n+\t\tif [ -z $(printf %s \"$x\" | grep -e \"^[+-]\") ]; then\n+\t\t\techo \"'$x' is not a valid guard name\"\n+\t\telse\n+\t\t\tsed -i -e \"s,^\\($p[[:space:]]*.*\\)$,\\1 #$x,\" \"$series\"\n+\t\tfi\n+\tdone\n+}\n+\n+# usage: unset_guards <patch> <guards...>\n+unset_guards()\n+{\n+\tp=\"$1\"\n+\tshift\n+\tfor x in \"$@\"; do\n+\t\tsed -i -e \"/^$p[[:space:]]/s/ #$x//\" \"$series\"\n+\tdone\n+}\n+\n # usage: do_make_header <hash>\n do_make_header()\n {\ndiff --git a/guilt-guard b/guilt-guard\nnew file mode 100755\nindex 0000000..a0cac2e\n--- /dev/null\n+++ b/guilt-guard\n@@ -0,0 +1,69 @@\n+#!/bin/sh\n+#\n+# Copyright (c) Eric Lesh, 2007\n+#\n+\n+USAGE=\"[-l|--list|-n|--none|[<patchname>] [(+|-)<guard>...]]\"\n+. `dirname $0`/guilt\n+\n+print_guards()\n+{\n+\tguards=`get_guards \"$1\"`\n+\techo \"$1: $guards\"\n+}\n+\n+if [ \"$1\" == \"-l\" ] || [ \"$1\" == \"--list\" ]; then\n+\tget_series | while read patch; do\n+\t\tprint_guards \"$patch\"\n+\tdone\n+\texit 0\n+elif [ \"$1\" == \"-n\" ] || [ \"$1\" == \"--none\" ]; then\n+\tpatch=\"$2\"\n+\tif [ -z \"$patch\" ]; then\n+\t\tpatch=`get_top`\n+\tfi\n+\tunset_guards \"$patch\" `get_guards \"$patch\"`\n+\texit 0\n+fi\n+\n+case $# in\n+\t0)\n+\t\tif [ ! -s \"$applied\" ]; then\n+\t\t\tdie \"No patches applied.\"\n+\t\tfi\n+\t\tprint_guards `get_top`\n+\t\t;;\n+\t1)\n+\t\tif [ -z $(printf %s \"$1\" | grep -e '^[+-]') ]; then\n+\t\t\tif [ -z $(get_series | grep -e \"^$1\\$\") ]; then\n+\t\t\t\tdie \"Patch $1 does not exist.\"\n+\t\t\telse\n+\t\t\t\tprint_guards \"$1\"\n+\t\t\tfi\n+\t\telse\n+\t\t\tpatch=`get_top`\n+\t\t\tif [ -z \"$patch\" ]; then\n+\t\t\t\tdie \"You must specify a patch.\"\n+\t\t\tfi\n+\t\t\tunset_guards \"$patch\" `get_guards \"$patch\"`\n+\t\t\tset_guards \"$patch\" \"$1\"\n+\t\tfi\n+\t\t;;\n+\t*)\n+\t\tif [ -z $(printf %s \"$1\" | grep -e '^[+-]') ]; then\n+\t\t\tif [ -z $(get_series | grep -e \"^$1\\$\") ]; then\n+\t\t\t\tdie \"Patch $1 does not exist.\"\n+\t\t\telse\n+\t\t\t\tpatch=\"$1\"\n+\t\t\tfi\n+\t\t\tshift\n+\t\telse\n+\t\t\tpatch=`get_top`\n+\t\t\tif [ -z \"$patch\" ]; then\n+\t\t\t\tdie \"You must specify a patch.\"\n+\t\t\tfi\n+\t\tfi\n+\t\tunset_guards \"$patch\" `get_guards \"$patch\"`\n+\t\tset_guards \"$patch\" \"$@\"\n+\t\t;;\n+esac\n-- \n1.5.2\n"},{"id":"49183","messageId":"11858514811245-git-send-email-eclesh@ucla.edu","threadId":"9321","inReplyTo":"1185851481190-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 3/5] guilt-select: Select guards to apply when pushing patches","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-31T03:11:19Z","receivedAt":"2007-07-31T03:11:19Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"guilt-select chooses guards that alter which patches will be applied\nwith a guilt-push.  The selected guards are stored in\n.git/patches/$branch/guards.\n\nSigned-off-by: Eric Lesh <eclesh@ucla.edu>\n---\n Documentation/guilt-select.txt |   47 ++++++++++++++++++++++++++++++++++++\n Documentation/guilt.txt        |    5 +++-\n guilt                          |    1 +\n guilt-select                   |   52 ++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 104 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/guilt-select.txt\n create mode 100755 guilt-select\n\ndiff --git a/Documentation/guilt-select.txt b/Documentation/guilt-select.txt\nnew file mode 100644\nindex 0000000..12f19b4\n--- /dev/null\n+++ b/Documentation/guilt-select.txt\n@@ -0,0 +1,47 @@\n+guilt-select(1)\n+===============\n+\n+NAME\n+----\n+guilt-select - Select guards to apply when pushing patches\n+\n+SYNOPSIS\n+--------\n+include::usage-guilt-select.txt[]\n+\n+DESCRIPTION\n+-----------\n+Select guards to apply when pushing patches.\n+\n+Guards are selected without the + or - prefix.  Patches are applied in\n+the following way:\n+\n+* An unguarded patch is always applied.\n+\n+* A patch with a positive guard is applied *only* if the guard is\n+selected with guilt-select.\n+\n+* A patch with a negative guard is applied *unless* the guard is\n+selected with guilt-select.\n+\n+OPTIONS\n+-------\n+-n|--none::\n+        Remove all selected guards\n+--pop::\n+        Pop back to the first guarded patch\n+--reapply::\n+        Pop back to first guarded patch, select a new guard, and\n+        push\n+-s|--series::\n+        List all guards listed in the series file\n+\n+Author\n+------\n+Written by Eric Lesh <eclesh@ucla.edu>\n+\n+Documentation\n+-------------\n+Documentation by Eric Lesh <eclesh@ucla.edu>\n+\n+include::footer.txt[]\ndiff --git a/Documentation/guilt.txt b/Documentation/guilt.txt\nindex 31dbc0e..11c2ca9 100644\n--- a/Documentation/guilt.txt\n+++ b/Documentation/guilt.txt\n@@ -33,7 +33,10 @@ PATCHES DIRECTORY\n In Guilt, all the patches are stored in .git/patches/$branch/, where $branch\n is the name of the branch being worked on. This means that one can have a\n independent series of patches for each branch present in the repository.\n-Each of these per-branch directories contains 2 special files:\n+Each of these per-branch directories contains 3 special files:\n+\n+guards: This file contains any guards that should be applied to the\n+series when pushing. It is only present when guards are selected.\n \n series: This file contains a list of all the patch filenames relative to the\n per-branch patch directory. Empty and commented out lines are ignored.\ndiff --git a/guilt b/guilt\nindex 6af590c..b289026 100755\n--- a/guilt\n+++ b/guilt\n@@ -666,6 +666,7 @@ fi\n # very useful files\n series=\"$GUILT_DIR/$branch/series\"\n applied=\"$GUILT_DIR/$branch/status\"\n+guards_file=\"$GUILT_DIR/$branch/guards\"\n \n # determine an editor to use for anything interactive (fall back to vi)\n editor=\"vi\"\ndiff --git a/guilt-select b/guilt-select\nnew file mode 100755\nindex 0000000..378ca98\n--- /dev/null\n+++ b/guilt-select\n@@ -0,0 +1,52 @@\n+#!/bin/sh\n+#\n+# Copyright (c) Eric Lesh, 2007\n+#\n+\n+USAGE=\"[-n|--none|-s|--series|[--pop|--reapply] <guards...>]\"\n+. `dirname $0`/guilt\n+\n+select_guards()\n+{\n+\tfor x in \"$@\"; do\n+\t\tif [ $(printf %s \"$x\" | grep -e \"^[+-]\") ]; then\n+\t\t\tdie \"'$x' cannot begin with + or -.\"\n+\t\tfi\n+\tdone\n+\techo \"$@\" | sed -e 's/ /\\n/g' | sort | uniq > \"$guards_file\"\n+}\n+\n+if [ $# == 0 ]; then\n+\tif [ -s \"$guards_file\" ]; then\n+\t\tcat \"$guards_file\"\n+\telse\n+\t\techo >&2 \"No guards applied\"\n+\tfi\n+\texit 0\n+fi\n+\n+case $1 in\n+\t-n|--none)\n+\t\trm -f \"$guards_file\"\n+\t\t;;\n+\t--pop)\n+\t\tguilt-pop -a\n+\t\tshift\n+\t\tselect_guards \"$@\"\n+\t\t;;\n+\t--reapply)\n+\t\ttop=`get_top`\n+\t\tguilt-pop -a\n+\t\tshift\n+\t\tselect_guards \"$@\"\n+\t\tguilt-push \"$top\"\n+\t\t;;\n+\t-s|--series)\n+\t\t(get_series | while read patch; do\n+\t\t\tget_guards \"$patch\"\n+\t\tdone) | sed -e 's/ /\\n/g' | sort | uniq\n+\t\t;;\n+\t*)\n+\t\tselect_guards \"$@\"\n+\t\t;;\n+esac\n-- \n1.5.2\n"},{"id":"49182","messageId":"11858514813702-git-send-email-eclesh@ucla.edu","threadId":"9321","inReplyTo":"1185851481190-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 4/5] get_series: return guarded patches only","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-31T03:11:20Z","receivedAt":"2007-07-31T03:11:20Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"This renames get_guarded_series to get_series, and introduces\nget_full_series for when the full series is needed.  Many guilt\nscripts Just Work with that change.  Those that don't are fixed up.\n\nWith this patch, guards are respected everywhere in guilt.\n\nSigned-off-by: Eric Lesh <eclesh@ucla.edu>\n---\n guilt        |    6 +++---\n guilt-export |    2 +-\n guilt-guard  |    6 +++---\n guilt-header |    4 ++--\n guilt-push   |    4 ++--\n guilt-select |    2 +-\n guilt-series |    6 ++++--\n 7 files changed, 16 insertions(+), 14 deletions(-)\n\ndiff --git a/guilt b/guilt\nindex b289026..d618980 100755\n--- a/guilt\n+++ b/guilt\n@@ -171,7 +171,7 @@ get_prev()\n \tfi\n }\n \n-get_series()\n+get_full_series()\n {\n \t# ignore all lines matching:\n \t#\t- empty lines\n@@ -187,9 +187,9 @@ get_series()\n \t\t\" $series\n }\n \n-get_guarded_series()\n+get_series()\n {\n-\tget_series | while read p\n+\tget_full_series | while read p\n \tdo\n \t\tcheck_guards \"$p\" && echo \"$p\"\n \tdone\ndiff --git a/guilt-export b/guilt-export\nindex 2c0a9fd..c872d7f 100755\n--- a/guilt-export\n+++ b/guilt-export\n@@ -18,7 +18,7 @@ fi\n trap \"rm -rf \\\"$target_dir\\\"\" 0\n mkdir -p \"$target_dir\"\n \n-get_series | tee \"$target_dir/series\" | while read p; do\n+get_full_series | tee \"$target_dir/series\" | while read p; do\n \tsilent mkdir -p \"`dirname $target_dir/$p`\" || true\n \tcp \"$GUILT_DIR/$branch/$p\" \"$target_dir/$p\"\n done\ndiff --git a/guilt-guard b/guilt-guard\nindex a0cac2e..a427e25 100755\n--- a/guilt-guard\n+++ b/guilt-guard\n@@ -13,7 +13,7 @@ print_guards()\n }\n \n if [ \"$1\" == \"-l\" ] || [ \"$1\" == \"--list\" ]; then\n-\tget_series | while read patch; do\n+\tget_full_series | while read patch; do\n \t\tprint_guards \"$patch\"\n \tdone\n \texit 0\n@@ -35,7 +35,7 @@ case $# in\n \t\t;;\n \t1)\n \t\tif [ -z $(printf %s \"$1\" | grep -e '^[+-]') ]; then\n-\t\t\tif [ -z $(get_series | grep -e \"^$1\\$\") ]; then\n+\t\t\tif [ -z $(get_full_series | grep -e \"^$1\\$\") ]; then\n \t\t\t\tdie \"Patch $1 does not exist.\"\n \t\t\telse\n \t\t\t\tprint_guards \"$1\"\n@@ -51,7 +51,7 @@ case $# in\n \t\t;;\n \t*)\n \t\tif [ -z $(printf %s \"$1\" | grep -e '^[+-]') ]; then\n-\t\t\tif [ -z $(get_series | grep -e \"^$1\\$\") ]; then\n+\t\t\tif [ -z $(get_full_series | grep -e \"^$1\\$\") ]; then\n \t\t\t\tdie \"Patch $1 does not exist.\"\n \t\t\telse\n \t\t\t\tpatch=\"$1\"\ndiff --git a/guilt-header b/guilt-header\nindex 5716265..540cf2a 100755\n--- a/guilt-header\n+++ b/guilt-header\n@@ -31,8 +31,8 @@ esac\n [ -z \"$patch\" ] && die \"No patches applied.\"\n \n # check that patch exists in the series\n-ret=`get_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n-if [ $ret -eq 0 ]; then\n+ret=`get_full_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n+if [ -z \"$ret\" ]; then\n \tdie \"Patch $patch is not in the series\"\n fi\n \ndiff --git a/guilt-push b/guilt-push\nindex ad3616b..e4004e0 100755\n--- a/guilt-push\n+++ b/guilt-push\n@@ -26,7 +26,7 @@ if [ \"$patch\" = \"--all\" ] || [ \"$patch\" = \"-a\" ]; then\n \n \teidx=`get_series | wc -l`\n \tif [ $eidx -eq 0 ]; then\n-\t\tdie \"There are no patches to push\"\n+\t\tdie \"There are no patches to push.\"\n \tfi\n elif [ -z \"$patch\" ]; then\n \t# we are supposed to push only the next patch onto the stack\n@@ -39,7 +39,7 @@ else\n \n \teidx=`get_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n \tif [ -z \"$eidx\" ]; then\n-\t\tdie \"Patch $patch is not in the series\"\n+\t\tdie \"Patch $patch is not in the series or is guarded.\"\n \tfi\n fi\n \ndiff --git a/guilt-select b/guilt-select\nindex 378ca98..57373c7 100755\n--- a/guilt-select\n+++ b/guilt-select\n@@ -42,7 +42,7 @@ case $1 in\n \t\tguilt-push \"$top\"\n \t\t;;\n \t-s|--series)\n-\t\t(get_series | while read patch; do\n+\t\t(get_full_series | while read patch; do\n \t\t\tget_guards \"$patch\"\n \t\tdone) | sed -e 's/ /\\n/g' | sort | uniq\n \t\t;;\ndiff --git a/guilt-series b/guilt-series\nindex 9c34a08..85ef15d 100755\n--- a/guilt-series\n+++ b/guilt-series\n@@ -36,12 +36,12 @@ elif [ ! -z \"$gui\" ]; then\n \n \tgitk $range\n elif [ -z \"$verbose\" ]; then\n-\tget_series\n+\tget_full_series\n else\n \tprefix=\"+\"\n \ttop=`get_top`\n \n-\tget_series |\n+\tget_full_series |\n \twhile read patch; do\n \t\tif [ -z \"$top\" ]; then\n \t\t\techo \"  $patch\"\n@@ -49,6 +49,8 @@ else\n \t\t\tif [ \"$patch\" = \"$top\" ]; then\n \t\t\t\techo \"= $patch\"\n \t\t\t\tprefix=\" \"\n+                        elif [ $(check_guards \"$patch\"; echo $?) -eq 1 ]; then\n+\t\t\t\techo \"  $patch\"\n \t\t\telse\n \t\t\t\techo \"$prefix $patch\"\n \t\t\tfi\n-- \n1.5.2\n"},{"id":"49185","messageId":"11858514811776-git-send-email-eclesh@ucla.edu","threadId":"9321","inReplyTo":"1185851481190-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 5/5] Guards test suite","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-31T03:11:21Z","receivedAt":"2007-07-31T03:11:21Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"The guards patches touch a lot of guilt, so make sure they don't muck\nanything up.\n\nSigned-off-by: Eric Lesh <eclesh@ucla.edu>\n---\n regression/070-guards.sh |  184 ++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 184 insertions(+), 0 deletions(-)\n create mode 100755 regression/070-guards.sh\n\ndiff --git a/regression/070-guards.sh b/regression/070-guards.sh\nnew file mode 100755\nindex 0000000..d6917f2\n--- /dev/null\n+++ b/regression/070-guards.sh\n@@ -0,0 +1,184 @@\n+#!/bin/bash\n+#\n+# Test the commands that use get_*_series, while applying guards\n+#\n+\n+source scaffold\n+source generic_test_data\n+\n+function prepare_for_tests\n+{\n+\t# generic_test_data's patches all depend on each other\n+\t# that's no good for guards testing\n+\n+\techo \"abc\" > def\n+\tgit-add def\n+\tgit-commit -s -m \"initial\" 2> /dev/null > /dev/null\n+\n+\tcat << DONE > .git/patches/master/first\n+diff --git a/first b/first\n+new file mode 100644\n+index 0000000..9c59e24\n+--- /dev/null\n++++ b/first\n+@@ -0,0 +1 @@\n++first\n+DONE\n+\n+\tcat << DONE > .git/patches/master/second\n+diff --git a/second b/second\n+new file mode 100644\n+index 0000000..e019be0\n+--- /dev/null\n++++ b/second\n+@@ -0,0 +1 @@\n++second\n+DONE\n+\n+\tcat << DONE > .git/patches/master/third\n+diff --git a/third b/third\n+new file mode 100644\n+index 0000000..234496b\n+--- /dev/null\n++++ b/third\n+@@ -0,0 +1 @@\n++third\n+DONE\n+\n+\tcat << DONE > .git/patches/master/fourth\n+diff --git a/fourth b/fourth\n+new file mode 100644\n+index 0000000..285a4e6\n+--- /dev/null\n++++ b/fourth\n+@@ -0,0 +1 @@\n++fourth\n+DONE\n+\n+\tcat << DONE > .git/patches/master/series\n+first\n+second\n+third\n+fourth\n+DONE\n+\n+\ttouch -d \"$GIT_COMMITTER_DATE\" .git/patches/master/first\n+\ttouch -d \"$GIT_COMMITTER_DATE\" .git/patches/master/second\n+\ttouch -d \"$GIT_COMMITTER_DATE\" .git/patches/master/third\n+\ttouch -d \"$GIT_COMMITTER_DATE\" .git/patches/master/fourth\n+}\n+\n+function expected_applied_none\n+{\n+\techo \"first\"\n+\techo \"second\"\n+\techo \"third\"\n+\techo \"fourth\"\n+}\n+\n+function expected_applied_positive\n+{\n+\techo \"second\"\n+\techo \"third\"\n+\techo \"fourth\"\n+}\n+\n+function expected_applied_positive_selected\n+{\n+\techo \"first\"\n+\techo \"second\"\n+\techo \"third\"\n+\techo \"fourth\"\n+}\n+\n+function expected_applied_negative\n+{\n+\techo \"first\"\n+\techo \"second\"\n+\techo \"third\"\n+\techo \"fourth\"\n+}\n+\n+function expected_applied_negative_selected\n+{\n+\techo \"second\"\n+\techo \"third\"\n+\techo \"fourth\"\n+}\n+\n+function expected_next\n+{\n+\techo \"second\"\n+}\n+\n+function expected_unapplied\n+{\n+\techo \"second\"\n+\techo \"third\"\n+\techo \"fourth\"\n+}\n+\n+empty_repo\n+cd $REPODIR\n+guilt-init\n+\n+prepare_for_tests\n+\n+# test with no guarded patches and no guards selected\n+guilt-push -a > /dev/null\n+guilt-applied > /tmp/reg.$$\n+expected_applied_none | diff -u - /tmp/reg.$$\n+echo -n \"[none] \"\n+\n+# test with one positive guarded patch and no guards selected\n+guilt-pop -a > /dev/null\n+guilt-guard first +foo\n+guilt-push -a > /dev/null\n+guilt-applied > /tmp/reg.$$\n+expected_applied_positive | diff -u - /tmp/reg.$$\n+echo -n \"[positive] \"\n+\n+# test with one positive guarded patch with that guard selected\n+guilt-pop -a > /dev/null\n+guilt-select foo\n+guilt-push -a > /dev/null\n+guilt-applied > /tmp/reg.$$\n+expected_applied_positive_selected | diff -u - /tmp/reg.$$\n+echo -n \"[positive selected] \"\n+\n+# test with one negative guarded patch and no guards selected\n+guilt pop -a > /dev/null\n+guilt-select -n\n+guilt-guard first -foo\n+guilt-push -a > /dev/null\n+guilt-applied > /tmp/reg.$$\n+expected_applied_negative | diff -u - /tmp/reg.$$\n+echo -n \"[negative] \"\n+\n+# test with one negative guarded patch with that guard selected\n+guilt pop -a > /dev/null\n+guilt-select foo\n+guilt-push -a > /dev/null\n+guilt-applied > /tmp/reg.$$\n+expected_applied_negative_selected | diff -u - /tmp/reg.$$\n+echo -n \"[negative selected] \"\n+\n+# test that guilt-next works\n+guilt-pop -a > /dev/null\n+guilt-select -n\n+guilt-guard first +foo\n+guilt-next > /tmp/reg.$$\n+expected_next | diff -u - /tmp/reg.$$\n+echo -n \"[next] \"\n+\n+# test that guilt-unapplied works\n+guilt-pop -a > /dev/null\n+guilt-select -n\n+guilt-guard first +foo\n+guilt-unapplied > /tmp/reg.$$\n+expected_unapplied | diff -u - /tmp/reg.$$\n+echo -n \"[unapplied] \"\n+\n+rm -f /tmp/reg.$$\n+\n+complete_test\n-- \n1.5.2\n"},{"id":"49187","messageId":"20070731034208.GB12918@filer.fsl.cs.sunysb.edu","threadId":"9321","inReplyTo":"1185851481190-git-send-email-eclesh@ucla.edu","subject":"Re: [GUILT PATCH v2 0/5] Add guards to guilt","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-31T03:42:08Z","receivedAt":"2007-07-31T03:42:08Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Mon, Jul 30, 2007 at 08:11:16PM -0700, Eric Lesh wrote:\n...\n> I did everything (maybe?) you suggested except implement a\n> safe_sed wrapper and a validate_guards function.  The sed stuff is\n> maybe better for a later patch that covers most sed usage in guilt,\n\nAgreed.\n\n> and the validate_guards isn't really necessary given the small number\n> of times it's called.  If you would prefer either of those to get\n> done, let me know.\n\nI'll look at the patches and complain there if it seems like something\nthat should be done. :)\n\nJosef 'Jeff' Sipek.\n\n-- \nI already backed up the [server] once, I can do it again.\n"},{"id":"49188","messageId":"20070731035018.GC12918@filer.fsl.cs.sunysb.edu","threadId":"9321","inReplyTo":"11858514812742-git-send-email-eclesh@ucla.edu","subject":"Re: [GUILT PATCH 1/5] get_series: Remove comments from end of series lines","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-31T03:50:18Z","receivedAt":"2007-07-31T03:50:18Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Mon, Jul 30, 2007 at 08:11:17PM -0700, Eric Lesh wrote:\n...\n> @@ -290,14 +296,17 @@ series_insert_patch()\n>  # usage: series_remove_patch <patchname>\n>  series_remove_patch()\n>  {\n> -\tgrep -v \"^$1\\$\" < \"$series\" > \"$series.tmp\"\n> +\tgrep -v \"^$1[[:space:]]*#*\" < \"$series\" > \"$series.tmp\"\n>  \tmv \"$series.tmp\" \"$series\"\n>  }\n\nI haven't tested it, but I believe that this change would be very\nbad...suppose you have series with patches \"foo\" and \"foo-2\". Now if you try\nto remove foo, the regexp would end up being:\n\n\"^foo[ ]*#*\"\n\nThis would match both patches!\n  \n>  # usage: series_rename_patch <oldname> <newname>\n>  series_rename_patch()\n>  {\n> -\tawk -v old=\"$1\" -v new=\"$2\" \\\n> +\t# Rename the patch, but preserve comments on the line\n> +\told=$(grep -e \"^$1[[:space:]]*\" $series)\n\nThis could match multiple lines.\n\n> +\tnew=$(echo \"$old\" | sed -e \"s,^$1,$2,\")\n\nOne more comment about sed...there are a number of place in guilt that take\npatch names and create regexps from them, but don't make sure things get\nproperly escaped. I guess all the sed changes should be done in one go.\n\nAlso, beware that this is in a function, so setting $new and $old affects\nthe _all_ of guilt. One way around it would be a force subshell to execute\nusing parenthesis around the contents of the function body.\n\n> +\tawk -v old=\"$old\" -v new=\"$new\" \\\n>  \t\t'{ if ($0 == old) print new; else print $0 }' \\\n>  \t\t\"$series\" > \"$series.tmp\"\n>  \n> diff --git a/regression/050-series.sh b/regression/050-series.sh\n> index eb23540..4c47e9d 100755\n> --- a/regression/050-series.sh\n> +++ b/regression/050-series.sh\n> @@ -26,7 +26,7 @@ modify\n>  add\n>  \n>  remove\n> -mode\n> +mode # and text\n>  #sure\n>  DONE\n>  }\n\nGood :)\n\nJeff.\n\n-- \nNT is to UNIX what a doughnut is to a particle accelerator.\n"},{"id":"49189","messageId":"20070731040510.GD12918@filer.fsl.cs.sunysb.edu","threadId":"9321","inReplyTo":"1185851481271-git-send-email-eclesh@ucla.edu","subject":"Re: [GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-31T04:05:10Z","receivedAt":"2007-07-31T04:05:10Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Mon, Jul 30, 2007 at 08:11:18PM -0700, Eric Lesh wrote:\n...\n> diff --git a/Documentation/guilt-guard.txt b/Documentation/guilt-guard.txt\n> new file mode 100644\n> index 0000000..6290bf7\n> --- /dev/null\n> +++ b/Documentation/guilt-guard.txt\n> @@ -0,0 +1,40 @@\n> +guilt-guard(1)\n> +===============\n\nExtra = ;)\n\n> +\n> +NAME\n> +----\n> +guilt-guard - Assign guards to patches\n> +\n> +SYNOPSIS\n> +--------\n> +include::usage-guilt-guard.txt[]\n> +\n> +DESCRIPTION\n> +-----------\n> +Assign guards to the specified patch, or to the patch on top of the\n> +stack if no patch is given on the command line.\n> +\n> +An unguarded patch is always pushed.\n> +\n> +A positive guard begins with a +. A patch with a positive guard is\n> +pushed *only if* the guard is selected.\n> +\n> +A negative guard begins with a -. A patch with a negative guard is\n> +always pushed, *unless* the guard is selected.\n> +\n> +OPTIONS\n> +-------\n> +-l|--list::\n> +        List all patches and their guards\n> +-n|--none::\n> +        Remove all guards from a patch\n\nI generally try to keep an empty line between the options. I don't think it\naffects rendering, but just for consistency.\n\n> +\n> +Author\n> +------\n> +Written by Eric Lesh <eclesh@ucla.edu>\n> +\n> +Documentation\n> +-------------\n> +Documentation by Eric Lesh <eclesh@ucla.edu>\n> +\n> +include::footer.txt[]\n> diff --git a/guilt b/guilt\n> index 700c167..6af590c 100755\n> --- a/guilt\n> +++ b/guilt\n> @@ -187,6 +187,72 @@ get_series()\n>  \t\t\" $series\n>  }\n>  \n> +get_guarded_series()\n> +{\n> +\tget_series | while read p\n> +\tdo\n> +\t\tcheck_guards \"$p\" && echo \"$p\"\n> +\tdone\n> +}\n> +\n> +# usage: check_guards <patch>\n> +# Returns 0 if the patch should be pushed\n> +check_guards()\n> +{\n> +\tget_guards \"$1\" | while read guard\n> +\tdo\n> +\t\tpos=`printf %s $guard | grep -e \"^+\"`\n> +\t\tguard=`printf %s $guard | sed -e 's/^[+-]//'`\n> +\t\tif [ \"$pos\" ]; then\n> +\t\t\t# Push +guard *only if* guard selected\n> +\t\t\tpush=`grep -e \"^$guard\\$\" \"$guards_file\" >/dev/null 2>/dev/null; echo $?`\n> +\t\t\t[ $push -ne 0 ] && return 1\n\n\t\t\tgrep -e \"^$guard\\$\" \"$guards_file\" >/dev/null 2>/dev/null\n\t\t\t[ $? -ne 0 ] && return 1\n\nMuch cleaner looking :) Or even:\n\n\t\t\tgrep -e ....... || return 1\n\n> +\t\telse\n> +\t\t\t# Push -guard *unless* guard selected\n> +\t\t\tpush=`grep -e \"^$guard\\$\" \"$guards_file\" >/dev/null 2>/dev/null; echo $?`\n> +\t\t\t[ $push -eq 0 ] && return 1\n\nDitto.\n\n> +\t\tfi\n> +\t\treturn 0\n> +\tdone\n> +\treturn $?\n\nI'd throw in a small comment above the outter return to make sure no one\ntries to clean things up and remove it.\n\n> +}\n> +\n> +# usage: get_guards <patch>\n> +get_guards()\n> +{\n> +\tsed -n -e \"\\,^$1[[:space:]]*#, {\n> +\t\ts,^$1[[:space:]]*,,\n> +\t\ts,#[^+-]*,,g\n> +\n> +\t\tp\n> +\t\t}\n> +\t\t\" $series\n\nThree things...\n\n1) I generally preserve the sed script indentation\n\n2) I like having the whole script start at col 0, syntax highlighting makes\nit readable enough.\n\n3) quote the \"$series\" in case there's whitespace in the repo path or branch\nname\n\n\nThis is what I'd make it look like if I were to write it, but that's me just\nnitpicking at this point :)\n\n\tsed -n -e \"\nline 1\t{\n\tline 2\n\n\tline 4\n}\n\" \"$series\"\n\n\n> +}\n> +\n> +# usage: set_guards <patch> <guards...>\n> +set_guards()\n> +{\n> +\tp=\"$1\"\n\nAgain, be careful about namespace polution.\n\n> +\tshift\n> +\tfor x in \"$@\"; do\n> +\t\tif [ -z $(printf %s \"$x\" | grep -e \"^[+-]\") ]; then\n\nOut of curiosity, why printf and not echo?\n\n> +\t\t\techo \"'$x' is not a valid guard name\"\n> +\t\telse\n> +\t\t\tsed -i -e \"s,^\\($p[[:space:]]*.*\\)$,\\1 #$x,\" \"$series\"\n\nThe regexp is in double quotes, so you should escape the $ (EOL), as well as\nall the \\. Yep, this is shell scripting at its worst.\n\n> +\t\tfi\n> +\tdone\n> +}\n> +\n> +# usage: unset_guards <patch> <guards...>\n> +unset_guards()\n> +{\n> +\tp=\"$1\"\n\nNamespace..\n\n> +\tshift\n> +\tfor x in \"$@\"; do\n> +\t\tsed -i -e \"/^$p[[:space:]]/s/ #$x//\" \"$series\"\n> +\tdone\n> +}\n> +\n>  # usage: do_make_header <hash>\n>  do_make_header()\n>  {\n> diff --git a/guilt-guard b/guilt-guard\n> new file mode 100755\n> index 0000000..a0cac2e\n> --- /dev/null\n> +++ b/guilt-guard\n> @@ -0,0 +1,69 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) Eric Lesh, 2007\n> +#\n> +\n> +USAGE=\"[-l|--list|-n|--none|[<patchname>] [(+|-)<guard>...]]\"\n> +. `dirname $0`/guilt\n> +\n> +print_guards()\n> +{\n> +\tguards=`get_guards \"$1\"`\n> +\techo \"$1: $guards\"\n\n\techo \"$1: `get_guards \\\"$1\\\"`\"\n\nEliminates assignment & namespace polution :) Not really a problem here as\nthis is a guilt-guard only function.\n\n> +}\n> +\n> +if [ \"$1\" == \"-l\" ] || [ \"$1\" == \"--list\" ]; then\n> +\tget_series | while read patch; do\n> +\t\tprint_guards \"$patch\"\n> +\tdone\n> +\texit 0\n> +elif [ \"$1\" == \"-n\" ] || [ \"$1\" == \"--none\" ]; then\n> +\tpatch=\"$2\"\n> +\tif [ -z \"$patch\" ]; then\n> +\t\tpatch=`get_top`\n> +\tfi\n> +\tunset_guards \"$patch\" `get_guards \"$patch\"`\n> +\texit 0\n> +fi\n> +\n> +case $# in\n> +\t0)\n> +\t\tif [ ! -s \"$applied\" ]; then\n> +\t\t\tdie \"No patches applied.\"\n> +\t\tfi\n> +\t\tprint_guards `get_top`\n\nQuote the `get_top` in case the topmost patch has whitespace in it. Yeah,\nit's annoying, but safety first :)\n\n> +\t\t;;\n> +\t1)\n> +\t\tif [ -z $(printf %s \"$1\" | grep -e '^[+-]') ]; then\n> +\t\t\tif [ -z $(get_series | grep -e \"^$1\\$\") ]; then\n> +\t\t\t\tdie \"Patch $1 does not exist.\"\n> +\t\t\telse\n> +\t\t\t\tprint_guards \"$1\"\n> +\t\t\tfi\n> +\t\telse\n> +\t\t\tpatch=`get_top`\n> +\t\t\tif [ -z \"$patch\" ]; then\n> +\t\t\t\tdie \"You must specify a patch.\"\n> +\t\t\tfi\n> +\t\t\tunset_guards \"$patch\" `get_guards \"$patch\"`\n> +\t\t\tset_guards \"$patch\" \"$1\"\n> +\t\tfi\n> +\t\t;;\n> +\t*)\n> +\t\tif [ -z $(printf %s \"$1\" | grep -e '^[+-]') ]; then\n> +\t\t\tif [ -z $(get_series | grep -e \"^$1\\$\") ]; then\n> +\t\t\t\tdie \"Patch $1 does not exist.\"\n> +\t\t\telse\n> +\t\t\t\tpatch=\"$1\"\n> +\t\t\tfi\n> +\t\t\tshift\n> +\t\telse\n> +\t\t\tpatch=`get_top`\n> +\t\t\tif [ -z \"$patch\" ]; then\n> +\t\t\t\tdie \"You must specify a patch.\"\n> +\t\t\tfi\n> +\t\tfi\n> +\t\tunset_guards \"$patch\" `get_guards \"$patch\"`\n> +\t\tset_guards \"$patch\" \"$@\"\n> +\t\t;;\n> +esac\n> -- \n> 1.5.2\n\nJosef 'Jeff' Sipek, falling asleep after a loooong day.\n\n-- \nWe have joy, we have fun, we have Linux on a Sun...\n"},{"id":"50293","messageId":"87bqdhnotj.fsf@hubert.paunchy.net","threadId":"9321","inReplyTo":"20070731040510.GD12918@filer.fsl.cs.sunysb.edu","subject":"Re: [GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-08-09T07:34:48Z","receivedAt":"2007-08-09T07:34:48Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"[ I'm finally back to this.  Thanks for your comments. ]\n\nJosef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n\n[...]\n\n>> +}\n>> +\n>> +# usage: set_guards <patch> <guards...>\n>> +set_guards()\n>> +{\n>> +\tp=\"$1\"\n>\n> Again, be careful about namespace polution.\n>\n\nCan I use \"local\", or is it a bashism?  If not, use parentheses around\nthe function body?\n\n>> +\tshift\n>> +\tfor x in \"$@\"; do\n>> +\t\tif [ -z $(printf %s \"$x\" | grep -e \"^[+-]\") ]; then\n>\n> Out of curiosity, why printf and not echo?\n>\n\nFor guards named '-e' or other funky things echo doesn't like and can't\nprocess with echo --.\n\n>> +\t\t\techo \"'$x' is not a valid guard name\"\n>> +\t\telse\n>> +\t\t\tsed -i -e \"s,^\\($p[[:space:]]*.*\\)$,\\1 #$x,\" \"$series\"\n>\n> The regexp is in double quotes, so you should escape the $ (EOL), as well as\n> all the \\. Yep, this is shell scripting at its worst.\n>\n\nYikes.\n\n[...]\n\nI'm trying to clean the rest and get it ready again. This whole series\nwill definitely need to incubate for a while once there's a\nreasonable-looking version, to make sure nothing goes crazy.  Hopefully\nit ends up being useful somewhere!\n\n\tEric\n"},{"id":"50296","messageId":"86r6mdp1e1.fsf@lola.quinscape.zz","threadId":"9321","inReplyTo":"87bqdhnotj.fsf@hubert.paunchy.net","subject":"Re: [GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-08-09T08:17:58Z","receivedAt":"2007-08-09T08:17:58Z","isPatch":true,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Eric Lesh <eclesh@ucla.edu> writes:\n\n> [ I'm finally back to this.  Thanks for your comments. ]\n>\n> Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n>\n> [...]\n>\n>>> +}\n>>> +\n>>> +# usage: set_guards <patch> <guards...>\n>>> +set_guards()\n>>> +{\n>>> +\tp=\"$1\"\n>>\n>> Again, be careful about namespace polution.\n>>\n>\n> Can I use \"local\", or is it a bashism?  If not, use parentheses around\n> the function body?\n>\n>>> +\tshift\n>>> +\tfor x in \"$@\"; do\n>>> +\t\tif [ -z $(printf %s \"$x\" | grep -e \"^[+-]\") ]; then\n>>> +\t\t\techo \"'$x' is not a valid guard name\"\n>>> +\t\telse\n>>> +\t\t\tsed -i -e \"s,^\\($p[[:space:]]*.*\\)$,\\1 #$x,\" \"$series\"\n>>\n>> Out of curiosity, why printf and not echo?\n>>\n>\n> For guards named '-e' or other funky things echo doesn't like and\n> can't process with echo --.\n\nThe problem with the above is that it reacts strangely to multiline\noptions.\n\nShould be much better (and faster on shells without builtin printf) to\nuse\n\ncase \"$x\" in\n   [+-]*)\n     sed -i -e ...  ;;\n       *)\n     echo \"'$x' is not ...\nesac\n\nand this runs portably without forking on shells that are 30 years\nold.  Shell script programmers _really_ should know \"case\" inside out.\n\nAlso, instead of 'for x in \"$@\"' one can just write \"for x'\n\n>> The regexp is in double quotes, so you should escape the $ (EOL),\n>> as well as all the \\. Yep, this is shell scripting at its worst.\n\n\\ does not need to be escaped in double quotes except before \\, $ and `.\nYou can write\n\n    sed -i -e \"s,^\\($p[[:space:]]*.*\\)\\$,\\1 #$x,\" \"$series\"\n\nand that's fine.\n\n-- \nDavid Kastrup\n"},{"id":"50297","messageId":"18071eea0708090122h79dec205j4528f4dfd7aab588@mail.gmail.com","threadId":"9321","inReplyTo":"86r6mdp1e1.fsf@lola.quinscape.zz","subject":"Re: [GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"Thomas Adam","fromEmail":"thomas.adam22@gmail.com","sentAt":"2007-08-09T08:22:44Z","receivedAt":"2007-08-09T08:22:44Z","isPatch":true,"sender":{"key":"thomas.adam22@gmail.com","avatar":"https://gravatar.com/avatar/137f9858bc6bfd5b2f743aefd988c81ce0cbd306248889df80e269519cfc8741?d=mp&s=160"},"body":"On 09/08/07, David Kastrup <dak@gnu.org> wrote:\n>     sed -i -e \"s,^\\($p[[:space:]]*.*\\)\\$,\\1 #$x,\" \"$series\"\n>\n> and that's fine.\n\nI'm surprised to see 'sed -i' being at all, it's certainly non-portable.\n\n-- Thomas Adam\n"},{"id":"50298","messageId":"868x8lnlml.fsf@lola.quinscape.zz","threadId":"9321","inReplyTo":"18071eea0708090122h79dec205j4528f4dfd7aab588@mail.gmail.com","subject":"Re: [GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2007-08-09T08:43:46Z","receivedAt":"2007-08-09T08:43:46Z","isPatch":true,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"\"Thomas Adam\" <thomas.adam22@gmail.com> writes:\n\n> On 09/08/07, David Kastrup <dak@gnu.org> wrote:\n>>     sed -i -e \"s,^\\($p[[:space:]]*.*\\)\\$,\\1 #$x,\" \"$series\"\n>>\n>> and that's fine.\n>\n> I'm surprised to see 'sed -i' being at all, it's certainly non-portable.\n\nYes.  Neither is [[:space:]].  The above actually is pretty much\nequivalent to\n\n      $(RM) \"$series+\"\n      sed \"/^$p/s/\\$/ #$x/\" \"$series\" >\"$series+\"\n      $(MV) \"$series+\" \"$series\"\n\nWhich is probably not what was intended (the whole [[:space:]]\nconstruct is irrelevant).  More likely it was intended to do something\nlike\n\n      $(RM) \"$series+\"\n      sed \"/^$p[ \t]/s/\\$/ #$x/\" \"$series\" >\"$series+\"\n      $(MV) \"$series+\" \"$series\"\n\nor if $p can contain slashes but not commata,\n\n      $(RM) \"$series+\"\n      sed \"\\,^$p[ \t],s,\\$, #$x,\" \"$series\" >\"$series+\"\n      $(MV) \"$series+\" \"$series\"\n\nNote that the included tab character will get safely from any shell to\nany sed.\n\n-- \nDavid Kastrup\n"},{"id":"50302","messageId":"877io5nl6f.fsf@hubert.paunchy.net","threadId":"9321","inReplyTo":"18071eea0708090122h79dec205j4528f4dfd7aab588@mail.gmail.com","subject":"Re: [GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-08-09T08:53:28Z","receivedAt":"2007-08-09T08:53:28Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"\"Thomas Adam\" <thomas.adam22@gmail.com> writes:\n\n> On 09/08/07, David Kastrup <dak@gnu.org> wrote:\n>>     sed -i -e \"s,^\\($p[[:space:]]*.*\\)\\$,\\1 #$x,\" \"$series\"\n>>\n>> and that's fine.\n>\n> I'm surprised to see 'sed -i' being at all, it's certainly non-portable.\n>\n> -- Thomas Adam\n\nYou're definitely right. I've been asked to change this a couple of\ntimes and keep forgetting.  Thanks for the reminder.\n\n\tEric\n"},{"id":"50305","messageId":"873aytnktn.fsf@hubert.paunchy.net","threadId":"9321","inReplyTo":"86r6mdp1e1.fsf@lola.quinscape.zz","subject":"Re: [GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-08-09T09:01:08Z","receivedAt":"2007-08-09T09:01:08Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"David Kastrup <dak@gnu.org> writes:\n\n>>>> +\tshift\n>>>> +\tfor x in \"$@\"; do\n>>>> +\t\tif [ -z $(printf %s \"$x\" | grep -e \"^[+-]\") ]; then\n>>>> +\t\t\techo \"'$x' is not a valid guard name\"\n>>>> +\t\telse\n>>>> +\t\t\tsed -i -e \"s,^\\($p[[:space:]]*.*\\)$,\\1 #$x,\" \"$series\"\n>>>\n>>> Out of curiosity, why printf and not echo?\n>>>\n>>\n>> For guards named '-e' or other funky things echo doesn't like and\n>> can't process with echo --.\n>\n> The problem with the above is that it reacts strangely to multiline\n> options.\n>\n\nThere shouldn't be multiline options passed to this function, so it\nmight not be a problem.\n\n> Should be much better (and faster on shells without builtin printf) to\n> use\n>\n> case \"$x\" in\n>    [+-]*)\n>      sed -i -e ...  ;;\n>        *)\n>      echo \"'$x' is not ...\n> esac\n>\n> and this runs portably without forking on shells that are 30 years\n> old.  Shell script programmers _really_ should know \"case\" inside out.\n>\n\nHeh, as you may have noticed, I'm no shell programmer :-)  Thanks for\nthe advice though.\n\n> Also, instead of 'for x in \"$@\"' one can just write \"for x'\n>\n\nNice.\n\n>>> The regexp is in double quotes, so you should escape the $ (EOL),\n>>> as well as all the \\. Yep, this is shell scripting at its worst.\n>\n> \\ does not need to be escaped in double quotes except before \\, $ and `.\n> You can write\n>\n>     sed -i -e \"s,^\\($p[[:space:]]*.*\\)\\$,\\1 #$x,\" \"$series\"\n>\n> and that's fine.\n\nYeah.  That one made itself clear.  The sed -i needs to go too, as\nThomas observed.  The regexp itself also needs cleansing.\n\nLots of work to do...\n\n\tEric\n"},{"id":"50322","messageId":"20070809134715.GA22563@filer.fsl.cs.sunysb.edu","threadId":"9321","inReplyTo":"87bqdhnotj.fsf@hubert.paunchy.net","subject":"Re: [GUILT PATCH 2/5] guilt-guard: Assign guards to patches in series","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-08-09T13:47:15Z","receivedAt":"2007-08-09T13:47:15Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Thu, Aug 09, 2007 at 12:34:48AM -0700, Eric Lesh wrote:\n> [ I'm finally back to this.  Thanks for your comments. ]\n\nGood. I was starting to get worried :)\n\n> Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n> \n> [...]\n> \n> >> +}\n> >> +\n> >> +# usage: set_guards <patch> <guards...>\n> >> +set_guards()\n> >> +{\n> >> +\tp=\"$1\"\n> >\n> > Again, be careful about namespace polution.\n> >\n> \n> Can I use \"local\", or is it a bashism?  If not, use parentheses around\n> the function body?\n\nRight, \"local\" is a bashism therefore you must use a subshell (paretheses).\n\n> >> +\tshift\n> >> +\tfor x in \"$@\"; do\n> >> +\t\tif [ -z $(printf %s \"$x\" | grep -e \"^[+-]\") ]; then\n> >\n> > Out of curiosity, why printf and not echo?\n> >\n> \n> For guards named '-e' or other funky things echo doesn't like and can't\n> process with echo --.\n\nGood enough reason :)\n\n...\n> I'm trying to clean the rest and get it ready again. This whole series\n> will definitely need to incubate for a while once there's a\n> reasonable-looking version, to make sure nothing goes crazy.  Hopefully\n> it ends up being useful somewhere!\n\nI'd use it at times. For certain scenarios (2 series that are mostly\nidentical) using guards makes more sense than different branches.\n\nThanks,\n\nJosef 'Jeff' Sipek.\n\n-- \nHumans were created by water to transport it upward.\n"}]}