{"thread":{"id":"13503","subject":"StGit: kha/{safe,experimental} updated","startedAt":"2008-05-14T01:43:09Z","lastAt":"2008-05-21T15:00:26Z","messageCount":16,"participants":["Karl Hasselström","David Kågedal","Catalin Marinas"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"76902","messageId":"20080514014309.GA17955@diana.vm.bytemark.co.uk","threadId":"13503","inReplyTo":null,"subject":"StGit: kha/{safe,experimental} updated","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-14T01:43:09Z","receivedAt":"2008-05-14T01:43:09Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"kha/safe has improved version handling: \"stg --version\" will now\npresent a detailed version number just like git does:\n\n  $ stg --version\n  Stacked GIT 0.14.2.152.g77bd\n\nkha/safe also has an improvement/bugfix to the emacs mode: it will\nautomatically cd up to the root of your worktree, just like git's\nemacs mode has done since forever.\n\nkha/experimental has a new command, stg redo. The combination undo +\nredo makes it easy to move back and forth in the patch stack history.\n\n                                 -+-\n\nThe following changes since commit d9b2f20a72706d6b4f553a8a8e25bd67f87ed616:\n  Karl Hasselström (1):\n        Use test_cmp instead of diff -u in the test suite\n\nare available in the git repository at:\n\n  git://repo.or.cz/stgit/kha.git safe\n\nKarl Hasselström (4):\n      Remove \"stg\" from start of log messages\n      Import version to a separate namespace\n      Better StGit version tracking\n      Emacs mode: automatically cd up to root of worktree\n\n contrib/stgit.el           |   13 ++++++++++-\n setup.py                   |   14 ++++++-----\n stgit/.gitignore           |    1 +\n stgit/commands/clean.py    |    2 +-\n stgit/commands/coalesce.py |    2 +-\n stgit/commands/commit.py   |    2 +-\n stgit/commands/edit.py     |    2 +-\n stgit/commands/goto.py     |    2 +-\n stgit/commands/uncommit.py |    2 +-\n stgit/version.py           |   52 +++++++++++++++++++++++++++++++++++++++++++-\n 10 files changed, 78 insertions(+), 14 deletions(-)\n\n\n                                 -+-\n\n\nThe following changes since commit 52144ce5f2bfb1268aee4a9999821987f8892dbf:\n  Karl Hasselström (1):\n        Emacs mode: automatically cd up to root of worktree\n\nare available in the git repository at:\n\n  git://repo.or.cz/stgit/kha.git experimental\n\nKarl Hasselström (20):\n      Disable patchlog test for \"stg new\"\n      Convert \"stg new\" to the new infrastructure\n      Refactor --author/--committer options\n      Let \"stg new\" support more message options\n      Emacs mode: use \"stg new --file\"\n      Convert \"stg delete\" to the new infrastructure\n      Emacs mode: delete patches\n      Prevent most commands from running when there are conflicts\n      Add property with a list of all patch names\n      Library functions for tree and blob manipulation\n      Write to a stack log when stack is modified\n      Add utility function for reordering patches\n      New command: stg reset\n      Log conflicts separately\n      Log conflicts separately for all commands\n      Add a --hard flag to stg reset\n      Don't write a log entry if there were no changes\n      Move stack reset function to a shared location\n      New command: stg undo\n      New command: stg redo\n\n contrib/stgit.el           |   33 ++++--\n stgit/commands/branch.py   |   19 ++-\n stgit/commands/clean.py    |    2 +-\n stgit/commands/coalesce.py |    6 +-\n stgit/commands/commit.py   |   13 ++-\n stgit/commands/common.py   |   41 +++----\n stgit/commands/delete.py   |   76 +++++--------\n stgit/commands/diff.py     |    2 +-\n stgit/commands/edit.py     |   28 +----\n stgit/commands/export.py   |    2 +-\n stgit/commands/files.py    |    2 +-\n stgit/commands/id.py       |    2 +-\n stgit/commands/log.py      |    2 +-\n stgit/commands/mail.py     |    2 +-\n stgit/commands/new.py      |   97 +++++++++-------\n stgit/commands/patches.py  |    2 +-\n stgit/commands/redo.py     |   52 +++++++++\n stgit/commands/reset.py    |   61 ++++++++++\n stgit/commands/series.py   |    2 +-\n stgit/commands/show.py     |    2 +-\n stgit/commands/status.py   |    3 +-\n stgit/commands/top.py      |    2 +-\n stgit/commands/uncommit.py |    5 +-\n stgit/commands/undo.py     |   49 ++++++++\n stgit/lib/git.py           |  154 +++++++++++++++++++++-----\n stgit/lib/log.py           |  265 ++++++++++++++++++++++++++++++++++++++++++++\n stgit/lib/stack.py         |    8 ++\n stgit/lib/transaction.py   |   93 ++++++++++++---\n stgit/main.py              |    8 ++\n stgit/utils.py             |   50 ++++++++\n t/t1400-patch-history.sh   |    2 -\n t/t1600-delete-one.sh      |    8 +-\n t/t3100-reset.sh           |  151 +++++++++++++++++++++++++\n t/t3101-reset-hard.sh      |   56 +++++++++\n t/t3102-undo.sh            |   86 ++++++++++++++\n t/t3103-undo-hard.sh       |   56 +++++++++\n t/t3104-redo.sh            |  122 ++++++++++++++++++++\n 37 files changed, 1339 insertions(+), 225 deletions(-)\n create mode 100644 stgit/commands/redo.py\n create mode 100644 stgit/commands/reset.py\n create mode 100644 stgit/commands/undo.py\n create mode 100644 stgit/lib/log.py\n create mode 100755 t/t3100-reset.sh\n create mode 100755 t/t3101-reset-hard.sh\n create mode 100755 t/t3102-undo.sh\n create mode 100755 t/t3103-undo-hard.sh\n create mode 100755 t/t3104-redo.sh\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"76903","messageId":"20080514014450.7043.20656.stgit@yoghurt","threadId":"13503","inReplyTo":"20080514014309.GA17955@diana.vm.bytemark.co.uk","subject":"[StGit PATCH 1/2] Import version to a separate namespace","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-14T01:44:56Z","receivedAt":"2008-05-14T01:44:56Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"The set of names we need from the version module is about to get too\nlarge to list explicitly, but we don't want to pollute the local\nnamespace with every name from version. So do a qualified import of\nthe module.\n\nSigned-off-by: Karl Hasselström <kha@treskal.com>\n\n---\n\n setup.py |   12 ++++++------\n 1 files changed, 6 insertions(+), 6 deletions(-)\n\n\ndiff --git a/setup.py b/setup.py\nindex 3be087c..04ca821 100755\n--- a/setup.py\n+++ b/setup.py\n@@ -3,7 +3,7 @@\n import sys, glob, os\n from distutils.core import setup\n \n-from stgit.version import version, git_min_ver, python_min_ver\n+from stgit import version\n from stgit.run import Run\n \n def __version_to_list(version):\n@@ -29,18 +29,18 @@ def __check_python_version():\n     \"\"\"Check the minimum Python version\n     \"\"\"\n     pyver = '.'.join(str(n) for n in sys.version_info)\n-    if not __check_min_version(python_min_ver, pyver):\n+    if not __check_min_version(version.python_min_ver, pyver):\n         print >> sys.stderr, 'Python version %s or newer required. Found %s' \\\n-              % (python_min_ver, pyver)\n+              % (version.python_min_ver, pyver)\n         sys.exit(1)\n \n def __check_git_version():\n     \"\"\"Check the minimum GIT version\n     \"\"\"\n     gitver = Run('git', '--version').output_one_line().split()[2]\n-    if not __check_min_version(git_min_ver, gitver):\n+    if not __check_min_version(version.git_min_ver, gitver):\n         print >> sys.stderr, 'GIT version %s or newer required. Found %s' \\\n-              % (git_min_ver, gitver)\n+              % (version.git_min_ver, gitver)\n         sys.exit(1)\n \n # Check the minimum versions required\n@@ -52,7 +52,7 @@ if sys.argv[1] in ['install', 'build']:\n old_mask = os.umask(0022)\n \n setup(name = 'stgit',\n-      version = version,\n+      version = version.version,\n       license = 'GPLv2',\n       author = 'Catalin Marinas',\n       author_email = 'catalin.marinas@gmail.com',\n"},{"id":"76904","messageId":"20080514014502.7043.44236.stgit@yoghurt","threadId":"13503","inReplyTo":"20080514014309.GA17955@diana.vm.bytemark.co.uk","subject":"[StGit PATCH 2/2] Better StGit version tracking","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-14T01:47:00Z","receivedAt":"2008-05-14T01:47:00Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"Instead of claiming to be the latest released version (really, a\nhardcoded string that we hope is the latest released version), run git\ndescribe to figure out what version we are, just like git does. Fall\nback to a hardcoded value that is generated at install time, or\nsupplied in a release tarball.\n\nCurrently, we have to give git describe the --tags flag, since StGit\nrelease tags are lightweight tags. This means we're going to pick up\nany lightweight tags the user makes, which isn't ideal. The solution\nis to start making annotated release tags, and then remove that flag.\n\nSigned-off-by: Karl Hasselström <kha@treskal.com>\n\n---\n\nCatalin, you might want to pay extra attention the first time you\nrelease something with this in it. Making sure that\nstgit/builtin_version.py is included in the tarball, for example.\n\n setup.py         |    2 ++\n stgit/.gitignore |    1 +\n stgit/version.py |   52 +++++++++++++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 54 insertions(+), 1 deletions(-)\n\n\ndiff --git a/setup.py b/setup.py\nindex 04ca821..40022a7 100755\n--- a/setup.py\n+++ b/setup.py\n@@ -48,6 +48,8 @@ if sys.argv[1] in ['install', 'build']:\n     __check_python_version()\n     __check_git_version()\n \n+version.write_builtin_version()\n+\n # ensure readable template files\n old_mask = os.umask(0022)\n \ndiff --git a/stgit/.gitignore b/stgit/.gitignore\nindex 0d20b64..4f9c8f1 100644\n--- a/stgit/.gitignore\n+++ b/stgit/.gitignore\n@@ -1 +1,2 @@\n *.pyc\n+/builtin_version.py\ndiff --git a/stgit/version.py b/stgit/version.py\nindex 06ac723..8ee5009 100644\n--- a/stgit/version.py\n+++ b/stgit/version.py\n@@ -1,4 +1,54 @@\n-version = '0.14.2'\n+from stgit.exception import StgException\n+from stgit import run, utils\n+import os.path, re, sys\n+\n+class VersionUnavailable(StgException):\n+    pass\n+\n+def git_describe_version():\n+    path = sys.path[0]\n+    try:\n+        v = run.Run('git', 'describe', '--tags', '--abbrev=4'\n+                    ).cwd(path).output_one_line()\n+    except run.RunException, e:\n+        raise VersionUnavailable(str(e))\n+    if not re.match(r'^v[0-9]', v):\n+        raise VersionUnavailable('%s: bad version' % v)\n+    try:\n+        dirty = run.Run('git', 'diff-index', '--name-only', 'HEAD'\n+                        ).cwd(path).raw_output()\n+    except run.RunException, e:\n+        raise VersionUnavailable(str(e))\n+    if dirty:\n+        v += '-dirty'\n+    return re.sub('-', '.', utils.strip_prefix('v', v))\n+\n+def builtin_version():\n+    try:\n+        import builtin_version as bv\n+    except ImportError:\n+        raise VersionUnavailable()\n+    else:\n+        return bv.version\n+\n+def write_builtin_version():\n+    try:\n+        v = git_describe_version()\n+    except VersionUnavailable:\n+        return\n+    f = file(os.path.join(sys.path[0], 'stgit', 'builtin_version.py'), 'w')\n+    f.write('# This file was generated automatically. Do not edit by hand.\\n'\n+            'version = %r\\n' % v)\n+\n+def get_version():\n+    for v in [git_describe_version, builtin_version]:\n+        try:\n+            return v()\n+        except VersionUnavailable:\n+            pass\n+    return 'unknown-version'\n+\n+version = get_version()\n \n # minimum version requirements\n git_min_ver = '1.5.2'\n"},{"id":"76906","messageId":"20080514014820.7140.28591.stgit@yoghurt","threadId":"13503","inReplyTo":"20080514014309.GA17955@diana.vm.bytemark.co.uk","subject":"[StGit PATCH] Emacs mode: automatically cd up to root of worktree","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-14T01:49:09Z","receivedAt":"2008-05-14T01:49:09Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"git's emacs mode automatically finds the root of the worktree, so that\nthe user doesn't have to. Teach StGit's emacs mode the same trick by\nborrowing the git-get-top-dir function from git.\n\nThe borrowed code was written by Alexandre Julliard <julliard@winehq.org>.\n\nSigned-off-by: Karl Hasselström <kha@treskal.com>\n\n---\n\nDavid, would you sanity check this for me?\n\n contrib/stgit.el |   13 ++++++++++++-\n 1 files changed, 12 insertions(+), 1 deletions(-)\n\n\ndiff --git a/contrib/stgit.el b/contrib/stgit.el\nindex 339ef13..2a6fee3 100644\n--- a/contrib/stgit.el\n+++ b/contrib/stgit.el\n@@ -12,9 +12,20 @@\n (defun stgit (dir)\n   \"Manage stgit patches\"\n   (interactive \"DDirectory: \\n\")\n-  (switch-to-stgit-buffer dir)\n+  (switch-to-stgit-buffer (git-get-top-dir dir))\n   (stgit-refresh))\n \n+(defun git-get-top-dir (dir)\n+  \"Retrieve the top-level directory of a git tree.\"\n+  (let ((cdup (with-output-to-string\n+                (with-current-buffer standard-output\n+                  (cd dir)\n+                  (unless (eq 0 (call-process \"git\" nil t nil\n+                                              \"rev-parse\" \"--show-cdup\"))\n+                    (error \"cannot find top-level git tree for %s.\" dir))))))\n+    (expand-file-name (concat (file-name-as-directory dir)\n+                              (car (split-string cdup \"\\n\"))))))\n+\n (defun switch-to-stgit-buffer (dir)\n   \"Switch to a (possibly new) buffer displaying StGit patches for DIR\"\n   (setq dir (file-name-as-directory dir))\n"},{"id":"76907","messageId":"20080514014934.7235.19766.stgit@yoghurt","threadId":"13503","inReplyTo":"20080514014309.GA17955@diana.vm.bytemark.co.uk","subject":"[StGit PATCH] New command: stg redo","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-14T01:49:34Z","receivedAt":"2008-05-14T01:49:34Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"Command for undoing an undo.\n\nSigned-off-by: Karl Hasselström <kha@treskal.com>\n\n---\n\n stgit/commands/redo.py |   21 +++++++++------\n stgit/lib/log.py       |   19 ++++++++++----\n stgit/main.py          |    2 +\n t/t3104-redo.sh        |   66 +++++++++++++++++++++++++++++++++++++-----------\n 4 files changed, 79 insertions(+), 29 deletions(-)\n copy stgit/commands/{undo.py => redo.py} (71%)\n copy t/{t3102-undo.sh => t3104-redo.sh} (53%)\n\n\ndiff --git a/stgit/commands/undo.py b/stgit/commands/redo.py\nsimilarity index 71%\ncopy from stgit/commands/undo.py\ncopy to stgit/commands/redo.py\nindex b1d7de9..47221a5 100644\n--- a/stgit/commands/undo.py\n+++ b/stgit/commands/redo.py\n@@ -19,28 +19,31 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n \n from optparse import make_option\n from stgit.commands import common\n-from stgit.lib import git, log, transaction\n-from stgit.out import out\n+from stgit.lib import log, transaction\n \n-help = 'undo the last operation'\n+help = 'undo the last undo operation'\n usage = \"\"\"%prog [options]\n \n-Reset the patch stack to the previous state. Consecutive invocations\n-of \"stg undo\" will take you ever further into the past.\"\"\"\n+If the last command was an undo, reset the patch stack to the state it\n+had before the undo. Consecutive invocations of \"stg redo\" will undo\n+the effects of consecutive invocations of \"stg undo\".\n+\n+It is an error to run \"stg redo\" if the last command was not an\n+undo.\"\"\"\n \n directory = common.DirectoryHasRepositoryLib()\n options = [make_option('-n', '--number', type = 'int', metavar = 'N',\n                        default = 1,\n-                       help = 'undo the last N commands'),\n+                       help = 'undo the last N undos'),\n            make_option('--hard', action = 'store_true',\n                        help = 'discard changes in your index/worktree')]\n \n def func(parser, options, args):\n     stack = directory.repository.current_stack\n     if options.number < 1:\n-        raise common.CmdException('Bad number of commands to undo')\n-    state = log.undo_state(stack, options.number)\n-    trans = transaction.StackTransaction(stack, 'undo %d' % options.number,\n+        raise common.CmdException('Bad number of undos to redo')\n+    state = log.undo_state(stack, -options.number)\n+    trans = transaction.StackTransaction(stack, 'redo %d' % options.number,\n                                          discard_changes = options.hard)\n     try:\n         log.reset_stack(trans, stack.repository.default_iw, state, [])\ndiff --git a/stgit/lib/log.py b/stgit/lib/log.py\nindex a82d4bc..d2a2ba7 100644\n--- a/stgit/lib/log.py\n+++ b/stgit/lib/log.py\n@@ -243,13 +243,22 @@ def reset_stack(trans, iw, state, only_patches):\n def undo_state(stack, undo_steps):\n     ref = log_ref(stack.name)\n     log = Log(stack.repository, ref, stack.repository.refs.get(ref))\n-    while undo_steps > 0:\n+    while undo_steps != 0:\n         msg = log.commit.data.message.strip()\n-        m = re.match(r'^undo\\s+(\\d+)$', msg)\n-        if m:\n-            undo_steps += int(m.group(1))\n+        um = re.match(r'^undo\\s+(\\d+)$', msg)\n+        if undo_steps > 0:\n+            if um:\n+                undo_steps += int(um.group(1))\n+            else:\n+                undo_steps -= 1\n         else:\n-            undo_steps -= 1\n+            rm = re.match(r'^redo\\s+(\\d+)$', msg)\n+            if um:\n+                undo_steps += 1\n+            elif rm:\n+                undo_steps -= int(rm.group(1))\n+            else:\n+                raise LogException('No more redo information available')\n         if not log.parents:\n             raise LogException('Not enough undo information available')\n         log = Log(stack.repository, log.parents[0].sha1, log.parents[0])\ndiff --git a/stgit/main.py b/stgit/main.py\nindex cf7b404..c53abf7 100644\n--- a/stgit/main.py\n+++ b/stgit/main.py\n@@ -86,6 +86,7 @@ commands = Commands({\n     'pull':             'pull',\n     'push':             'push',\n     'rebase':           'rebase',\n+    'redo':             'redo',\n     'refresh':          'refresh',\n     'rename':           'rename',\n     'repair':           'repair',\n@@ -123,6 +124,7 @@ stackcommands = (\n     'pull',\n     'push',\n     'rebase',\n+    'redo',\n     'repair',\n     'reset',\n     'series',\ndiff --git a/t/t3102-undo.sh b/t/t3104-redo.sh\nsimilarity index 53%\ncopy from t/t3102-undo.sh\ncopy to t/t3104-redo.sh\nindex 1093f70..290fc6f 100755\n--- a/t/t3102-undo.sh\n+++ b/t/t3104-redo.sh\n@@ -1,6 +1,6 @@\n #!/bin/sh\n \n-test_description='Simple test cases for \"stg undo\"'\n+test_description='Simple test cases for \"stg redo\"'\n \n . ./test-lib.sh\n \n@@ -20,18 +20,18 @@ test_expect_success 'Initialize StGit stack with three patches' '\n     git commit -a -m p2 &&\n     echo 333 >> a &&\n     git commit -a -m p3 &&\n-    stg uncommit -n 3 &&\n-    stg pop\n+    stg uncommit -n 3\n '\n \n cat > expected.txt <<EOF\n 000\n 111\n+222\n EOF\n test_expect_success 'Pop one patch ...' '\n     stg pop &&\n-    test \"$(echo $(stg applied))\" = \"p1\" &&\n-    test \"$(echo $(stg unapplied))\" = \"p2 p3\" &&\n+    test \"$(echo $(stg applied))\" = \"p1 p2\" &&\n+    test \"$(echo $(stg unapplied))\" = \"p3\" &&\n     test_cmp expected.txt a\n '\n \n@@ -39,9 +39,22 @@ cat > expected.txt <<EOF\n 000\n 111\n 222\n+333\n EOF\n-test_expect_success '... and undo it' '\n+test_expect_success '... undo it ...' '\n     stg undo &&\n+    test \"$(echo $(stg applied))\" = \"p1 p2 p3\" &&\n+    test \"$(echo $(stg unapplied))\" = \"\" &&\n+    test_cmp expected.txt a\n+'\n+\n+cat > expected.txt <<EOF\n+000\n+111\n+222\n+EOF\n+test_expect_success '... and redo' '\n+    stg redo &&\n     test \"$(echo $(stg applied))\" = \"p1 p2\" &&\n     test \"$(echo $(stg unapplied))\" = \"p3\" &&\n     test_cmp expected.txt a\n@@ -50,7 +63,9 @@ test_expect_success '... and undo it' '\n cat > expected.txt <<EOF\n 000\n EOF\n-test_expect_success 'Pop two patches ...' '\n+test_expect_success 'Pop three patches ...' '\n+    stg push &&\n+    stg pop &&\n     stg pop &&\n     stg pop &&\n     test \"$(echo $(stg applied))\" = \"\" &&\n@@ -62,24 +77,45 @@ cat > expected.txt <<EOF\n 000\n 111\n 222\n+333\n EOF\n-test_expect_success '... and undo it' '\n+test_expect_success '... undo it ...' '\n     stg undo &&\n     stg undo &&\n-    test \"$(echo $(stg applied))\" = \"p1 p2\" &&\n-    test \"$(echo $(stg unapplied))\" = \"p3\" &&\n+    stg undo &&\n+    test \"$(echo $(stg applied))\" = \"p1 p2 p3\" &&\n+    test \"$(echo $(stg unapplied))\" = \"\" &&\n     test_cmp expected.txt a\n '\n \n cat > expected.txt <<EOF\n 000\n 111\n-222\n EOF\n-test_expect_success 'Undo past end of history' '\n-    ! stg undo -n 100 &&\n-    test \"$(echo $(stg applied))\" = \"p1 p2\" &&\n-    test \"$(echo $(stg unapplied))\" = \"p3\" &&\n+test_expect_success '... redo the first two pops ...' '\n+    stg redo -n 2 &&\n+    test \"$(echo $(stg applied))\" = \"p1\" &&\n+    test \"$(echo $(stg unapplied))\" = \"p2 p3\" &&\n+    test_cmp expected.txt a\n+'\n+\n+cat > expected.txt <<EOF\n+000\n+EOF\n+test_expect_success '... and the remaining one' '\n+    stg redo &&\n+    test \"$(echo $(stg applied))\" = \"\" &&\n+    test \"$(echo $(stg unapplied))\" = \"p1 p2 p3\" &&\n+    test_cmp expected.txt a\n+'\n+\n+cat > expected.txt <<EOF\n+000\n+EOF\n+test_expect_success 'Redo past end of history' '\n+    ! stg redo &&\n+    test \"$(echo $(stg applied))\" = \"\" &&\n+    test \"$(echo $(stg unapplied))\" = \"p1 p2 p3\" &&\n     test_cmp expected.txt a\n '\n \n"},{"id":"76924","messageId":"87r6c5uyhb.fsf@lysator.liu.se","threadId":"13503","inReplyTo":"20080514014820.7140.28591.stgit@yoghurt","subject":"Re: [StGit PATCH] Emacs mode: automatically cd up to root of worktree","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2008-05-14T07:38:24Z","receivedAt":"2008-05-14T07:38:24Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"Karl Hasselström <kha@treskal.com> writes:\n\n> git's emacs mode automatically finds the root of the worktree, so that\n> the user doesn't have to. Teach StGit's emacs mode the same trick by\n> borrowing the git-get-top-dir function from git.\n>\n> The borrowed code was written by Alexandre Julliard <julliard@winehq.org>.\n>\n> Signed-off-by: Karl Hasselström <kha@treskal.com>\n\nSigned-off-by: David Kågedal <davidk@lysator.liu.se>\n\nExcellent. It's an itch that I've been meaning to scratch for some time.\n\n-- \nDavid Kågedal\n"},{"id":"76928","messageId":"20080514081321.GB21708@diana.vm.bytemark.co.uk","threadId":"13503","inReplyTo":"87r6c5uyhb.fsf@lysator.liu.se","subject":"Re: [StGit PATCH] Emacs mode: automatically cd up to root of worktree","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-14T08:13:21Z","receivedAt":"2008-05-14T08:13:21Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-05-14 09:38:24 +0200, David Kågedal wrote:\n\n> Karl Hasselström <kha@treskal.com> writes:\n>\n> > git's emacs mode automatically finds the root of the worktree, so\n> > that the user doesn't have to. Teach StGit's emacs mode the same\n> > trick by borrowing the git-get-top-dir function from git.\n> >\n> > The borrowed code was written by Alexandre Julliard\n> > <julliard@winehq.org>.\n> >\n> > Signed-off-by: Karl Hasselström <kha@treskal.com>\n>\n> Signed-off-by: David Kågedal <davidk@lysator.liu.se>\n\nI guess you mean \"Acked-by\"?\n\n> Excellent. It's an itch that I've been meaning to scratch for some\n> time.\n\nMe too. I've gotten into the habit of running \"C-x b *stgit*\" to get\nto the StGit buffer, just so I don't have to give the right directory\nevery time.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"77294","messageId":"b0943d9e0805191421n1ca676dai1b3ed7d6eb1df5f4@mail.gmail.com","threadId":"13503","inReplyTo":"20080514014309.GA17955@diana.vm.bytemark.co.uk","subject":"Re: StGit: kha/{safe,experimental} updated","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-05-19T21:21:17Z","receivedAt":"2008-05-19T21:21:17Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 14/05/2008, Karl Hasselström <kha@treskal.com> wrote:\n> kha/safe has improved version handling: \"stg --version\" will now\n>  present a detailed version number just like git does:\n>\n>   $ stg --version\n>   Stacked GIT 0.14.2.152.g77bd\n\nThanks, I merged this patch. I create a similar patch some weeks ago\n(just some naming differences and only use the id of the HEAD) but\nwent on holiday + a conference and forgot about it. Anyway, yours\nlooks fine but I'll modify it slightly to use just 0.14.2 if a file\nnamed \".release\" exists in the working directory. I did this with my\npatch to allow building of release tarballs without the git\ninformation. Do you have any better suggestion?\n\n-- \nCatalin\n"},{"id":"77311","messageId":"20080520070441.GB7324@diana.vm.bytemark.co.uk","threadId":"13503","inReplyTo":"b0943d9e0805191421n1ca676dai1b3ed7d6eb1df5f4@mail.gmail.com","subject":"Re: StGit: kha/{safe,experimental} updated","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-20T07:04:41Z","receivedAt":"2008-05-20T07:04:41Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-05-19 22:21:17 +0100, Catalin Marinas wrote:\n\n> On 14/05/2008, Karl Hasselström <kha@treskal.com> wrote:\n>\n> > kha/safe has improved version handling: \"stg --version\" will now\n> > present a detailed version number just like git does:\n> >\n> >   $ stg --version\n> >   Stacked GIT 0.14.2.152.g77bd\n>\n> Thanks, I merged this patch. I create a similar patch some weeks ago\n> (just some naming differences and only use the id of the HEAD) but\n> went on holiday + a conference and forgot about it. Anyway, yours\n> looks fine but I'll modify it slightly to use just 0.14.2 if a file\n> named \".release\" exists in the working directory. I did this with my\n> patch to allow building of release tarballs without the git\n> information. Do you have any better suggestion?\n\nThe system I built works like this at install time:\n\n  i1. Create stgit/builtin_version.py, populated with git-describe\n      output.\n\n  i2. Install as usual.\n\nAnd at runtime:\n\n  r1. If we have a .git directory, ask git what version we are.\n      (Actually, we just try to run git describe and see if it\n      succeeds.)\n\n  r2. Otherwise, go with the built-in version (only works if\n      stgit/builtin_version.py exists).\n\nNow, as to released versions, you could simply plop a suitably\nprepared stgit/builtin_version.py in the tarball, and it'll all work.\ni1 should fail silently when run from an unpacked tarball, so i2 will\npick up the builtin_version.py from the tarball. And at runtime, r1\nwill fail and we'll fall back to r2.\n\nOh, and please consider making annotated release tags in the future.\nAs is, I had to ask git-describe to look at unannotated tags as well,\nwhich won't be so good in case a developer uses those as a scratch pad\nwhile developing.\n\n( The reason to do r1 before r2 is that otherwise an StGit tree will\n  \"stick\" with the version it had at the time the last installation\n  was run from that tree. We might fix that if we make sure to delete\n  builtin_version.py immediately after the installation. That's\n  desirable since any installed version of StGit currently runs\n  git-describe unnecessarily. )\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"77328","messageId":"b0943d9e0805201019x10bf87ecr1c11c8ee474f6138@mail.gmail.com","threadId":"13503","inReplyTo":"20080520070441.GB7324@diana.vm.bytemark.co.uk","subject":"Re: StGit: kha/{safe,experimental} updated","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-05-20T17:19:02Z","receivedAt":"2008-05-20T17:19:02Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"2008/5/20 Karl Hasselström <kha@treskal.com>:\n> The system I built works like this at install time:\n>\n>  i1. Create stgit/builtin_version.py, populated with git-describe\n>      output.\n>\n>  i2. Install as usual.\n\nFine (with some notes for releases, see below).\n\n> And at runtime:\n>\n>  r1. If we have a .git directory, ask git what version we are.\n>      (Actually, we just try to run git describe and see if it\n>      succeeds.)\n>\n>  r2. Otherwise, go with the built-in version (only works if\n>      stgit/builtin_version.py exists).\n\nOK.\n\n> Now, as to released versions, you could simply plop a suitably\n> prepared stgit/builtin_version.py in the tarball, and it'll all work.\n> i1 should fail silently when run from an unpacked tarball, so i2 will\n> pick up the builtin_version.py from the tarball. And at runtime, r1\n> will fail and we'll fall back to r2.\n\nI build release tarball from the directory under Git control and I\nalways get a builtin_version.py generated. In my initial patch I had a\ncheck in setup.py for a .release file. I could add a check in\nwrite_builtin_version to ignore the extra .git stuff if I am making a\nrelease (only keep the tag name).\n\nAnother alternative is to check for the number of commits from the\nlatest tag and, if this is 0, simply ignore the Git id.\n\nBTW, Git seems to use 6 characters for the current commit id and StGIT\n5. Should we change this for consistency?\n\n> Oh, and please consider making annotated release tags in the future.\n> As is, I had to ask git-describe to look at unannotated tags as well,\n> which won't be so good in case a developer uses those as a scratch pad\n> while developing.\n\nI always thought annotated tags are created by default. I'll do this\nfrom now on.\n\n-- \nCatalin\n"},{"id":"77346","messageId":"20080520210249.GA19465@diana.vm.bytemark.co.uk","threadId":"13503","inReplyTo":"b0943d9e0805201019x10bf87ecr1c11c8ee474f6138@mail.gmail.com","subject":"Re: StGit: kha/{safe,experimental} updated","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-20T21:02:49Z","receivedAt":"2008-05-20T21:02:49Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-05-20 18:19:02 +0100, Catalin Marinas wrote:\n\n> 2008/5/20 Karl Hasselström <kha@treskal.com>:\n>\n> > The system I built works like this at install time:\n> >\n> >  i1. Create stgit/builtin_version.py, populated with git-describe\n> >      output.\n> >\n> >  i2. Install as usual.\n>\n> Fine (with some notes for releases, see below).\n>\n> > And at runtime:\n> >\n> >  r1. If we have a .git directory, ask git what version we are.\n> >      (Actually, we just try to run git describe and see if it\n> >      succeeds.)\n> >\n> >  r2. Otherwise, go with the built-in version (only works if\n> >      stgit/builtin_version.py exists).\n>\n> OK.\n>\n> > Now, as to released versions, you could simply plop a suitably\n> > prepared stgit/builtin_version.py in the tarball, and it'll all\n> > work. i1 should fail silently when run from an unpacked tarball,\n> > so i2 will pick up the builtin_version.py from the tarball. And at\n> > runtime, r1 will fail and we'll fall back to r2.\n>\n> I build release tarball from the directory under Git control and I\n> always get a builtin_version.py generated. In my initial patch I had\n> a check in setup.py for a .release file. I could add a check in\n> write_builtin_version to ignore the extra .git stuff if I am making\n> a release (only keep the tag name).\n\nNah, easier to just change the order of the checks (try r2 before r1)\nas I outlined. I'll whip up a patch.\n\n> Another alternative is to check for the number of commits from the\n> latest tag and, if this is 0, simply ignore the Git id.\n\nIf you're exactly on a tagged commit, git-describe will return just\nthe name of that tag, so you don't need to do anything extra.\n\n> BTW, Git seems to use 6 characters for the current commit id and\n> StGIT 5. Should we change this for consistency?\n\nBoth git and we call git-describe with --abbrev=4, which I think means\n\"describe the commit uniquely with as few digits as possible, but no\nless than four\". So we'll get upgraded automatically when it becomes\nnecessary.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"77348","messageId":"20080520213844.13410.32757.stgit@yoghurt","threadId":"13503","inReplyTo":"20080520210249.GA19465@diana.vm.bytemark.co.uk","subject":"[StGit PATCH] Try the built-in version string before git-describe","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-20T21:39:43Z","receivedAt":"2008-05-20T21:39:43Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"Try to get the built-in version string first, and fall back to git\ndescribe if there is no built-in string, instead of the other way\naround. This makes computing the version string much cheaper in the\ncommon case (whenever StGit is not run directly from a git-controlled\ntree).\n\nIn order for this to work when StGit _is_ run directly from a\ngit-controlled tree, setup.py has to delete the builtin version file\nonce the installation process is over. (Otherwise, the StGit version\nin a git-controlled tree would be frozen at whatever value it happened\nto have when setup.py was last run.)\n\nSigned-off-by: Karl Hasselström <kha@treskal.com>\n\n---\n\nOn 2008-05-20 23:02:49 +0200, Karl Hasselström wrote:\n\n> Nah, easier to just change the order of the checks (try r2 before r1)\n> as I outlined. I'll whip up a patch.\n\n\n setup.py         |   45 +++++++++++++++++++++++++--------------------\n stgit/.gitignore |    1 -\n stgit/version.py |   15 ++++++++++++---\n 3 files changed, 37 insertions(+), 24 deletions(-)\n\n\ndiff --git a/setup.py b/setup.py\nindex 40022a7..8d8f7a8 100755\n--- a/setup.py\n+++ b/setup.py\n@@ -43,34 +43,39 @@ def __check_git_version():\n               % (version.git_min_ver, gitver)\n         sys.exit(1)\n \n+def __run_setup():\n+    setup(name = 'stgit',\n+          version = version.version,\n+          license = 'GPLv2',\n+          author = 'Catalin Marinas',\n+          author_email = 'catalin.marinas@gmail.com',\n+          url = 'http://www.procode.org/stgit/',\n+          description = 'Stacked GIT',\n+          long_description = 'Push/pop utility on top of GIT',\n+          scripts = ['stg'],\n+          packages = ['stgit', 'stgit.commands', 'stgit.lib'],\n+          data_files = [\n+            ('share/stgit/templates', glob.glob('templates/*.tmpl')),\n+            ('share/stgit/examples', glob.glob('examples/*.tmpl')),\n+            ('share/stgit/examples', ['examples/gitconfig']),\n+            ('share/stgit/contrib', ['contrib/diffcol.sh',\n+                                     'contrib/stgbashprompt.sh',\n+                                     'contrib/stgit-completion.bash']),\n+            ('share/doc/stgit', glob.glob('doc/*.txt'))])\n+\n # Check the minimum versions required\n if sys.argv[1] in ['install', 'build']:\n     __check_python_version()\n     __check_git_version()\n \n-version.write_builtin_version()\n-\n # ensure readable template files\n old_mask = os.umask(0022)\n \n-setup(name = 'stgit',\n-      version = version.version,\n-      license = 'GPLv2',\n-      author = 'Catalin Marinas',\n-      author_email = 'catalin.marinas@gmail.com',\n-      url = 'http://www.procode.org/stgit/',\n-      description = 'Stacked GIT',\n-      long_description = 'Push/pop utility on top of GIT',\n-      scripts = ['stg'],\n-      packages = ['stgit', 'stgit.commands', 'stgit.lib'],\n-      data_files = [('share/stgit/templates', glob.glob('templates/*.tmpl')),\n-                    ('share/stgit/examples', glob.glob('examples/*.tmpl')),\n-                    ('share/stgit/examples', ['examples/gitconfig']),\n-                    ('share/stgit/contrib', ['contrib/diffcol.sh',\n-                                             'contrib/stgbashprompt.sh',\n-                                             'contrib/stgit-completion.bash']),\n-                    ('share/doc/stgit', glob.glob('doc/*.txt'))]\n-      )\n+try:\n+    version.write_builtin_version()\n+    __run_setup()\n+finally:\n+    version.delete_builtin_version()\n \n # restore the old mask\n os.umask(old_mask)\ndiff --git a/stgit/.gitignore b/stgit/.gitignore\nindex 4f9c8f1..0d20b64 100644\n--- a/stgit/.gitignore\n+++ b/stgit/.gitignore\n@@ -1,2 +1 @@\n *.pyc\n-/builtin_version.py\ndiff --git a/stgit/version.py b/stgit/version.py\nindex 8ee5009..d57053d 100644\n--- a/stgit/version.py\n+++ b/stgit/version.py\n@@ -1,6 +1,6 @@\n from stgit.exception import StgException\n from stgit import run, utils\n-import os.path, re, sys\n+import os, os.path, re, sys\n \n class VersionUnavailable(StgException):\n     pass\n@@ -31,17 +31,26 @@ def builtin_version():\n     else:\n         return bv.version\n \n+def _builtin_version_file(ext = 'py'):\n+    return os.path.join(sys.path[0], 'stgit', 'builtin_version.%s' % ext)\n+\n def write_builtin_version():\n     try:\n         v = git_describe_version()\n     except VersionUnavailable:\n         return\n-    f = file(os.path.join(sys.path[0], 'stgit', 'builtin_version.py'), 'w')\n+    f = file(_builtin_version_file(), 'w')\n     f.write('# This file was generated automatically. Do not edit by hand.\\n'\n             'version = %r\\n' % v)\n \n+def delete_builtin_version():\n+    for ext in ['py', 'pyc', 'pyo']:\n+        fn = _builtin_version_file(ext)\n+        if os.path.exists(fn):\n+            os.remove(fn)\n+\n def get_version():\n-    for v in [git_describe_version, builtin_version]:\n+    for v in [builtin_version, git_describe_version]:\n         try:\n             return v()\n         except VersionUnavailable:\n"},{"id":"77385","messageId":"b0943d9e0805210707s5af76462wc92a4cf55e5d4a9d@mail.gmail.com","threadId":"13503","inReplyTo":"20080520210249.GA19465@diana.vm.bytemark.co.uk","subject":"Re: StGit: kha/{safe,experimental} updated","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-05-21T14:07:44Z","receivedAt":"2008-05-21T14:07:44Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"2008/5/20 Karl Hasselström <kha@treskal.com>:\n> On 2008-05-20 18:19:02 +0100, Catalin Marinas wrote:\n>> I build release tarball from the directory under Git control and I\n>> always get a builtin_version.py generated. In my initial patch I had\n>> a check in setup.py for a .release file. I could add a check in\n>> write_builtin_version to ignore the extra .git stuff if I am making\n>> a release (only keep the tag name).\n>\n> Nah, easier to just change the order of the checks (try r2 before r1)\n> as I outlined. I'll whip up a patch.\n[...]\n> If you're exactly on a tagged commit, git-describe will return just\n> the name of that tag, so you don't need to do anything extra.\n\nNow that you mentioned this (I didn't know), is there a need to\nreverse steps r2 and r1? I always build the release from the current\ntag and the version should be clean.\n\n>> BTW, Git seems to use 6 characters for the current commit id and\n>> StGIT 5. Should we change this for consistency?\n>\n> Both git and we call git-describe with --abbrev=4, which I think means\n> \"describe the commit uniquely with as few digits as possible, but no\n> less than four\". So we'll get upgraded automatically when it becomes\n> necessary.\n\nOK, I didn't know this either.\n\n-- \nCatalin\n"},{"id":"77388","messageId":"b0943d9e0805210738v40b25d54j65e70b3ef2745987@mail.gmail.com","threadId":"13503","inReplyTo":"20080520213844.13410.32757.stgit@yoghurt","subject":"Re: [StGit PATCH] Try the built-in version string before git-describe","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-05-21T14:38:18Z","receivedAt":"2008-05-21T14:38:18Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 20/05/2008, Karl Hasselström <kha@treskal.com> wrote:\n> Try to get the built-in version string first, and fall back to git\n>  describe if there is no built-in string, instead of the other way\n>  around. This makes computing the version string much cheaper in the\n>  common case (whenever StGit is not run directly from a git-controlled\n>  tree).\n>\n>  In order for this to work when StGit _is_ run directly from a\n>  git-controlled tree, setup.py has to delete the builtin version file\n>  once the installation process is over. (Otherwise, the StGit version\n>  in a git-controlled tree would be frozen at whatever value it happened\n>  to have when setup.py was last run.)\n\nOK, I thought it was only the ordering change. With this change to\nsetup.py, I'm OK with the patch. I'll merge your tree tonight.\n\n-- \nCatalin\n"},{"id":"77393","messageId":"20080521145834.GB31982@diana.vm.bytemark.co.uk","threadId":"13503","inReplyTo":"b0943d9e0805210707s5af76462wc92a4cf55e5d4a9d@mail.gmail.com","subject":"Re: StGit: kha/{safe,experimental} updated","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-21T14:58:34Z","receivedAt":"2008-05-21T14:58:34Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-05-21 15:07:44 +0100, Catalin Marinas wrote:\n\n> 2008/5/20 Karl Hasselström <kha@treskal.com>:\n>\n> > Nah, easier to just change the order of the checks (try r2 before\n> > r1) as I outlined. I'll whip up a patch.\n> [...]\n> > If you're exactly on a tagged commit, git-describe will return\n> > just the name of that tag, so you don't need to do anything extra.\n>\n> Now that you mentioned this (I didn't know), is there a need to\n> reverse steps r2 and r1? I always build the release from the current\n> tag and the version should be clean.\n\nThe advantage is that step r1 involves running git-describe, which is\nrelatively expensive. With the patch I just posted, we only have to\npay that cost when it's really necessary (which is when running stg\ndirectly from a git tree).\n\n> > Both git and we call git-describe with --abbrev=4, which I think\n> > means \"describe the commit uniquely with as few digits as\n> > possible, but no less than four\". So we'll get upgraded\n> > automatically when it becomes necessary.\n>\n> OK, I didn't know this either.\n\nI only found out when I wrote the first version patch.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"77392","messageId":"20080521150026.GC31982@diana.vm.bytemark.co.uk","threadId":"13503","inReplyTo":"b0943d9e0805210738v40b25d54j65e70b3ef2745987@mail.gmail.com","subject":"Re: [StGit PATCH] Try the built-in version string before git-describe","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-05-21T15:00:26Z","receivedAt":"2008-05-21T15:00:26Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-05-21 15:38:18 +0100, Catalin Marinas wrote:\n\n> On 20/05/2008, Karl Hasselström <kha@treskal.com> wrote:\n>\n> > In order for this to work when StGit _is_ run directly from a\n> > git-controlled tree, setup.py has to delete the builtin version\n> > file once the installation process is over. (Otherwise, the StGit\n> > version in a git-controlled tree would be frozen at whatever value\n> > it happened to have when setup.py was last run.)\n>\n> OK, I thought it was only the ordering change. With this change to\n> setup.py, I'm OK with the patch. I'll merge your tree tonight.\n\nThe change to setup.py is actually tiny. I just had to reindent a\ngazillion line, which makes the patch less than perfectly readable...\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"}]}