{"thread":{"id":"9285","subject":"[GUILT PATCH 1/4] get_series: Remove comments from end of series lines","startedAt":"2007-07-29T07:50:14Z","lastAt":"2007-07-30T19:34:18Z","messageCount":20,"participants":["Eric Lesh","Josef Sipek"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"48966","messageId":"118569541814-git-send-email-eclesh@ucla.edu","threadId":"9285","inReplyTo":null,"subject":"[GUILT PATCH 0/4] Add guards to guilt","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-29T07:50:14Z","receivedAt":"2007-07-29T07:50:14Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"\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 introduces the command `get_guarded_series`, which just lists\npatches that are to be applied based on the guards.  It also makes\n        eidx=`wc -l < $applied`\ninaccurate if you're using it as an index into get_series.\n\nIf you change guards on a patch or select a different guard while\npatches are applied, some commands might get confused. guilt pop -a will fix\neverything though.  Usually, it's best to pop -a before fiddling with\nguards anyway.\n\nThis is an RFC, but I have tested it and things seem to be working\nwell.\n\n[PATCH 1/4] 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/4] guilt-guard: Assign guards to patches in series\n       This adds the guilt-guard command and utility functions to\n       guilt.\n\n[PATCH 3/4] 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/4] Use guards information and functions\n       This changes guilt-header, guilt-next, guilt-push and guilt-unapplied to\n       use the guards information properly.\n\n       After the guilt-push change, header, next, and unapplied get\n       confused and break, so I rolled their fixes into this patch\n       instead of separate ones.\n\n Documentation/guilt-guards.txt |   40 +++++++++++++++++++++++++\n Documentation/guilt-select.txt |   42 ++++++++++++++++++++++++++\n guilt                          |   62 ++++++++++++++++++++++++++++++++++++++-\n guilt-guards                   |   63 ++++++++++++++++++++++++++++++++++++++++\n guilt-header                   |    7 ++--\n guilt-next                     |    2 +-\n guilt-push                     |    8 ++--\n guilt-select                   |   36 +++++++++++++++++++++++\n guilt-unapplied                |    2 +-\n 9 files changed, 252 insertions(+), 10 deletions(-)\n create mode 100644 Documentation/guilt-guards.txt\n create mode 100644 Documentation/guilt-select.txt\n create mode 100755 guilt-guards\n create mode 100755 guilt-select\n"},{"id":"48961","messageId":"11856954183111-git-send-email-eclesh@ucla.edu","threadId":"9285","inReplyTo":"118569541814-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 1/4] get_series: Remove comments from end of series lines","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-29T07:50:15Z","receivedAt":"2007-07-29T07:50:15Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"Signed-off-by: Eric Lesh <eclesh@ucla.edu>\n\n--\n---\n guilt |    3 ++-\n 1 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/guilt b/guilt\nindex f67bfb5..774909e 100755\n--- a/guilt\n+++ b/guilt\n@@ -178,7 +178,8 @@ 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+\tgrep -ve '^[[:space:]]*\\(#.*\\)*$' < \"$series\" | sed -e 's/[[:space:]]*#.*$//'\n }\n \n # usage: do_make_header <hash>\n-- \n1.5.2\n"},{"id":"48963","messageId":"11856954181497-git-send-email-eclesh@ucla.edu","threadId":"9285","inReplyTo":"118569541814-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 2/4] guilt-guard: Assign guards to patches in series","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-29T07:50:16Z","receivedAt":"2007-07-29T07:50:16Z","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\nSigned-off-by: Eric Lesh <eclesh@ucla.edu>\n---\n Documentation/guilt-guards.txt |   40 +++++++++++++++++++++++++\n guilt                          |   58 ++++++++++++++++++++++++++++++++++++\n guilt-guards                   |   63 ++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 161 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/guilt-guards.txt\n create mode 100755 guilt-guards\n\ndiff --git a/Documentation/guilt-guards.txt b/Documentation/guilt-guards.txt\nnew file mode 100644\nindex 0000000..f5ac537\n--- /dev/null\n+++ b/Documentation/guilt-guards.txt\n@@ -0,0 +1,40 @@\n+guilt-guards(1)\n+===============\n+\n+NAME\n+----\n+guilt-guards - Assign guards to patches\n+\n+SYNOPSIS\n+--------\n+include::usage-guilt-guards.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 774909e..b2767ea 100755\n--- a/guilt\n+++ b/guilt\n@@ -182,6 +182,64 @@ get_series()\n \tgrep -ve '^[[:space:]]*\\(#.*\\)*$' < \"$series\" | sed -e 's/[[:space:]]*#.*$//'\n }\n \n+get_guarded_series()\n+{\n+\tget_series | while read p\n+\tdo\n+\t\t[ -z `check_guards $p` ] && echo \"$p\"\n+\tdone\n+}\n+\n+# usage: check_guards <patch>\n+# Returns t if the patch should be skipped\n+check_guards()\n+{\n+        get_guards \"$1\" | while read guard\n+        do\n+                pos=`echo $guard | grep -e \"^+\"`\n+                guard=`echo $guard | sed -e 's/[+-]//'`\n+                if [ $pos ]; then\n+                        # Push +guard *only if* guard selected\n+                        push=`grep -e \"^$guard\\$\" \"$guards_file\" > /dev/null; echo $?`\n+                        [ $push -ne 0 ] && echo t\n+                else\n+                        # Push -guard *unless* guard selected\n+                        push=`grep -e \"^$guard\\$\" \"$guards_file\" > /dev/null; echo $?`\n+                        [ $push -eq 0 ] && echo t\n+                fi\n+        done\n+}\n+\n+# usage: get_guards <patch>\n+get_guards()\n+{\n+\tgrep -e \"^$1[[:space:]]*#\" < \"$series\" | sed -e \"s/^$1 //\" -e 's/#[^+-]*//g'\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 $(echo \"$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+        p=\"$1\"\n+        shift\n+        for x in \"$@\"; do\n+            sed -i -e \"/^$p[[:space:]]/s/ #$x//\" \"$series\"\n+        done\n+}\n+\n # usage: do_make_header <hash>\n do_make_header()\n {\ndiff --git a/guilt-guards b/guilt-guards\nnew file mode 100755\nindex 0000000..71df4f8\n--- /dev/null\n+++ b/guilt-guards\n@@ -0,0 +1,63 @@\n+#!/bin/sh\n+#\n+# Copyright (c) Eric Lesh, 2007\n+#\n+\n+USAGE=\"[-l|--list] [-n|--none] [<patchname>] [+<guard>] [-<guard>]\"\n+. 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 $(echo $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\tp=`get_top`\n+\t\t\tunset_guards \"$p\" `get_guards \"$p\"`\n+\t\t\tset_guards \"$p\" \"$1\"\n+\t\tfi\n+\t\t;;\n+\t*)\n+\t\tif [ -z $(echo $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\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":"48964","messageId":"11856954182318-git-send-email-eclesh@ucla.edu","threadId":"9285","inReplyTo":"118569541814-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 3/4] guilt-select: Select guards to apply when pushing patches","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-29T07:50:17Z","receivedAt":"2007-07-29T07:50:17Z","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 |   42 ++++++++++++++++++++++++++++++++++++++++\n guilt                          |    1 +\n guilt-select                   |   36 ++++++++++++++++++++++++++++++++++\n 3 files changed, 79 insertions(+), 0 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..8e18f26\n--- /dev/null\n+++ b/Documentation/guilt-select.txt\n@@ -0,0 +1,42 @@\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+-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/guilt b/guilt\nindex b2767ea..3882962 100755\n--- a/guilt\n+++ b/guilt\n@@ -641,6 +641,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..f237ef0\n--- /dev/null\n+++ b/guilt-select\n@@ -0,0 +1,36 @@\n+#!/bin/sh\n+#\n+# Copyright (c) Eric Lesh, 2007\n+#\n+\n+USAGE=\"[-n|--none] [-s|--series] [<guard>]\"\n+ . `dirname $0`/guilt\n+\n+if [ $# == 0 ]; then\n+\tif [ -s \"$guards_file\" ]; then\n+\t\tcat \"$guards_file\"\n+\telse\n+\t\techo \"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\ttouch \"$guards_file\"\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\tfor x in \"$@\"; do\n+\t\t\tif [ $(echo $x | grep -e \"^[+-]\") ]; then\n+\t\t\t\tdie \"'$x' is not a valid guard name\"\n+\t\t\tfi\n+\t\tdone\n+\t\techo \"$@\" | sed -e 's/ /\\n/g' | sort | uniq > \"$guards_file\"\n+\t\t;;\n+esac\n-- \n1.5.2\n"},{"id":"48962","messageId":"1185695418227-git-send-email-eclesh@ucla.edu","threadId":"9285","inReplyTo":"118569541814-git-send-email-eclesh@ucla.edu","subject":"[GUILT PATCH 4/4] Use guards information and functions","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-29T07:50:18Z","receivedAt":"2007-07-29T07:50:18Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"Make guilt-push respect guards. Also teach guilt-header, guilt-next,\nand guilt-unapplied to grok patches that are skipped because of\nguards.\n\nSigned-off-by: Eric Lesh <eclesh@ucla.edu>\n---\n guilt-header    |    7 ++++---\n guilt-next      |    2 +-\n guilt-push      |    8 ++++----\n guilt-unapplied |    2 +-\n 4 files changed, 10 insertions(+), 9 deletions(-)\n\ndiff --git a/guilt-header b/guilt-header\nindex d07e2be..ef7f55e 100755\n--- a/guilt-header\n+++ b/guilt-header\n@@ -15,15 +15,16 @@ patch=\"$1\"\n if [ -z \"$patch\" ]; then\n \t# use the patch that's on the top of the stack\n \n-\teidx=`wc -l < $applied`\n-\tif [ $eidx -eq 0 ]; then\n+\tpatch=`get_top`\n+\tif [ -z \"$patch\" ]; then\n \t\tdie \"Status file is empty\"\n \tfi\n+\teidx=`get_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n else\n \t# use the specified patch\n \n \teidx=`get_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n-\tif [ $eidx -eq 0 ]; then\n+\tif [ -z \"$eidx\" ]; then\n \t\tdie \"Patch $patch is not in the series\"\n \tfi\n fi\ndiff --git a/guilt-next b/guilt-next\nindex f38f1cc..38f57fa 100755\n--- a/guilt-next\n+++ b/guilt-next\n@@ -13,5 +13,5 @@ fi\n n=`wc -l < $applied`\n n=$(($n + 1))\n \n-get_series | awk \"{ if (NR == $n) print \\$0}\"\n+get_guarded_series | awk \"{ if (NR == $n) print \\$0}\"\n \ndiff --git a/guilt-push b/guilt-push\nindex ad3616b..ce928e3 100755\n--- a/guilt-push\n+++ b/guilt-push\n@@ -24,7 +24,7 @@ if [ \"$patch\" = \"--all\" ] || [ \"$patch\" = \"-a\" ]; then\n \t# we are supposed to push all patches, get the last one out of\n \t# series\n \n-\teidx=`get_series | wc -l`\n+\teidx=`get_guarded_series | wc -l`\n \tif [ $eidx -eq 0 ]; then\n \t\tdie \"There are no patches to push\"\n \tfi\n@@ -37,9 +37,9 @@ else\n \t# we're supposed to push only up to a patch, make sure the patch is\n \t# in the series\n \n-\teidx=`get_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n+\teidx=`get_guarded_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 \n@@ -52,7 +52,7 @@ fi\n sidx=`wc -l < $applied`\n sidx=`expr $sidx + 1`\n \n-get_series | sed -n -e \"${sidx},${eidx}p\" | while read p\n+get_guarded_series | sed -n -e \"${sidx},${eidx}p\" | while read p\n do\n \techo \"Applying patch..$p\"\n \tif [ ! -f \"$GUILT_DIR/$branch/$p\" ]; then\ndiff --git a/guilt-unapplied b/guilt-unapplied\nindex 192a7e5..6904360 100755\n--- a/guilt-unapplied\n+++ b/guilt-unapplied\n@@ -13,4 +13,4 @@ fi\n n=`wc -l < $applied`\n n=`expr $n + 1`\n \n-get_series | sed -n -e \"$n,\\$p\"\n+get_guarded_series | sed -n -e \"$n,\\$p\"\n-- \n1.5.2\n"},{"id":"49049","messageId":"20070730035422.GB22017@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"11856954183111-git-send-email-eclesh@ucla.edu","subject":"Re: [GUILT PATCH 1/4] get_series: Remove comments from end of series lines","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T03:54:22Z","receivedAt":"2007-07-30T03:54:22Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Sun, Jul 29, 2007 at 12:50:15AM -0700, Eric Lesh wrote:\n... \n> diff --git a/guilt b/guilt\n> index f67bfb5..774909e 100755\n> --- a/guilt\n> +++ b/guilt\n> @@ -178,7 +178,8 @@ 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> +\tgrep -ve '^[[:space:]]*\\(#.*\\)*$' < \"$series\" | sed -e 's/[[:space:]]*#.*$//'\n\nI'd be tempted to replace the whole thing with one sed script...something\nlike (not tested):\n\n\"\n/^[[:space:]]*#/ ! {\n\ts/[[:space:]]*#.*$//\n\n\tp\n}\n\"\n\nRegardless of the other 3 patches, this one makes sense to include.\n\nJosef 'Jeff' Sipek.\n\n-- \nOnce you have their hardware. Never give it back.\n(The First Rule of Hardware Acquisition)\n"},{"id":"49050","messageId":"20070730035443.GC22017@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"118569541814-git-send-email-eclesh@ucla.edu","subject":"Re: [GUILT PATCH 0/4] Add guards to guilt","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T03:54:43Z","receivedAt":"2007-07-30T03:54:43Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Sun, Jul 29, 2007 at 12:50:14AM -0700, Eric Lesh wrote:\n> \n> This series adds Mercurial Queues-like guards to guilt.  It allows you\n> to assign guards to related patches in the series file to selectively\n> push patches.\n\nNeat. I actually never looked into guards, but you forced me to :) Very\ninteresting concept. I think it would be worth it having such functionality\nin guilt.\n\nI know I've been bad about forcing even myself to write new regression\ntests. Your patches modify things significantly enough, that I'd like to see\nsome regression tests cases to make sure that user's data is not eaten\n(e.g., a bug in the guard setting code could blow away the series file =>\nvery bad).\n\n> This introduces the command `get_guarded_series`, which just lists\n> patches that are to be applied based on the guards.  It also makes\n>         eidx=`wc -l < $applied`\n> inaccurate if you're using it as an index into get_series.\n\nThe index-based patch finding is a bit nasty anyway.\n\n> If you change guards on a patch or select a different guard while\n> patches are applied, some commands might get confused. guilt pop -a will fix\n> everything though.  Usually, it's best to pop -a before fiddling with\n> guards anyway.\n\nIs this a problem with other projects' implementations of guards as well?\nPerhaps printing a warning if a new guard is set when there are applied\npatches would be in order?\n\n> This is an RFC, but I have tested it and things seem to be working\n> well.\n\nGreat!\n\nI'm going to reply to each of the patches separately with any comments.\n\nJosef 'Jeff' Sipek.\n\n-- \nPenguin : Linux version 2.4.20-46.9.legacysmp on an i386 machine (2778.72 BogoMips).\n"},{"id":"49052","messageId":"20070730040610.GD22017@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"11856954181497-git-send-email-eclesh@ucla.edu","subject":"Re: [GUILT PATCH 2/4] guilt-guard: Assign guards to patches in series","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T04:06:10Z","receivedAt":"2007-07-30T04:06:10Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Sun, Jul 29, 2007 at 12:50:16AM -0700, Eric Lesh wrote:\n> 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> \n> Signed-off-by: Eric Lesh <eclesh@ucla.edu>\n> ---\n>  Documentation/guilt-guards.txt |   40 +++++++++++++++++++++++++\n>  guilt                          |   58 ++++++++++++++++++++++++++++++++++++\n>  guilt-guards                   |   63 ++++++++++++++++++++++++++++++++++++++++\n>  3 files changed, 161 insertions(+), 0 deletions(-)\n>  create mode 100644 Documentation/guilt-guards.txt\n>  create mode 100755 guilt-guards\n> \n> diff --git a/Documentation/guilt-guards.txt b/Documentation/guilt-guards.txt\n> new file mode 100644\n> index 0000000..f5ac537\n> --- /dev/null\n> +++ b/Documentation/guilt-guards.txt\n> @@ -0,0 +1,40 @@\n> +guilt-guards(1)\n> +===============\n> +\n> +NAME\n> +----\n> +guilt-guards - Assign guards to patches\n> +\n> +SYNOPSIS\n> +--------\n> +include::usage-guilt-guards.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[]\n> diff --git a/guilt b/guilt\n> index 774909e..b2767ea 100755\n> --- a/guilt\n> +++ b/guilt\n> @@ -182,6 +182,64 @@ get_series()\n>  \tgrep -ve '^[[:space:]]*\\(#.*\\)*$' < \"$series\" | sed -e 's/[[:space:]]*#.*$//'\n>  }\n>  \n> +get_guarded_series()\n> +{\n> +\tget_series | while read p\n> +\tdo\n> +\t\t[ -z `check_guards $p` ] && echo \"$p\"\n\nHaving check_guards return 0 or 1 makes things cleaner:\n\ncheck_guards \"$p\" && echo \"$p\"\n\n> +\tdone\n> +}\n> +\n> +# usage: check_guards <patch>\n> +# Returns t if the patch should be skipped\n> +check_guards()\n> +{\n> +        get_guards \"$1\" | while read guard\n> +        do\n> +                pos=`echo $guard | grep -e \"^+\"`\n> +                guard=`echo $guard | sed -e 's/[+-]//'`\n> +                if [ $pos ]; then\n> +                        # Push +guard *only if* guard selected\n> +                        push=`grep -e \"^$guard\\$\" \"$guards_file\" > /dev/null; echo $?`\n> +                        [ $push -ne 0 ] && echo t\n\n\t\t\t   [ $push -ne 0 ] && return 1\n\n> +                else\n> +                        # Push -guard *unless* guard selected\n> +                        push=`grep -e \"^$guard\\$\" \"$guards_file\" > /dev/null; echo $?`\n> +                        [ $push -eq 0 ] && echo t\n\nditto\n\n> +                fi\n> +        done\n\n\treturn 0\n> +}\n> +\n> +# usage: get_guards <patch>\n> +get_guards()\n> +{\n> +\tgrep -e \"^$1[[:space:]]*#\" < \"$series\" | sed -e \"s/^$1 //\" -e 's/#[^+-]*//g'\n> +}\n> +\n> +# usage: set_guards <patch> <guards>\n\nI'd try to make it clearer that multiple guards can be specified.\n\n> +set_guards()\n> +{\n> +\tp=\"$1\"\n> +\tshift\n> +\tfor x in \"$@\"; do\n> +\t\tif [ -z $(echo \"$x\" | grep -e \"^[+-]\") ]; then\n\nIs that the only restriction on the guard name?\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> +\t\tfi\n> +\tdone\n> +}\n> +\n> +# usage: unset_guards <patch> <guards>\n\nditto.\n\n> +unset_guards()\n> +{\n> +        p=\"$1\"\n> +        shift\n> +        for x in \"$@\"; do\n> +            sed -i -e \"/^$p[[:space:]]/s/ #$x//\" \"$series\"\n> +        done\n> +}\n> +\n>  # usage: do_make_header <hash>\n>  do_make_header()\n>  {\n> diff --git a/guilt-guards b/guilt-guards\n> new file mode 100755\n> index 0000000..71df4f8\n> --- /dev/null\n> +++ b/guilt-guards\n> @@ -0,0 +1,63 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) Eric Lesh, 2007\n> +#\n> +\n> +USAGE=\"[-l|--list] [-n|--none] [<patchname>] [+<guard>] [-<guard>]\"\n\nSince -l and -n are mutually exclusive, shouldn't it be something like:\n\n[-l|--list|-n|--none|[<patchname>] [(+|-)guard...]]\n\n> +. 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 $(echo $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\tp=`get_top`\n> +\t\t\tunset_guards \"$p\" `get_guards \"$p\"`\n> +\t\t\tset_guards \"$p\" \"$1\"\n> +\t\tfi\n> +\t\t;;\n> +\t*)\n> +\t\tif [ -z $(echo $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\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\n-- \nNote 96.3% of all statistics are fiction.\n"},{"id":"49054","messageId":"20070730041231.GE22017@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"11856954182318-git-send-email-eclesh@ucla.edu","subject":"Re: [GUILT PATCH 3/4] guilt-select: Select guards to apply when pushing patches","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T04:12:31Z","receivedAt":"2007-07-30T04:12:31Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Sun, Jul 29, 2007 at 12:50:17AM -0700, Eric Lesh wrote:\n> guilt-select chooses guards that alter which patches will be applied\n> with a guilt-push.  The selected guards are stored in\n> .git/patches/$branch/guards.\n> \n> Signed-off-by: Eric Lesh <eclesh@ucla.edu>\n> ---\n>  Documentation/guilt-select.txt |   42 ++++++++++++++++++++++++++++++++++++++++\n>  guilt                          |    1 +\n>  guilt-select                   |   36 ++++++++++++++++++++++++++++++++++\n>  3 files changed, 79 insertions(+), 0 deletions(-)\n>  create mode 100644 Documentation/guilt-select.txt\n>  create mode 100755 guilt-select\n> \n> diff --git a/Documentation/guilt-select.txt b/Documentation/guilt-select.txt\n> new file mode 100644\n> index 0000000..8e18f26\n> --- /dev/null\n> +++ b/Documentation/guilt-select.txt\n\nYou might want to update the guilt(7) page's description of the patch\ndirectory.\n\n> @@ -0,0 +1,42 @@\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> +-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[]\n> diff --git a/guilt b/guilt\n> index b2767ea..3882962 100755\n> --- a/guilt\n> +++ b/guilt\n> @@ -641,6 +641,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\"\n> diff --git a/guilt-select b/guilt-select\n> new file mode 100755\n> index 0000000..f237ef0\n> --- /dev/null\n> +++ b/guilt-select\n> @@ -0,0 +1,36 @@\n> +#!/bin/sh\n> +#\n> +# Copyright (c) Eric Lesh, 2007\n> +#\n> +\n> +USAGE=\"[-n|--none] [-s|--series] [<guard>]\"\n> + . `dirname $0`/guilt\n> +\n> +if [ $# == 0 ]; then\n> +\tif [ -s \"$guards_file\" ]; then\n> +\t\tcat \"$guards_file\"\n\nLater on, for the -s option processing, you sort (presumably to have uniq do\nthe right thing), should we sort here too to be consitent?\n\n> +\telse\n> +\t\techo \"No guards applied\"\n\nI think outputing this message to stderr might be better; it'll allow for\nredirection more easily.\n\n> +\tfi\n> +\texit 0\n> +fi\n> +\n> +case $1 in\n> +\t-n|--none)\n> +\t\trm -f \"$guards_file\"\n> +\t\ttouch \"$guards_file\"\n\nSince guilt-init doesn't create the guards file, I'm thinking that this\nshould be just a rm -f ...\n\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\tfor x in \"$@\"; do\n> +\t\t\tif [ $(echo $x | grep -e \"^[+-]\") ]; then\n> +\t\t\t\tdie \"'$x' is not a valid guard name\"\n> +\t\t\tfi\n> +\t\tdone\n> +\t\techo \"$@\" | sed -e 's/ /\\n/g' | sort | uniq > \"$guards_file\"\n> +\t\t;;\n> +esac\n> -- \n> 1.5.2\n\n-- \nThe box said \"Windows XP or better required\". So I installed Linux.\n"},{"id":"49056","messageId":"20070730041549.GF22017@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"1185695418227-git-send-email-eclesh@ucla.edu","subject":"Re: [GUILT PATCH 4/4] Use guards information and functions","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T04:15:49Z","receivedAt":"2007-07-30T04:15:49Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Sun, Jul 29, 2007 at 12:50:18AM -0700, Eric Lesh wrote:\n> Make guilt-push respect guards. Also teach guilt-header, guilt-next,\n> and guilt-unapplied to grok patches that are skipped because of\n> guards.\n> \n> Signed-off-by: Eric Lesh <eclesh@ucla.edu>\n> ---\n>  guilt-header    |    7 ++++---\n>  guilt-next      |    2 +-\n>  guilt-push      |    8 ++++----\n>  guilt-unapplied |    2 +-\n>  4 files changed, 10 insertions(+), 9 deletions(-)\n> \n> diff --git a/guilt-header b/guilt-header\n> index d07e2be..ef7f55e 100755\n> --- a/guilt-header\n> +++ b/guilt-header\n> @@ -15,15 +15,16 @@ patch=\"$1\"\n>  if [ -z \"$patch\" ]; then\n>  \t# use the patch that's on the top of the stack\n>  \n> -\teidx=`wc -l < $applied`\n> -\tif [ $eidx -eq 0 ]; then\n> +\tpatch=`get_top`\n> +\tif [ -z \"$patch\" ]; then\n>  \t\tdie \"Status file is empty\"\n>  \tfi\n> +\teidx=`get_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n>  else\n>  \t# use the specified patch\n>  \n>  \teidx=`get_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n> -\tif [ $eidx -eq 0 ]; then\n> +\tif [ -z \"$eidx\" ]; then\n>  \t\tdie \"Patch $patch is not in the series\"\n>  \tfi\n>  fi\n> diff --git a/guilt-next b/guilt-next\n> index f38f1cc..38f57fa 100755\n> --- a/guilt-next\n> +++ b/guilt-next\n> @@ -13,5 +13,5 @@ fi\n>  n=`wc -l < $applied`\n>  n=$(($n + 1))\n>  \n> -get_series | awk \"{ if (NR == $n) print \\$0}\"\n> +get_guarded_series | awk \"{ if (NR == $n) print \\$0}\"\n\nSeeing this almost makes me thing that get_series should give you the\nguarded series unless you poke it the right way...something like:\n\nget_series --full\n\nor\n\nget_full_series\n\n\nThe guarded series is what most commands care about, right?\n\n> diff --git a/guilt-push b/guilt-push\n> index ad3616b..ce928e3 100755\n> --- a/guilt-push\n> +++ b/guilt-push\n> @@ -24,7 +24,7 @@ if [ \"$patch\" = \"--all\" ] || [ \"$patch\" = \"-a\" ]; then\n>  \t# we are supposed to push all patches, get the last one out of\n>  \t# series\n>  \n> -\teidx=`get_series | wc -l`\n> +\teidx=`get_guarded_series | wc -l`\n>  \tif [ $eidx -eq 0 ]; then\n>  \t\tdie \"There are no patches to push\"\n>  \tfi\n> @@ -37,9 +37,9 @@ else\n>  \t# we're supposed to push only up to a patch, make sure the patch is\n>  \t# in the series\n>  \n> -\teidx=`get_series | grep -ne \"^$patch\\$\" | cut -d: -f1`\n> +\teidx=`get_guarded_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>  \n> @@ -52,7 +52,7 @@ fi\n>  sidx=`wc -l < $applied`\n>  sidx=`expr $sidx + 1`\n>  \n> -get_series | sed -n -e \"${sidx},${eidx}p\" | while read p\n> +get_guarded_series | sed -n -e \"${sidx},${eidx}p\" | while read p\n>  do\n>  \techo \"Applying patch..$p\"\n>  \tif [ ! -f \"$GUILT_DIR/$branch/$p\" ]; then\n> diff --git a/guilt-unapplied b/guilt-unapplied\n> index 192a7e5..6904360 100755\n> --- a/guilt-unapplied\n> +++ b/guilt-unapplied\n> @@ -13,4 +13,4 @@ fi\n>  n=`wc -l < $applied`\n>  n=`expr $n + 1`\n>  \n> -get_series | sed -n -e \"$n,\\$p\"\n> +get_guarded_series | sed -n -e \"$n,\\$p\"\n> -- \n> 1.5.2\n\n-- \nDebugging is twice as hard as writing the code in the first place.\nTherefore, if you write the code as cleverly as possible, you are, by\ndefinition, not smart enough to debug it.\n\t\t- Brian W. Kernighan \n"},{"id":"49058","messageId":"87r6mqcvzp.fsf@hubert.paunchy.net","threadId":"9285","inReplyTo":"20070730035422.GB22017@filer.fsl.cs.sunysb.edu","subject":"Re: [GUILT PATCH 1/4] get_series: Remove comments from end of series lines","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-30T05:15:54Z","receivedAt":"2007-07-30T05:15:54Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"\n[ Do you mind if these messages go to both your email addresses, or\nshould I remove one or the other? ]\n\nJosef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n\n> On Sun, Jul 29, 2007 at 12:50:15AM -0700, Eric Lesh wrote:\n> ... \n>> diff --git a/guilt b/guilt\n>> index f67bfb5..774909e 100755\n>> --- a/guilt\n>> +++ b/guilt\n>> @@ -178,7 +178,8 @@ 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>> +\tgrep -ve '^[[:space:]]*\\(#.*\\)*$' < \"$series\" | sed -e 's/[[:space:]]*#.*$//'\n>\n> I'd be tempted to replace the whole thing with one sed script...something\n> like (not tested):\n>\n> \"\n> /^[[:space:]]*#/ ! {\n> \ts/[[:space:]]*#.*$//\n>\n> \tp\n> }\n> \"\n>\n\nsed -e \"/^[[:space:]]*\\(#.*\\)*$/d\n\t/^[[:space:]]*\\(#.*\\)*$/!{\n\ts/[[:space:]]*#.*$//\n\t}\n\t\" $series\n\nis the best I can do.\n\nsed -e \"/^[[:space:]]*\\(#.*\\)*$/d\" -e \"s/[[:space:]]*#.*$//\" $series\n\nworks too, and is maybe more readable.\n\nMy sed-foo is weak, though.\n\n\tEric\n"},{"id":"49059","messageId":"20070730052633.GI22017@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"87r6mqcvzp.fsf@hubert.paunchy.net","subject":"Re: [GUILT PATCH 1/4] get_series: Remove comments from end of series lines","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T05:26:33Z","receivedAt":"2007-07-30T05:26:33Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Sun, Jul 29, 2007 at 10:15:54PM -0700, Eric Lesh wrote:\n> \n> [ Do you mind if these messages go to both your email addresses, or\n> should I remove one or the other? ]\n \nI really don't care if I get duplicates. It'll happen anyway when the git\nmailing list is cc'd. As for which address I prefer, it really doesn't\nmatter to me which one stays in Cc. I'm slowly trying to move everything\nover to @cs.\n\n> Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n> \n> > On Sun, Jul 29, 2007 at 12:50:15AM -0700, Eric Lesh wrote:\n> > ... \n> >> diff --git a/guilt b/guilt\n> >> index f67bfb5..774909e 100755\n> >> --- a/guilt\n> >> +++ b/guilt\n> >> @@ -178,7 +178,8 @@ 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> >> +\tgrep -ve '^[[:space:]]*\\(#.*\\)*$' < \"$series\" | sed -e 's/[[:space:]]*#.*$//'\n> >\n> > I'd be tempted to replace the whole thing with one sed script...something\n> > like (not tested):\n> >\n> > \"\n> > /^[[:space:]]*#/ ! {\n> > \ts/[[:space:]]*#.*$//\n> >\n> > \tp\n> > }\n> > \"\n> >\n> \n> sed -e \"/^[[:space:]]*\\(#.*\\)*$/d\n> \t/^[[:space:]]*\\(#.*\\)*$/!{\n> \ts/[[:space:]]*#.*$//\n> \t}\n> \t\" $series\n> \n> is the best I can do.\n\nI think the script I wrote is a bit cleaner as it more easily translates to:\n\nif (!ignore_line) {\n\tstrip comment\n\tprint\n}\n\nto make it work, you'd need to run sed with -n to not implicitly print the\nline.\n\nJeff.\n\n-- \nI'm somewhere between geek and normal.\n\t\t- Linus Torvalds\n"},{"id":"49064","messageId":"87k5sics0f.fsf@hubert.paunchy.net","threadId":"9285","inReplyTo":"20070730040610.GD22017@filer.fsl.cs.sunysb.edu","subject":"Re: [GUILT PATCH 2/4] guilt-guard: Assign guards to patches in series","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-30T06:41:52Z","receivedAt":"2007-07-30T06:41:52Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n\n[...]\n\n>> +get_guarded_series()\n>> +{\n>> +\tget_series | while read p\n>> +\tdo\n>> +\t\t[ -z `check_guards $p` ] && echo \"$p\"\n>\n> Having check_guards return 0 or 1 makes things cleaner:\n>\n> check_guards \"$p\" && echo \"$p\"\n>\n>> +\tdone\n>> +}\n>> +\n>> +# usage: check_guards <patch>\n>> +# Returns t if the patch should be skipped\n>> +check_guards()\n>> +{\n>> +        get_guards \"$1\" | while read guard\n>> +        do\n>> +                pos=`echo $guard | grep -e \"^+\"`\n>> +                guard=`echo $guard | sed -e 's/[+-]//'`\n>> +                if [ $pos ]; then\n>> +                        # Push +guard *only if* guard selected\n>> +                        push=`grep -e \"^$guard\\$\" \"$guards_file\" > /dev/null; echo $?`\n>> +                        [ $push -ne 0 ] && echo t\n>\n> \t\t\t   [ $push -ne 0 ] && return 1\n>\n\nThis returns from the subshell created by the pipe and the while loop,\nright?\n\nSo I'm using:\n\ncheck_guards()\n{\n\tget_guards \"$1\" | while read guard\n\tdo\n\t\tpos=`echo $guard | grep -e \"^+\"`\n\t\tguard=`echo $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; 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; echo $?`\n\t\t\t[ $push -eq 0 ] && return 1\n\t\tfi\n                return 0\n\tdone\n\treturn $?\n}\n\nwhere 1 means push.\n\n>> +# usage: get_guards <patch>\n>> +get_guards()\n>> +{\n>> +\tgrep -e \"^$1[[:space:]]*#\" < \"$series\" | sed -e \"s/^$1 //\" -e 's/#[^+-]*//g'\n>> +}\n\nShould this also be one sed script instead of a grep + sed?\n\n>> +\n>> +# usage: set_guards <patch> <guards>\n>\n> I'd try to make it clearer that multiple guards can be specified.\n>\n\nDone with <guards...> now.\n\n>> +set_guards()\n>> +{\n>> +\tp=\"$1\"\n>> +\tshift\n>> +\tfor x in \"$@\"; do\n>> +\t\tif [ -z $(echo \"$x\" | grep -e \"^[+-]\") ]; then\n>\n> Is that the only restriction on the guard name?\n>\n\nYes.  On patches, you put a '+guard' or '-guard'.  When selecting with\nguilt-select, it's just 'guard'.  The + or - just means 'apply when\nselected' or 'apply unless selected'.  You can edit things manually to\nmake guards with a space in the name, but the mechanism will work even\nin that case.\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>> +\t\tfi\n>> +\tdone\n>> +}\n>> +\n>> +# usage: unset_guards <patch> <guards>\n>\n\n[...]\n\nThe rest I'll do.  Thanks for the review.\n\n\tEric\n"},{"id":"49066","messageId":"87fy36cr25.fsf@hubert.paunchy.net","threadId":"9285","inReplyTo":"20070730041231.GE22017@filer.fsl.cs.sunysb.edu","subject":"Re: [GUILT PATCH 3/4] guilt-select: Select guards to apply when pushing patches","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-30T07:02:26Z","receivedAt":"2007-07-30T07:02:26Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n\n[...]\n\n>> +if [ $# == 0 ]; then\n>> +\tif [ -s \"$guards_file\" ]; then\n>> +\t\tcat \"$guards_file\"\n>\n> Later on, for the -s option processing, you sort (presumably to have uniq do\n> the right thing), should we sort here too to be consitent?\n>\n\nThe $guards_file isn't really meant to be handed edited, and\nguilt-select itself sorts before it stores them in the guards file.  I could\nsort it again on printing, but don't think it's necessary.\n\n>> +\n>> +case $1 in\n>> +\t-n|--none)\n>> +\t\trm -f \"$guards_file\"\n>> +\t\ttouch \"$guards_file\"\n>\n> Since guilt-init doesn't create the guards file, I'm thinking that this\n> should be just a rm -f ...\n\nShould guilt-init create it?  I added $guards_file to guilt(7), so not\nseeing it might freak Documentation-conscious readers out?\n\n\tEric\n"},{"id":"49068","messageId":"87bqducqvz.fsf@hubert.paunchy.net","threadId":"9285","inReplyTo":"20070730041549.GF22017@filer.fsl.cs.sunysb.edu","subject":"Re: [GUILT PATCH 4/4] Use guards information and functions","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-30T07:06:08Z","receivedAt":"2007-07-30T07:06:08Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n\n>> -get_series | awk \"{ if (NR == $n) print \\$0}\"\n>> +get_guarded_series | awk \"{ if (NR == $n) print \\$0}\"\n>\n> Seeing this almost makes me thing that get_series should give you the\n> guarded series unless you poke it the right way...something like:\n>\n> get_series --full\n>\n> or\n>\n> get_full_series\n>\n>\n> The guarded series is what most commands care about, right?\n>\n\nYou're right.  I'll do it with get_full_series.\n\n\tEric\n"},{"id":"49069","messageId":"877ioicqu7.fsf@hubert.paunchy.net","threadId":"9285","inReplyTo":"20070730052633.GI22017@filer.fsl.cs.sunysb.edu","subject":"Re: [GUILT PATCH 1/4] get_series: Remove comments from end of series lines","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-30T07:07:12Z","receivedAt":"2007-07-30T07:07:12Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n\n>\n> I think the script I wrote is a bit cleaner as it more easily translates to:\n>\n> if (!ignore_line) {\n> \tstrip comment\n> \tprint\n> }\n>\n> to make it work, you'd need to run sed with -n to not implicitly print the\n> line.\n>\n\nTold you my sed-foo sucks ;-)  You're right again, of course.\n\n\tEric\n"},{"id":"49079","messageId":"873az6cmve.fsf@hubert.paunchy.net","threadId":"9285","inReplyTo":"20070730035443.GC22017@filer.fsl.cs.sunysb.edu","subject":"Re: [GUILT PATCH 0/4] Add guards to guilt","fromName":"Eric Lesh","fromEmail":"eclesh@ucla.edu","sentAt":"2007-07-30T08:32:53Z","receivedAt":"2007-07-30T08:32:53Z","isPatch":true,"sender":{"key":"eclesh@ucla.edu","avatar":null},"body":"Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n\n>\n> I know I've been bad about forcing even myself to write new regression\n> tests. Your patches modify things significantly enough, that I'd like to see\n> some regression tests cases to make sure that user's data is not eaten\n> (e.g., a bug in the guard setting code could blow away the series file =>\n> very bad).\n>\n\nYeah, I'll try and make one.  070-guards.sh to test guilt-guard and\nguilt-select plus pushing and popping?\n\nThere's also sed -i in a few places. For integrity purposes, are a cp\nand sed better?\n\n>> This introduces the command `get_guarded_series`, which just lists\n>> patches that are to be applied based on the guards.  It also makes\n>>         eidx=`wc -l < $applied`\n>> inaccurate if you're using it as an index into get_series.\n>\n> The index-based patch finding is a bit nasty anyway.\n>\n>> If you change guards on a patch or select a different guard while\n>> patches are applied, some commands might get confused. guilt pop -a will fix\n>> everything though.  Usually, it's best to pop -a before fiddling with\n>> guards anyway.\n>\n> Is this a problem with other projects' implementations of guards as well?\n> Perhaps printing a warning if a new guard is set when there are applied\n> patches would be in order?\n>\n\nYeah, they have this problem too, but tell you so when you select, so\nguilt should too. I'll fix that up.  Mercurial also has two options\nwhich do the popping and reapplying for you, which I'll try and implement also.\n\nThanks a lot for the review.  Things were pretty ugly, but with your\nhelp it should look much better.\n\n\tEric\n"},{"id":"49123","messageId":"20070730192027.GB17253@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"873az6cmve.fsf@hubert.paunchy.net","subject":"Re: [GUILT PATCH 0/4] Add guards to guilt","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T19:20:27Z","receivedAt":"2007-07-30T19:20:27Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Mon, Jul 30, 2007 at 01:32:53AM -0700, Eric Lesh wrote:\n> Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n> \n> >\n> > I know I've been bad about forcing even myself to write new regression\n> > tests. Your patches modify things significantly enough, that I'd like to see\n> > some regression tests cases to make sure that user's data is not eaten\n> > (e.g., a bug in the guard setting code could blow away the series file =>\n> > very bad).\n> >\n> \n> Yeah, I'll try and make one.  070-guards.sh to test guilt-guard and\n> guilt-select plus pushing and popping?\n\nSounds good.\n\n> There's also sed -i in a few places. For integrity purposes, are a cp\n> and sed better?\n\nI like the fact that sed -i makes the code cleaner, BUT I don't want the\nusers to come after me if they patches disappear. Perhaps having a wrapper\n(a function) for sed that's nicely paranoid and handles errors as well as\npossible would be in order:\n\nsafe_sed [<sed options...>]\n\n> > Is this a problem with other projects' implementations of guards as well?\n> > Perhaps printing a warning if a new guard is set when there are applied\n> > patches would be in order?\n> >\n> \n> Yeah, they have this problem too,\n\nGood :)\n\n> but tell you so when you select, so guilt should too.\n\nAgreed.\n\n> Mercurial also has two options which do the popping and reapplying for\n> you, which I'll try and implement also.\n\nAs in:\n\nt=`guilt-top`\nguilt-pop -a\nguilt-push \"$t\"\n\n? Beware that \"$t\" might not be in the new guarded series.\n\n> Thanks a lot for the review.  Things were pretty ugly, but with your\n> help it should look much better.\n\nNah...just a few nit-picks, that's all :)\n\nJosef 'Jeff' Sipek.\n\n-- \nI think there is a world market for maybe five computers.\n\t\t- Thomas Watson, chairman of IBM, 1943.\n"},{"id":"49127","messageId":"20070730192815.GC17253@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"87k5sics0f.fsf@hubert.paunchy.net","subject":"Re: [GUILT PATCH 2/4] guilt-guard: Assign guards to patches in series","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T19:28:15Z","receivedAt":"2007-07-30T19:28:15Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Sun, Jul 29, 2007 at 11:41:52PM -0700, Eric Lesh wrote:\n> Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n> \n> [...]\n> \n> >> +get_guarded_series()\n> >> +{\n> >> +\tget_series | while read p\n> >> +\tdo\n> >> +\t\t[ -z `check_guards $p` ] && echo \"$p\"\n> >\n> > Having check_guards return 0 or 1 makes things cleaner:\n> >\n> > check_guards \"$p\" && echo \"$p\"\n> >\n> >> +\tdone\n> >> +}\n> >> +\n> >> +# usage: check_guards <patch>\n> >> +# Returns t if the patch should be skipped\n> >> +check_guards()\n> >> +{\n> >> +        get_guards \"$1\" | while read guard\n> >> +        do\n> >> +                pos=`echo $guard | grep -e \"^+\"`\n> >> +                guard=`echo $guard | sed -e 's/[+-]//'`\n> >> +                if [ $pos ]; then\n> >> +                        # Push +guard *only if* guard selected\n> >> +                        push=`grep -e \"^$guard\\$\" \"$guards_file\" > /dev/null; echo $?`\n> >> +                        [ $push -ne 0 ] && echo t\n> >\n> > \t\t\t   [ $push -ne 0 ] && return 1\n> >\n> \n> This returns from the subshell created by the pipe and the while loop,\n> right?\n\nRight, sorry.\n\n> So I'm using:\n> \n> check_guards()\n> {\n> \tget_guards \"$1\" | while read guard\n> \tdo\n> \t\tpos=`echo $guard | grep -e \"^+\"`\n> \t\tguard=`echo $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; 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; echo $?`\n> \t\t\t[ $push -eq 0 ] && return 1\n> \t\tfi\n>                 return 0\n\nBeware of whitespace :)\n\n> \tdone\n> \treturn $?\n> }\n> \n> where 1 means push.\n> \n> >> +# usage: get_guards <patch>\n> >> +get_guards()\n> >> +{\n> >> +\tgrep -e \"^$1[[:space:]]*#\" < \"$series\" | sed -e \"s/^$1 //\" -e 's/#[^+-]*//g'\n> >> +}\n> \n> Should this also be one sed script instead of a grep + sed?\n\nI'm all for more complex sed/awk scripts to replace lots of forks and pipes.\n\n> >> +\n> >> +# usage: set_guards <patch> <guards>\n> >\n> > I'd try to make it clearer that multiple guards can be specified.\n> >\n> \n> Done with <guards...> now.\n> \n> >> +set_guards()\n> >> +{\n> >> +\tp=\"$1\"\n> >> +\tshift\n> >> +\tfor x in \"$@\"; do\n> >> +\t\tif [ -z $(echo \"$x\" | grep -e \"^[+-]\") ]; then\n> >\n> > Is that the only restriction on the guard name?\n> >\n> \n> Yes.  On patches, you put a '+guard' or '-guard'.  When selecting with\n> guilt-select, it's just 'guard'.  The + or - just means 'apply when\n> selected' or 'apply unless selected'.  You can edit things manually to\n> make guards with a space in the name, but the mechanism will work even\n> in that case.\n\nI am thinking that it _might_ make sense to have some validate_guard_name\nfunction - I am not sure if it would be used enough to make it useful\ninstead of just obfuscating the code.\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> >> +\t\tfi\n> >> +\tdone\n> >> +}\n> >> +\n> >> +# usage: unset_guards <patch> <guards>\n> >\n> \n> [...]\n> \n> The rest I'll do.  Thanks for the review.\n\nThanks for the patches :)\n\nJeff.\n\n-- \nThe obvious mathematical breakthrough would be development of an easy way to\nfactor large prime numbers.\n\t\t- Bill Gates, The Road Ahead, pg. 265\n"},{"id":"49129","messageId":"20070730193418.GD17253@filer.fsl.cs.sunysb.edu","threadId":"9285","inReplyTo":"87fy36cr25.fsf@hubert.paunchy.net","subject":"Re: [GUILT PATCH 3/4] guilt-select: Select guards to apply when pushing patches","fromName":"Josef Sipek","fromEmail":"jsipek@fsl.cs.sunysb.edu","sentAt":"2007-07-30T19:34:18Z","receivedAt":"2007-07-30T19:34:18Z","isPatch":true,"sender":{"key":"jsipek@fsl.cs.sunysb.edu","avatar":null},"body":"On Mon, Jul 30, 2007 at 12:02:26AM -0700, Eric Lesh wrote:\n> Josef Sipek <jsipek@fsl.cs.sunysb.edu> writes:\n> \n> [...]\n> \n> >> +if [ $# == 0 ]; then\n> >> +\tif [ -s \"$guards_file\" ]; then\n> >> +\t\tcat \"$guards_file\"\n> >\n> > Later on, for the -s option processing, you sort (presumably to have uniq do\n> > the right thing), should we sort here too to be consitent?\n> >\n> \n> The $guards_file isn't really meant to be handed edited, and\n> guilt-select itself sorts before it stores them in the guards file.  I could\n> sort it again on printing, but don't think it's necessary.\n \nDuh. No need to re-sort.\n\n> >> +\n> >> +case $1 in\n> >> +\t-n|--none)\n> >> +\t\trm -f \"$guards_file\"\n> >> +\t\ttouch \"$guards_file\"\n> >\n> > Since guilt-init doesn't create the guards file, I'm thinking that this\n> > should be just a rm -f ...\n> \n> Should guilt-init create it?  I added $guards_file to guilt(7), so not\n> seeing it might freak Documentation-conscious readers out?\n\nI'm thinking that it would be nice to have the file created when the first\nguard is set, and removed when the last guard is removed. This way, if you\ndon't care about guards, you don't have to ignore the file (if you have your\npatches dir under version control). This also happens to be the nicer way to\ntransition from pre-guard patch dirs to ones with guards - in a way it's\ncheating around \"upgrading\" the repo :)\n\nI'd like this lazy creation to be documented, of course to not confuse the\nhandful that actually read the docs :)\n\nJeff.\n\n-- \nLinux, n.:\n  Generous programmers from around the world all join forces to help\n  you shoot yourself in the foot for free. \n"}]}