{"thread":{"id":"14438","subject":"[PATCH 0/4] Proposed patches","startedAt":"2008-07-13T11:40:17Z","lastAt":"2008-08-21T21:39:04Z","messageCount":17,"participants":["Catalin Marinas","Lukas Sandström","Karl Hasselström","Mark Brown"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"83138","messageId":"20080713113853.18845.37686.stgit@localhost.localdomain","threadId":"14438","inReplyTo":null,"subject":"[PATCH 0/4] Proposed patches","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-13T11:40:17Z","receivedAt":"2008-07-13T11:40:17Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"A new post of the proposed patches after implementing Karl's comments.\n\n---\n\nCatalin Marinas (4):\n      Remove the applied/unapplied commands\n      Convert git_id() to the new id format\n      Implement a new patch identification scheme and id command\n      Allow e-mails to be sent with the Unix sendmail tool\n\n\n examples/gitconfig          |    1 \n stgit/commands/applied.py   |   51 --------------------\n stgit/commands/common.py    |  109 +++++++++++++++----------------------------\n stgit/commands/diff.py      |   23 ++++-----\n stgit/commands/files.py     |   10 ++--\n stgit/commands/id.py        |   28 +++++------\n stgit/commands/mail.py      |   54 +++++++++++++++------\n stgit/commands/pick.py      |   10 ++--\n stgit/commands/refresh.py   |    4 +-\n stgit/commands/series.py    |   29 ++++++++---\n stgit/commands/unapplied.py |   50 --------------------\n stgit/lib/git.py            |    4 +-\n stgit/main.py               |    4 --\n t/t0001-subdir-branches.sh  |   24 ++++-----\n t/t1002-branch-clone.sh     |    6 +-\n t/t1003-new.sh              |    4 +-\n t/t1200-push-modified.sh    |   14 +++---\n t/t1201-pull-trailing.sh    |    2 -\n t/t1203-pop.sh              |   12 ++---\n t/t1204-pop-keep.sh         |   12 ++---\n t/t1205-push-subdir.sh      |    4 +-\n t/t1301-repair.sh           |   12 ++---\n t/t1302-repair-interop.sh   |   20 ++++----\n t/t1500-float.sh            |   14 +++---\n t/t1501-sink.sh             |    2 -\n t/t1600-delete-one.sh       |   28 ++++++-----\n t/t1601-delete-many.sh      |   24 +++++----\n t/t2000-sync.sh             |   50 ++++++++++----------\n t/t2200-rebase.sh           |    6 +-\n t/t2500-clean.sh            |   12 ++---\n t/t2600-coalesce.sh         |   12 ++---\n t/t3000-dirty-merge.sh      |    8 ++-\n t/t4000-upgrade.sh          |    4 +-\n 33 files changed, 265 insertions(+), 382 deletions(-)\n delete mode 100644 stgit/commands/applied.py\n delete mode 100644 stgit/commands/unapplied.py\n\n-- \nCatalin\n"},{"id":"83139","messageId":"20080713114026.18845.77979.stgit@localhost.localdomain","threadId":"14438","inReplyTo":"20080713113853.18845.37686.stgit@localhost.localdomain","subject":"[PATCH 1/4] Allow e-mails to be sent with the Unix sendmail tool","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-13T11:40:26Z","receivedAt":"2008-07-13T11:40:26Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"If the stgit.smtpserver configuration option does not have a host:port\nformat, it is assumed to be an external tool. For example, to use\nsendmail just set this variable to \"/usr/sbin/sendmail -t -i\" (see the\nexamples/gitconfig file).\n\nSigned-off-by: Catalin Marinas <catalin.marinas@gmail.com>\n---\n\n examples/gitconfig     |    1 +\n stgit/commands/mail.py |   46 ++++++++++++++++++++++++++++++++++------------\n 2 files changed, 35 insertions(+), 12 deletions(-)\n\ndiff --git a/examples/gitconfig b/examples/gitconfig\nindex c16f786..28d94af 100644\n--- a/examples/gitconfig\n+++ b/examples/gitconfig\n@@ -19,6 +19,7 @@\n \t#autoresolved = no\n \n \t# SMTP server for sending patches\n+\t#smtpserver = /usr/sbin/sendmail -t -i\n \t#smtpserver = localhost:25\n \n \t# Set to 'yes' to use SMTP over TLS\ndiff --git a/stgit/commands/mail.py b/stgit/commands/mail.py\nindex b4d4e18..c87d67e 100644\n--- a/stgit/commands/mail.py\n+++ b/stgit/commands/mail.py\n@@ -24,6 +24,7 @@ from stgit.utils import *\n from stgit.out import *\n from stgit import stack, git, version, templates\n from stgit.config import config\n+from stgit.run import Run\n \n \n help = 'send a patch or series of patches by e-mail'\n@@ -31,13 +32,15 @@ usage = r\"\"\"%prog [options] [<patch1>] [<patch2>] [<patch3>..<patch4>]\n \n Send a patch or a range of patches by e-mail using the SMTP server\n specified by the 'stgit.smtpserver' configuration option, or the\n-'--smtp-server' command line option. The From address and the e-mail\n-format are generated from the template file passed as argument to\n-'--template' (defaulting to '.git/patchmail.tmpl' or\n-'~/.stgit/templates/patchmail.tmpl' or\n+'--smtp-server' command line option. This option can also be an\n+absolute path to 'sendmail' followed by command line arguments.\n+\n+The From address and the e-mail format are generated from the template\n+file passed as argument to '--template' (defaulting to\n+'.git/patchmail.tmpl' or '~/.stgit/templates/patchmail.tmpl' or\n '/usr/share/stgit/templates/patchmail.tmpl'). A patch can be sent as\n-attachment using the --attach option in which case the 'mailattch.tmpl'\n-template will be used instead of 'patchmail.tmpl'.\n+attachment using the --attach option in which case the\n+'mailattch.tmpl' template will be used instead of 'patchmail.tmpl'.\n \n The To/Cc/Bcc addresses can either be added to the template file or\n passed via the corresponding command line options. They can be e-mail\n@@ -133,8 +136,9 @@ options = [make_option('-a', '--all',\n                        help = 'sleep for SECONDS between e-mails sending'),\n            make_option('--refid',\n                        help = 'use REFID as the reference id'),\n-           make_option('--smtp-server', metavar = 'HOST[:PORT]',\n-                       help = 'SMTP server to use for sending mail'),\n+           make_option('--smtp-server',\n+                       metavar = 'HOST[:PORT] or \"/path/to/sendmail -t -i\"',\n+                       help = 'SMTP server or command to use for sending mail'),\n            make_option('-u', '--smtp-user', metavar = 'USER',\n                        help = 'username for SMTP authentication'),\n            make_option('-p', '--smtp-password', metavar = 'PASSWORD',\n@@ -184,8 +188,14 @@ def __parse_addresses(msg):\n \n     return (from_addr_list[0], to_addr_list)\n \n-def __send_message(smtpserver, from_addr, to_addr_list, msg, sleep,\n-                   smtpuser, smtppassword, use_tls):\n+def __send_message_sendmail(sendmail, msg):\n+    \"\"\"Send the message using the sendmail command.\n+    \"\"\"\n+    cmd = sendmail.split()\n+    Run(*cmd).raw_input(msg).discard_output()\n+\n+def __send_message_smtp(smtpserver, from_addr, to_addr_list, msg,\n+                        smtpuser, smtppassword, use_tls):\n     \"\"\"Send the message using the given SMTP server\n     \"\"\"\n     try:\n@@ -207,13 +217,25 @@ def __send_message(smtpserver, from_addr, to_addr_list, msg, sleep,\n         result = s.sendmail(from_addr, to_addr_list, msg)\n         if len(result):\n             print \"mail server refused delivery for the following recipients: %s\" % result\n-        # give recipients a chance of receiving patches in the correct order\n-        time.sleep(sleep)\n     except Exception, err:\n         raise CmdException, str(err)\n \n     s.quit()\n \n+def __send_message(smtpserver, from_addr, to_addr_list, msg,\n+                   sleep, smtpuser, smtppassword, use_tls):\n+    \"\"\"Message sending dispatcher.\n+    \"\"\"\n+    if smtpserver.startswith('/'):\n+        # Use the sendmail tool\n+        __send_message_sendmail(smtpserver, msg)\n+    else:\n+        # Use the SMTP server (we have host and port information)\n+        __send_message_smtp(smtpserver, from_addr, to_addr_list, msg,\n+                            smtpuser, smtppassword, use_tls)\n+    # give recipients a chance of receiving patches in the correct order\n+    time.sleep(sleep)\n+\n def __build_address_headers(msg, options, extra_cc = []):\n     \"\"\"Build the address headers and check existing headers in the\n     template.\n"},{"id":"83140","messageId":"20080713114035.18845.45056.stgit@localhost.localdomain","threadId":"14438","inReplyTo":"20080713113853.18845.37686.stgit@localhost.localdomain","subject":"[PATCH 2/4] Implement a new patch identification scheme and id command","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-13T11:40:35Z","receivedAt":"2008-07-13T11:40:35Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"The new scheme allows '[<branch>:]<patch>' and '[<branch>:]{base}'\n(the latter showing the base of a stack). The former format allows\nsymbols like ^ and ^{...}.\n\nSigned-off-by: Catalin Marinas <catalin.marinas@gmail.com>\n---\n\n stgit/commands/common.py   |   33 +++++++++++++++++++++++++++++++++\n stgit/commands/id.py       |   28 ++++++++++++----------------\n stgit/lib/git.py           |    4 ++--\n t/t0001-subdir-branches.sh |   24 ++++++++++--------------\n t/t1200-push-modified.sh   |    2 +-\n t/t1201-pull-trailing.sh   |    2 +-\n t/t2200-rebase.sh          |    2 +-\n 7 files changed, 60 insertions(+), 35 deletions(-)\n\ndiff --git a/stgit/commands/common.py b/stgit/commands/common.py\nindex 029ec65..0133f1a 100644\n--- a/stgit/commands/common.py\n+++ b/stgit/commands/common.py\n@@ -28,6 +28,7 @@ from stgit.run import *\n from stgit import stack, git, basedir\n from stgit.config import config, file_extensions\n from stgit.lib import stack as libstack\n+from stgit.lib import git as libgit\n \n # Command exception class\n class CmdException(StgException):\n@@ -116,6 +117,38 @@ def git_id(crt_series, rev):\n \n     raise CmdException, 'Unknown patch or revision: %s' % rev\n \n+def git_commit(name, repository, branch = None):\n+    \"\"\"Return the a Commit object if 'name' is a patch name or Git commit.\n+    The patch names allowed are in the form '<branch>:<patch>' and can\n+    be followed by standard symbols used by git-rev-parse. If <patch>\n+    is '{base}', it represents the bottom of the stack.\n+    \"\"\"\n+    # Try a [branch:]patch name first\n+    try:\n+        branch, patch = name.split(':', 1)\n+    except ValueError:\n+        patch = name\n+    if not branch:\n+        branch = repository.current_branch_name\n+\n+    # The stack base\n+    if patch.startswith('{base}'):\n+        base_id = repository.get_stack(branch).base.sha1\n+        return repository.rev_parse(base_id + patch[6:])\n+\n+    # Other combination of branch and patch\n+    try:\n+        return repository.rev_parse('patches/%s/%s' % (branch, patch),\n+                                    discard_stderr = True)\n+    except libgit.RepositoryException:\n+        pass\n+\n+    # Try a Git commit\n+    try:\n+        return repository.rev_parse(name, discard_stderr = True)\n+    except libgit.RepositoryException:\n+        raise CmdException('%s: Unknown patch or revision name' % name)\n+\n def check_local_changes():\n     if git.local_changes():\n         raise CmdException('local changes in the tree. Use \"refresh\" or'\ndiff --git a/stgit/commands/id.py b/stgit/commands/id.py\nindex 94b0229..3819acc 100644\n--- a/stgit/commands/id.py\n+++ b/stgit/commands/id.py\n@@ -15,28 +15,24 @@ along with this program; if not, write to the Free Software\n Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n \"\"\"\n \n-import sys, os\n from optparse import OptionParser, make_option\n \n-from stgit.commands.common import *\n-from stgit.utils import *\n-from stgit.out import *\n-from stgit import stack, git\n-\n+from stgit.out import out\n+from stgit.commands import common\n+from stgit.lib import stack\n \n help = 'print the GIT hash value of a StGIT reference'\n usage = \"\"\"%prog [options] [id]\n \n-Print the hash value of a GIT id (defaulting to HEAD). In addition to\n-the standard GIT id's like heads and tags, this command also accepts\n-'base[@<branch>]' and '[<patch>[@<branch>]][//[bottom | top]]'. If no\n-'top' or 'bottom' are passed and <patch> is a valid patch name, 'top'\n-will be used by default.\"\"\"\n-\n-directory = DirectoryHasRepository()\n-options = [make_option('-b', '--branch',\n-                       help = 'use BRANCH instead of the default one')]\n+Print the SHA1 value of a Git id (defaulting to HEAD). In addition to\n+the standard Git id's like heads and tags, this command also accepts\n+'[<branch>:]<patch>' and '[<branch>:]{base}' showing the id of a patch\n+or the base of the stack. If no branch is specified, it defaults to the\n+current one. The bottom of a patch is accessible with the\n+'[<branch>:]<patch>^' format.\"\"\"\n \n+directory = common.DirectoryHasRepositoryLib()\n+options = []\n \n def func(parser, options, args):\n     \"\"\"Show the applied patches\n@@ -48,4 +44,4 @@ def func(parser, options, args):\n     else:\n         parser.error('incorrect number of arguments')\n \n-    out.stdout(git_id(crt_series, id_str))\n+    out.stdout(common.git_commit(id_str, directory.repository).sha1)\ndiff --git a/stgit/lib/git.py b/stgit/lib/git.py\nindex 6ccdfa7..4746da3 100644\n--- a/stgit/lib/git.py\n+++ b/stgit/lib/git.py\n@@ -422,11 +422,11 @@ class Repository(RunWithEnv):\n     refs = property(lambda self: self.__refs)\n     def cat_object(self, sha1):\n         return self.run(['git', 'cat-file', '-p', sha1]).raw_output()\n-    def rev_parse(self, rev):\n+    def rev_parse(self, rev, discard_stderr = False):\n         try:\n             return self.get_commit(self.run(\n                     ['git', 'rev-parse', '%s^{commit}' % rev]\n-                    ).output_one_line())\n+                    ).discard_stderr(discard_stderr).output_one_line())\n         except run.RunException:\n             raise RepositoryException('%s: No such revision' % rev)\n     def get_tree(self, sha1):\ndiff --git a/t/t0001-subdir-branches.sh b/t/t0001-subdir-branches.sh\nindex 69c11a3..3f7962a 100755\n--- a/t/t0001-subdir-branches.sh\n+++ b/t/t0001-subdir-branches.sh\n@@ -18,25 +18,21 @@ test_expect_success 'Create a patch' \\\n    stg new foo -m \"Add foo.txt\" &&\n    stg refresh'\n \n-test_expect_success 'Old and new id with non-slashy branch' \\\n-  'stg id foo &&\n-   stg id foo// &&\n-   stg id foo/ &&\n-   stg id foo//top &&\n-   stg id foo/top &&\n-   stg id foo@master &&\n-   stg id foo@master//top &&\n-   stg id foo@master/top'\n+test_expect_success 'Try id with non-slashy branch' \\\n+  'stg id &&\n+   stg id foo &&\n+   stg id foo^ &&\n+   stg id master:foo &&\n+   stg id master:foo^'\n \n test_expect_success 'Clone branch to slashier name' \\\n   'stg branch --clone x/y/z'\n \n-test_expect_success 'Try new form of id with slashy branch' \\\n+test_expect_success 'Try new id with slashy branch' \\\n   'stg id foo &&\n-   stg id foo// &&\n-   stg id foo//top &&\n-   stg id foo@x/y/z &&\n-   stg id foo@x/y/z//top'\n+   stg id foo^ &&\n+   stg id x/y/z:foo &&\n+   stg id x/y/z:foo^'\n \n test_expect_success 'Try old id with slashy branch' '\n    command_error stg id foo/ &&\ndiff --git a/t/t1200-push-modified.sh b/t/t1200-push-modified.sh\nindex 6ebd0a1..2edc760 100755\n--- a/t/t1200-push-modified.sh\n+++ b/t/t1200-push-modified.sh\n@@ -36,7 +36,7 @@ test_expect_success \\\n     (\n         cd foo &&\n         GIT_DIR=../bar/.git git-format-patch --stdout \\\n-          $(cd ../bar && stg id base@master)..HEAD | git-am -3 -k\n+          $(cd ../bar && stg id master:{base})..HEAD | git-am -3 -k\n     )\n '\n \ndiff --git a/t/t1201-pull-trailing.sh b/t/t1201-pull-trailing.sh\nindex 9d70fe0..8a74873 100755\n--- a/t/t1201-pull-trailing.sh\n+++ b/t/t1201-pull-trailing.sh\n@@ -30,7 +30,7 @@ test_expect_success \\\n     'Port those patches to orig tree' \\\n     '(cd foo &&\n       GIT_DIR=../bar/.git git-format-patch --stdout \\\n-          $(cd ../bar && stg id base@master)..HEAD |\n+          $(cd ../bar && stg id master:{base})..HEAD |\n       git-am -3 -k\n      )\n     '\ndiff --git a/t/t2200-rebase.sh b/t/t2200-rebase.sh\nindex a6f43bc..256eaaa 100755\n--- a/t/t2200-rebase.sh\n+++ b/t/t2200-rebase.sh\n@@ -27,7 +27,7 @@ test_expect_success \\\n \t'Rebase to previous commit' \\\n \t'\n \tstg rebase master~1 &&\n-\ttest `stg id base@stack` = `git rev-parse master~1` &&\n+\ttest `stg id stack:{base}` = `git rev-parse master~1` &&\n \ttest `stg applied | wc -l` = 1\n \t'\n \n"},{"id":"83141","messageId":"20080713114047.18845.34899.stgit@localhost.localdomain","threadId":"14438","inReplyTo":"20080713113853.18845.37686.stgit@localhost.localdomain","subject":"[PATCH 3/4] Convert git_id() to the new id format","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-13T11:40:48Z","receivedAt":"2008-07-13T11:40:48Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"The patch rewrites git_id() to use the new id format and coverts the\ncommands using this function. The git_id() will be removed once all the\ncommands are converted to the new infrastructure where git_commit() will\nbe used instead.\n\nSigned-off-by: Catalin Marinas <catalin.marinas@gmail.com>\n---\n\n stgit/commands/common.py  |   98 +++++++--------------------------------------\n stgit/commands/diff.py    |   23 +++++------\n stgit/commands/files.py   |   10 ++---\n stgit/commands/mail.py    |    8 ++--\n stgit/commands/pick.py    |   10 ++---\n stgit/commands/refresh.py |    4 +-\n stgit/commands/series.py  |    4 +-\n t/t2000-sync.sh           |    2 -\n 8 files changed, 43 insertions(+), 116 deletions(-)\n\ndiff --git a/stgit/commands/common.py b/stgit/commands/common.py\nindex 0133f1a..0413aac 100644\n--- a/stgit/commands/common.py\n+++ b/stgit/commands/common.py\n@@ -35,101 +35,35 @@ class CmdException(StgException):\n     pass\n \n # Utility functions\n-class RevParseException(StgException):\n-    \"\"\"Revision spec parse error.\"\"\"\n-    pass\n-\n def parse_rev(rev):\n-    \"\"\"Parse a revision specification into its\n-    patchname@branchname//patch_id parts. If no branch name has a slash\n-    in it, also accept / instead of //.\"\"\"\n-    if '/' in ''.join(git.get_heads()):\n-        # We have branch names with / in them.\n-        branch_chars = r'[^@]'\n-        patch_id_mark = r'//'\n-    else:\n-        # No / in branch names.\n-        branch_chars = r'[^@/]'\n-        patch_id_mark = r'(/|//)'\n-    patch_re = r'(?P<patch>[^@/]+)'\n-    branch_re = r'@(?P<branch>%s+)' % branch_chars\n-    patch_id_re = r'%s(?P<patch_id>[a-z.]*)' % patch_id_mark\n-\n-    # Try //patch_id.\n-    m = re.match(r'^%s$' % patch_id_re, rev)\n-    if m:\n-        return None, None, m.group('patch_id')\n-\n-    # Try path[@branch]//patch_id.\n-    m = re.match(r'^%s(%s)?%s$' % (patch_re, branch_re, patch_id_re), rev)\n-    if m:\n-        return m.group('patch'), m.group('branch'), m.group('patch_id')\n-\n-    # Try patch[@branch].\n-    m = re.match(r'^%s(%s)?$' % (patch_re, branch_re), rev)\n-    if m:\n-        return m.group('patch'), m.group('branch'), None\n-\n-    # No, we can't parse that.\n-    raise RevParseException\n-\n-def git_id(crt_series, rev):\n-    \"\"\"Return the GIT id\n+    \"\"\"Parse a revision specification into its branch:patch parts.\n     \"\"\"\n-    if not rev:\n-        return None\n-\n-    # try a GIT revision first\n     try:\n-        return git.rev_parse(rev + '^{commit}')\n-    except git.GitException:\n-        pass\n+        branch, patch = rev.split(':', 1)\n+    except ValueError:\n+        branch = None\n+        patch = rev\n \n-    # try an StGIT patch name\n-    try:\n-        patch, branch, patch_id = parse_rev(rev)\n-        if branch == None:\n-            series = crt_series\n-        else:\n-            series = stack.Series(branch)\n-        if patch == None:\n-            patch = series.get_current()\n-            if not patch:\n-                raise CmdException, 'No patches applied'\n-        if patch in series.get_applied() or patch in series.get_unapplied() or \\\n-               patch in series.get_hidden():\n-            if patch_id in ['top', '', None]:\n-                return series.get_patch(patch).get_top()\n-            elif patch_id == 'bottom':\n-                return series.get_patch(patch).get_bottom()\n-            elif patch_id == 'top.old':\n-                return series.get_patch(patch).get_old_top()\n-            elif patch_id == 'bottom.old':\n-                return series.get_patch(patch).get_old_bottom()\n-            elif patch_id == 'log':\n-                return series.get_patch(patch).get_log()\n-        if patch == 'base' and patch_id == None:\n-            return series.get_base()\n-    except RevParseException:\n-        pass\n-    except stack.StackException:\n-        pass\n+    return (branch, patch)\n \n-    raise CmdException, 'Unknown patch or revision: %s' % rev\n+def git_id(crt_series, rev):\n+    \"\"\"Return the GIT id\n+    \"\"\"\n+    # TODO: remove this function once all the occurrences were converted\n+    # to git_commit()\n+    repository = libstack.Repository.default()\n+    return git_commit(rev, repository, crt_series.get_name()).sha1\n \n-def git_commit(name, repository, branch = None):\n+def git_commit(name, repository, branch_name = None):\n     \"\"\"Return the a Commit object if 'name' is a patch name or Git commit.\n     The patch names allowed are in the form '<branch>:<patch>' and can\n     be followed by standard symbols used by git-rev-parse. If <patch>\n     is '{base}', it represents the bottom of the stack.\n     \"\"\"\n     # Try a [branch:]patch name first\n-    try:\n-        branch, patch = name.split(':', 1)\n-    except ValueError:\n-        patch = name\n+    branch, patch = parse_rev(name)\n     if not branch:\n-        branch = repository.current_branch_name\n+        branch = branch_name or repository.current_branch_name\n \n     # The stack base\n     if patch.startswith('{base}'):\ndiff --git a/stgit/commands/diff.py b/stgit/commands/diff.py\nindex fd6be34..c57f720 100644\n--- a/stgit/commands/diff.py\n+++ b/stgit/commands/diff.py\n@@ -30,17 +30,14 @@ help = 'show the tree diff'\n usage = \"\"\"%prog [options] [<files or dirs>]\n \n Show the diff (default) or diffstat between the current working copy\n-or a tree-ish object and another tree-ish object. File names can also\n-be given to restrict the diff output. The tree-ish object can be a\n-standard git commit, tag or tree. In addition to these, the command\n-also supports 'base', representing the bottom of the current stack,\n-and '[patch][//[bottom | top]]' for the patch boundaries (defaulting to\n-the current one):\n+or a tree-ish object and another tree-ish object (defaulting to HEAD).\n+File names can also be given to restrict the diff output. The\n+tree-ish object can be an StGIT patch, a standard git commit, tag or\n+tree. In addition to these, the command also supports '{base}',\n+representing the bottom of the current stack.\n \n-rev = '([patch][//[bottom | top]]) | <tree-ish> | base'\n-\n-If neither bottom nor top are given but a '//' is present, the command\n-shows the specified patch (defaulting to the current one).\"\"\"\n+rev = '[branch:](<patch>|{base}) | <tree-ish>'\n+\"\"\"\n \n directory = DirectoryHasRepository()\n options = [make_option('-r', '--range',\n@@ -67,8 +64,8 @@ def func(parser, options, args):\n                 rev = strip_suffix('/', rev)\n                 if rev.endswith('/'):\n                     rev = strip_suffix('/', rev)\n-                rev1 = rev + '//bottom'\n-                rev2 = rev + '//top'\n+                rev1 = rev + 'HEAD^'\n+                rev2 = rev + 'HEAD'\n             else:\n                 rev1 = rev_list[0]\n                 rev2 = None\n@@ -82,7 +79,7 @@ def func(parser, options, args):\n         rev2 = None\n \n     diff_str = git.diff(args, git_id(crt_series, rev1),\n-                        git_id(crt_series, rev2),\n+                        rev2 and git_id(crt_series, rev2),\n                         diff_flags = options.diff_flags)\n     if options.stat:\n         out.stdout_raw(git.diffstat(diff_str) + '\\n')\ndiff --git a/stgit/commands/files.py b/stgit/commands/files.py\nindex b43b12f..d240872 100644\n--- a/stgit/commands/files.py\n+++ b/stgit/commands/files.py\n@@ -26,7 +26,7 @@ from stgit import stack, git\n \n \n help = 'show the files modified by a patch (or the current patch)'\n-usage = \"\"\"%prog [options] [<patch>]\n+usage = \"\"\"%prog [options] [[<branch>:]<patch>]\n \n List the files modified by the given patch (defaulting to the current\n one). Passing the '--stat' option shows the diff statistics for the\n@@ -38,8 +38,6 @@ directory = DirectoryHasRepository()\n options = [make_option('-s', '--stat',\n                        help = 'show the diff stat',\n                        action = 'store_true'),\n-           make_option('-b', '--branch',\n-                       help = 'use BRANCH instead of the default one'),\n            make_option('--bare',\n                        help = 'bare file names (useful for scripting)',\n                        action = 'store_true')\n@@ -50,14 +48,14 @@ def func(parser, options, args):\n     \"\"\"Show the files modified by a patch (or the current patch)\n     \"\"\"\n     if len(args) == 0:\n-        patch = ''\n+        patch = 'HEAD'\n     elif len(args) == 1:\n         patch = args[0]\n     else:\n         parser.error('incorrect number of arguments')\n \n-    rev1 = git_id(crt_series, '%s//bottom' % patch)\n-    rev2 = git_id(crt_series, '%s//top' % patch)\n+    rev1 = git_id(crt_series, '%s^' % patch)\n+    rev2 = git_id(crt_series, '%s' % patch)\n \n     if options.stat:\n         out.stdout_raw(git.diffstat(git.diff(rev1 = rev1, rev2 = rev2)) + '\\n')\ndiff --git a/stgit/commands/mail.py b/stgit/commands/mail.py\nindex c87d67e..e04dc2f 100644\n--- a/stgit/commands/mail.py\n+++ b/stgit/commands/mail.py\n@@ -383,8 +383,8 @@ def __build_cover(tmpl, patches, msg_id, options):\n                  'shortlog':     stack.shortlog(crt_series.get_patch(p)\n                                                 for p in patches),\n                  'diffstat':     git.diffstat(git.diff(\n-                     rev1 = git_id(crt_series, '%s//bottom' % patches[0]),\n-                     rev2 = git_id(crt_series, '%s//top' % patches[-1])))}\n+                     rev1 = git_id(crt_series, '%s^' % patches[0]),\n+                     rev2 = git_id(crt_series, '%s' % patches[-1])))}\n \n     try:\n         msg_string = tmpl % tmpl_dict\n@@ -460,8 +460,8 @@ def __build_message(tmpl, patch, patch_nr, total_nr, msg_id, ref_id, options):\n     else:\n         number_str = ''\n \n-    diff = git.diff(rev1 = git_id(crt_series, '%s//bottom' % patch),\n-                    rev2 = git_id(crt_series, '%s//top' % patch),\n+    diff = git.diff(rev1 = git_id(crt_series, '%s^' % patch),\n+                    rev2 = git_id(crt_series, '%s' % patch),\n                     diff_flags = options.diff_flags)\n     tmpl_dict = {'patch':        patch,\n                  'sender':       sender,\ndiff --git a/stgit/commands/pick.py b/stgit/commands/pick.py\nindex 1f7c84b..2a670e8 100644\n--- a/stgit/commands/pick.py\n+++ b/stgit/commands/pick.py\n@@ -87,8 +87,8 @@ def __pick_commit(commit_id, patchname, options):\n \n         out.done()\n     elif options.update:\n-        rev1 = git_id(crt_series, '//bottom')\n-        rev2 = git_id(crt_series, '//top')\n+        rev1 = git_id(crt_series, 'HEAD^')\n+        rev2 = git_id(crt_series, 'HEAD')\n         files = git.barefiles(rev1, rev2).split('\\n')\n \n         out.start('Updating with commit %s' % commit_id)\n@@ -115,10 +115,8 @@ def __pick_commit(commit_id, patchname, options):\n         patchname = newpatch.get_name()\n \n         # find a patchlog to fork from\n-        (refpatchname, refbranchname, refpatchid) = parse_rev(patchname)\n-        if refpatchname and not refpatchid and \\\n-               (not refpatchid or refpatchid == 'top'):\n-            # FIXME: should also support picking //top.old\n+        refbranchname, refpatchname = parse_rev(patchname)\n+        if refpatchname:\n             if refbranchname:\n                 # assume the refseries is OK, since we already resolved\n                 # commit_str to a git_id\ndiff --git a/stgit/commands/refresh.py b/stgit/commands/refresh.py\nindex 4695c62..73e4ee0 100644\n--- a/stgit/commands/refresh.py\n+++ b/stgit/commands/refresh.py\n@@ -103,8 +103,8 @@ def func(parser, options, args):\n             between = applied[:applied.index(patch):-1]\n             pop_patches(crt_series, between, keep = True)\n         elif options.update:\n-            rev1 = git_id(crt_series, '//bottom')\n-            rev2 = git_id(crt_series, '//top')\n+            rev1 = git_id(crt_series, 'HEAD^')\n+            rev2 = git_id(crt_series, 'HEAD')\n             patch_files = git.barefiles(rev1, rev2).split('\\n')\n             files = [f for f in files if f in patch_files]\n             if not files:\ndiff --git a/stgit/commands/series.py b/stgit/commands/series.py\nindex 04183bd..c11c74f 100644\n--- a/stgit/commands/series.py\n+++ b/stgit/commands/series.py\n@@ -88,7 +88,7 @@ def __print_patch(stack, patch, branch_str, prefix, empty_prefix, length, option\n     elif options.empty and stack.patches.get(patch).is_empty():\n         prefix = empty_prefix\n \n-    patch_str = patch + branch_str\n+    patch_str = branch_str + patch\n \n     if options.description or options.author:\n         patch_str = patch_str.ljust(length)\n@@ -164,7 +164,7 @@ def func(parser, options, args):\n         return\n \n     if options.showbranch:\n-        branch_str = '@' + stack.name\n+        branch_str = stack.name + ':'\n     else:\n         branch_str = ''\n \ndiff --git a/t/t2000-sync.sh b/t/t2000-sync.sh\nindex 9852eb8..f4e8b07 100755\n--- a/t/t2000-sync.sh\n+++ b/t/t2000-sync.sh\n@@ -37,7 +37,7 @@ test_expect_success \\\n test_expect_success \\\n     'Create a branch with empty patches' \\\n     '\n-    stg branch -c foo base &&\n+    stg branch -c foo {base} &&\n     stg new p1 -m p1 &&\n     stg new p2 -m p2 &&\n     stg new p3 -m p3 &&\n"},{"id":"83142","messageId":"20080713114057.18845.74524.stgit@localhost.localdomain","threadId":"14438","inReplyTo":"20080713113853.18845.37686.stgit@localhost.localdomain","subject":"[PATCH 4/4] Remove the applied/unapplied commands","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-13T11:40:57Z","receivedAt":"2008-07-13T11:40:57Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"This patch moves the applied/unapplied functionality to the 'series'\ncommand via the corresponding options.\n\nSigned-off-by: Catalin Marinas <catalin.marinas@gmail.com>\n---\n\n stgit/commands/applied.py   |   51 -------------------------------------------\n stgit/commands/series.py    |   25 ++++++++++++++++-----\n stgit/commands/unapplied.py |   50 ------------------------------------------\n stgit/main.py               |    4 ---\n t/t1002-branch-clone.sh     |    6 +++--\n t/t1003-new.sh              |    4 ++-\n t/t1200-push-modified.sh    |   12 +++++-----\n t/t1203-pop.sh              |   12 +++++-----\n t/t1204-pop-keep.sh         |   12 +++++-----\n t/t1205-push-subdir.sh      |    4 ++-\n t/t1301-repair.sh           |   12 +++++-----\n t/t1302-repair-interop.sh   |   20 ++++++++---------\n t/t1500-float.sh            |   14 ++++++------\n t/t1501-sink.sh             |    2 +-\n t/t1600-delete-one.sh       |   28 ++++++++++++------------\n t/t1601-delete-many.sh      |   24 ++++++++++----------\n t/t2000-sync.sh             |   48 ++++++++++++++++++++--------------------\n t/t2200-rebase.sh           |    4 ++-\n t/t2500-clean.sh            |   12 +++++-----\n t/t2600-coalesce.sh         |   12 +++++-----\n t/t3000-dirty-merge.sh      |    8 +++----\n t/t4000-upgrade.sh          |    4 ++-\n 22 files changed, 138 insertions(+), 230 deletions(-)\n delete mode 100644 stgit/commands/applied.py\n delete mode 100644 stgit/commands/unapplied.py\n\ndiff --git a/stgit/commands/applied.py b/stgit/commands/applied.py\ndeleted file mode 100644\nindex e57c796..0000000\n--- a/stgit/commands/applied.py\n+++ /dev/null\n@@ -1,51 +0,0 @@\n-\n-__copyright__ = \"\"\"\n-Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>\n-\n-This program is free software; you can redistribute it and/or modify\n-it under the terms of the GNU General Public License version 2 as\n-published by the Free Software Foundation.\n-\n-This program is distributed in the hope that it will be useful,\n-but WITHOUT ANY WARRANTY; without even the implied warranty of\n-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-GNU General Public License for more details.\n-\n-You should have received a copy of the GNU General Public License\n-along with this program; if not, write to the Free Software\n-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n-\"\"\"\n-\n-from optparse import make_option\n-from stgit.out import *\n-from stgit.commands import common\n-\n-\n-help = 'print the applied patches'\n-usage = \"\"\"%prog [options]\n-\n-List the patches from the series which have already been pushed onto\n-the stack. They are listed in the order in which they were pushed, the\n-last one being the current (topmost) patch.\"\"\"\n-\n-directory = common.DirectoryHasRepositoryLib()\n-options = [make_option('-b', '--branch',\n-                       help = 'use BRANCH instead of the default branch'),\n-           make_option('-c', '--count',\n-                       help = 'print the number of applied patches',\n-                       action = 'store_true')]\n-\n-\n-def func(parser, options, args):\n-    \"\"\"Show the applied patches\n-    \"\"\"\n-    if len(args) != 0:\n-        parser.error('incorrect number of arguments')\n-\n-    s = directory.repository.get_stack(options.branch)\n-\n-    if options.count:\n-        out.stdout(len(s.patchorder.applied))\n-    else:\n-        for pn in s.patchorder.applied:\n-            out.stdout(pn)\ndiff --git a/stgit/commands/series.py b/stgit/commands/series.py\nindex c11c74f..b7899d7 100644\n--- a/stgit/commands/series.py\n+++ b/stgit/commands/series.py\n@@ -37,7 +37,13 @@ options = [make_option('-b', '--branch',\n            make_option('-a', '--all',\n                        help = 'show all patches, including the hidden ones',\n                        action = 'store_true'),\n-           make_option('--hidden',\n+           make_option('-A', '--applied',\n+                       help = 'show the applied patches only',\n+                       action = 'store_true'),\n+           make_option('-U', '--unapplied',\n+                       help = 'show the unapplied patches only',\n+                       action = 'store_true'),\n+           make_option('-H', '--hidden',\n                        help = 'show the hidden patches only',\n                        action = 'store_true'),\n            make_option('-m', '--missing', metavar = 'BRANCH',\n@@ -112,17 +118,24 @@ def func(parser, options, args):\n         stack = directory.repository.get_stack(options.missing)\n \n     # current series patches\n-    if options.all:\n+    applied = unapplied = hidden = ()\n+    if options.applied or options.unapplied or options.hidden:\n+        if options.all:\n+            raise common.CmdException, \\\n+                '--all cannot be used with --applied/unapplied/hidden'\n+        if options.applied:\n+            applied = stack.patchorder.applied\n+        if options.unapplied:\n+            unapplied = stack.patchorder.unapplied\n+        if options.hidden:\n+            hidden = stack.patchorder.hidden\n+    elif options.all:\n         applied = stack.patchorder.applied\n         unapplied = stack.patchorder.unapplied\n         hidden = stack.patchorder.hidden\n-    elif options.hidden:\n-        applied = unapplied = ()\n-        hidden = stack.patchorder.hidden\n     else:\n         applied = stack.patchorder.applied\n         unapplied = stack.patchorder.unapplied\n-        hidden = ()\n \n     if options.missing:\n         cmp_patches = cmp_stack.patchorder.all\ndiff --git a/stgit/commands/unapplied.py b/stgit/commands/unapplied.py\ndeleted file mode 100644\nindex 7323346..0000000\n--- a/stgit/commands/unapplied.py\n+++ /dev/null\n@@ -1,50 +0,0 @@\n-\n-__copyright__ = \"\"\"\n-Copyright (C) 2005, Catalin Marinas <catalin.marinas@gmail.com>\n-\n-This program is free software; you can redistribute it and/or modify\n-it under the terms of the GNU General Public License version 2 as\n-published by the Free Software Foundation.\n-\n-This program is distributed in the hope that it will be useful,\n-but WITHOUT ANY WARRANTY; without even the implied warranty of\n-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-GNU General Public License for more details.\n-\n-You should have received a copy of the GNU General Public License\n-along with this program; if not, write to the Free Software\n-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n-\"\"\"\n-\n-from optparse import make_option\n-from stgit.out import *\n-from stgit.commands import common\n-\n-\n-help = 'print the unapplied patches'\n-usage = \"\"\"%prog [options]\n-\n-List the patches from the series which are not pushed onto the stack.\n-They are listed in the reverse order in which they were popped.\"\"\"\n-\n-directory = common.DirectoryHasRepositoryLib()\n-options = [make_option('-b', '--branch',\n-                       help = 'use BRANCH instead of the default branch'),\n-           make_option('-c', '--count',\n-                       help = 'print the number of unapplied patches',\n-                       action = 'store_true')]\n-\n-\n-def func(parser, options, args):\n-    \"\"\"Show the unapplied patches\n-    \"\"\"\n-    if len(args) != 0:\n-        parser.error('incorrect number of arguments')\n-\n-    s = directory.repository.get_stack(options.branch)\n-\n-    if options.count:\n-        out.stdout(len(s.patchorder.unapplied))\n-    else:\n-        for pn in s.patchorder.unapplied:\n-            out.stdout(pn)\ndiff --git a/stgit/main.py b/stgit/main.py\nindex aa1f8ef..7be8e14 100644\n--- a/stgit/main.py\n+++ b/stgit/main.py\n@@ -59,7 +59,6 @@ class Commands(dict):\n         return getattr(stgit.commands, cmd_mod)\n \n commands = Commands({\n-    'applied':          'applied',\n     'branch':           'branch',\n     'delete':           'delete',\n     'diff':             'diff',\n@@ -96,7 +95,6 @@ commands = Commands({\n     'status':           'status',\n     'sync':             'sync',\n     'top':              'top',\n-    'unapplied':        'unapplied',\n     'uncommit':         'uncommit',\n     'unhide':           'unhide'\n     })\n@@ -107,7 +105,6 @@ repocommands = (\n     'id',\n     )\n stackcommands = (\n-    'applied',\n     'branch',\n     'clean',\n     'coalesce',\n@@ -125,7 +122,6 @@ stackcommands = (\n     'series',\n     'sink',\n     'top',\n-    'unapplied',\n     'uncommit',\n     'unhide',\n     )\ndiff --git a/t/t1002-branch-clone.sh b/t/t1002-branch-clone.sh\nindex 19bdc45..1303b41 100755\n--- a/t/t1002-branch-clone.sh\n+++ b/t/t1002-branch-clone.sh\n@@ -29,16 +29,16 @@ test_expect_success \\\n     '\n     stg branch --clone foo &&\n     stg new p1 -m \"p1\" &&\n-    test $(stg applied -c) -eq 1\n+    test $(stg series --applied -c) -eq 1\n     '\n \n test_expect_success \\\n     'Clone the current StGIT branch' \\\n     '\n     stg branch --clone bar &&\n-    test $(stg applied -c) -eq 1 &&\n+    test $(stg series --applied -c) -eq 1 &&\n     stg new p2 -m \"p2\" &&\n-    test $(stg applied -c) -eq 2\n+    test $(stg series --applied -c) -eq 2\n     '\n \n test_done\ndiff --git a/t/t1003-new.sh b/t/t1003-new.sh\nindex 0be5d9b..826e41d 100755\n--- a/t/t1003-new.sh\n+++ b/t/t1003-new.sh\n@@ -17,13 +17,13 @@ test_expect_success \\\n test_expect_success \\\n     'Create a named patch' '\n     stg new foo -m foobar &&\n-    [ $(stg applied -c) -eq 1 ]\n+    [ $(stg series --applied -c) -eq 1 ]\n '\n \n test_expect_success \\\n     'Create a patch without giving a name' '\n     stg new -m yo &&\n-    [ $(stg applied -c) -eq 2 ]\n+    [ $(stg series --applied -c) -eq 2 ]\n '\n \n test_done\ndiff --git a/t/t1200-push-modified.sh b/t/t1200-push-modified.sh\nindex 2edc760..113e41d 100755\n--- a/t/t1200-push-modified.sh\n+++ b/t/t1200-push-modified.sh\n@@ -26,8 +26,8 @@ test_expect_success \\\n         printf \"a\\nc\\n\" > file && git add file && stg refresh &&\n         stg new p2 -m p2 &&\n         printf \"a\\nb\\nc\\n\" > file && stg refresh &&\n-        [ \"$(echo $(stg applied))\" = \"p1 p2\" ] &&\n-        [ \"$(echo $(stg unapplied))\" = \"\" ]\n+        [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2\" ] &&\n+        [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n     )\n '\n \n@@ -57,8 +57,8 @@ test_expect_success \\\n     'Rollback the push' '\n     (\n         cd bar && stg push --undo &&\n-        [ \"$(echo $(stg applied))\" = \"\" ] &&\n-        [ \"$(echo $(stg unapplied))\" = \"p1 p2\" ]\n+        [ \"$(echo $(stg series --applied --noprefix))\" = \"\" ] &&\n+        [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p1 p2\" ]\n     )\n '\n \n@@ -66,8 +66,8 @@ test_expect_success \\\n     'Push those patches while checking they were merged upstream' '\n     (\n         cd bar && stg push --merged --all\n-        [ \"$(echo $(stg applied))\" = \"p1 p2\" ] &&\n-        [ \"$(echo $(stg unapplied))\" = \"\" ]\n+        [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2\" ] &&\n+        [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n     )\n '\n \ndiff --git a/t/t1203-pop.sh b/t/t1203-pop.sh\nindex 6e49b4d..e1ed577 100755\n--- a/t/t1203-pop.sh\n+++ b/t/t1203-pop.sh\n@@ -12,22 +12,22 @@ test_expect_success \\\n     for i in 0 1 2 3 4 5 6 7 8 9; do\n         stg new p$i -m p$i;\n     done &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2 p3 p4 p5 p6 p7 p8 p9\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2 p3 p4 p5 p6 p7 p8 p9\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n '\n \n test_expect_success \\\n     'Pop half the patches' '\n     stg pop -n 5 &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2 p3 p4\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p5 p6 p7 p8 p9\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2 p3 p4\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p5 p6 p7 p8 p9\" ]\n '\n \n test_expect_success \\\n     'Pop the remaining patches' '\n     stg pop -a &&\n-    [ \"$(echo $(stg applied))\" = \"\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p0 p1 p2 p3 p4 p5 p6 p7 p8 p9\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p0 p1 p2 p3 p4 p5 p6 p7 p8 p9\" ]\n '\n \n test_done\ndiff --git a/t/t1204-pop-keep.sh b/t/t1204-pop-keep.sh\nindex 35f4ec0..db473f2 100755\n--- a/t/t1204-pop-keep.sh\n+++ b/t/t1204-pop-keep.sh\n@@ -11,8 +11,8 @@ test_expect_success 'Create a few patches' '\n         git add patch$i.txt &&\n         stg refresh\n     done &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n '\n \n test_expect_success 'Make some non-conflicting local changes' '\n@@ -21,8 +21,8 @@ test_expect_success 'Make some non-conflicting local changes' '\n \n test_expect_success 'Pop two patches, keeping local changes' '\n     stg pop -n 2 --keep &&\n-    [ \"$(echo $(stg applied))\" = \"p0\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p1 p2\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p1 p2\" ] &&\n     [ \"$(echo $(ls patch?.txt))\" = \"patch0.txt\" ] &&\n     [ \"$(echo $(cat patch0.txt))\" = \"patch0 local\" ]\n '\n@@ -34,8 +34,8 @@ test_expect_success 'Reset and push patches again' '\n \n test_expect_success 'Pop a patch without local changes' '\n     stg pop --keep &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p2\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p2\" ] &&\n     [ \"$(echo $(ls patch?.txt))\" = \"patch0.txt patch1.txt\" ]\n '\n \ndiff --git a/t/t1205-push-subdir.sh b/t/t1205-push-subdir.sh\nindex 945eb74..f852762 100755\n--- a/t/t1205-push-subdir.sh\n+++ b/t/t1205-push-subdir.sh\n@@ -12,8 +12,8 @@ test_expect_success 'Create some patches' '\n         git add x.txt foo/y.txt &&\n         stg refresh\n     done &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n '\n \n test_expect_success 'Fast-forward push from a subdir' '\ndiff --git a/t/t1301-repair.sh b/t/t1301-repair.sh\nindex 33f8f6d..8d5d4e5 100755\n--- a/t/t1301-repair.sh\n+++ b/t/t1301-repair.sh\n@@ -37,9 +37,9 @@ test_expect_success \\\n     '\n \n test_expect_success 'Turn one GIT commit into a patch' '\n-    [ $(stg applied | wc -l) -eq 1 ] &&\n+    [ $(stg series --applied -c) -eq 1 ] &&\n     stg repair &&\n-    [ $(stg applied | wc -l) -eq 2 ]\n+    [ $(stg series --applied -c) -eq 2 ]\n     '\n \n test_expect_success \\\n@@ -55,9 +55,9 @@ test_expect_success \\\n     '\n \n test_expect_success 'Turn three GIT commits into patches' '\n-    [ $(stg applied | wc -l) -eq 2 ] &&\n+    [ $(stg series --applied -c) -eq 2 ] &&\n     stg repair &&\n-    [ $(stg applied | wc -l) -eq 5 ]\n+    [ $(stg series --applied -c) -eq 5 ]\n     '\n \n test_expect_success \\\n@@ -72,9 +72,9 @@ test_expect_success \\\n     '\n \n test_expect_success 'Repair in the presence of a merge commit' '\n-    [ $(stg applied | wc -l) -eq 5 ] &&\n+    [ $(stg series --applied -c) -eq 5 ] &&\n     stg repair &&\n-    [ $(stg applied | wc -l) -eq 0 ]\n+    [ $(stg series --applied -c) -eq 0 ]\n '\n \n test_done\ndiff --git a/t/t1302-repair-interop.sh b/t/t1302-repair-interop.sh\nindex 3ea48e7..224c4ba 100755\n--- a/t/t1302-repair-interop.sh\n+++ b/t/t1302-repair-interop.sh\n@@ -21,8 +21,8 @@ test_expect_success 'Create five patches' '\n     for i in 0 1 2 3 4; do\n         stg new p$i -m p$i;\n     done &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2 p3 p4\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2 p3 p4\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n '\n \n test_expect_success 'Pop two patches with git-reset' '\n@@ -30,14 +30,14 @@ test_expect_success 'Pop two patches with git-reset' '\n     command_error stg refresh &&\n     stg repair &&\n     stg refresh &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p3 p4\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p3 p4\" ]\n '\n \n test_expect_success 'Create a new patch' '\n     stg new q0 -m q0 &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2 q0\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p3 p4\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2 q0\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p3 p4\" ]\n '\n \n test_expect_success 'Go to an unapplied patch with with git-reset' '\n@@ -45,15 +45,15 @@ test_expect_success 'Go to an unapplied patch with with git-reset' '\n     command_error stg refresh &&\n     stg repair &&\n     stg refresh &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"q0 p4\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"q0 p4\" ]\n '\n \n test_expect_success 'Go back to below the stack base with git-reset' '\n     git reset --hard foo-tag &&\n     stg repair &&\n-    [ \"$(echo $(stg applied))\" = \"\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p0 p1 p2 p3 q0 p4\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p0 p1 p2 p3 q0 p4\" ]\n '\n \n test_done\ndiff --git a/t/t1500-float.sh b/t/t1500-float.sh\nindex 778fde4..e44af3a 100755\n--- a/t/t1500-float.sh\n+++ b/t/t1500-float.sh\n@@ -20,37 +20,37 @@ test_expect_success \\\n \t stg new F -m \"f\" && echo F >f.txt && git add f.txt && stg refresh &&\n \t stg new G -m \"g\" && echo G >g.txt && git add g.txt && stg refresh &&\n \t stg pop &&\n-\t test \"$(echo $(stg applied))\" = \"A B C D E F\"\n+\t test \"$(echo $(stg series --applied --noprefix))\" = \"A B C D E F\"\n \t'\n \n test_expect_success \\\n \t'Float A to top' \\\n \t'stg float A &&\n-\t test \"$(echo $(stg applied))\" = \"B C D E F A\"\n+\t test \"$(echo $(stg series --applied --noprefix))\" = \"B C D E F A\"\n \t'\n test_expect_success \\\n \t'Float A to top (noop)' \\\n \t'stg float A &&\n-\t test \"$(echo $(stg applied))\" = \"B C D E F A\"\n+\t test \"$(echo $(stg series --applied --noprefix))\" = \"B C D E F A\"\n \t'\n test_expect_success \\\n \t'Float B C to top' \\\n \t'stg float B C &&\n-\t test \"$(echo $(stg applied))\" = \"D E F A B C\"\n+\t test \"$(echo $(stg series --applied --noprefix))\" = \"D E F A B C\"\n \t'\n test_expect_success \\\n \t'Float E A to top' \\\n \t'stg float E A &&\n-\t test \"$(echo $(stg applied))\" = \"D F B C E A\"\n+\t test \"$(echo $(stg series --applied --noprefix))\" = \"D F B C E A\"\n \t'\n test_expect_success \\\n \t'Float E to top' \\\n \t'stg float E &&\n-\t test \"$(echo $(stg applied))\" = \"D F B C A E\"\n+\t test \"$(echo $(stg series --applied --noprefix))\" = \"D F B C A E\"\n \t'\n test_expect_success \\\n \t'Float G F to top' \\\n \t'stg float G F &&\n-\t test \"$(echo $(stg applied))\" = \"D B C A E G F\"\n+\t test \"$(echo $(stg series --applied --noprefix))\" = \"D B C A E G F\"\n \t'\n test_done\ndiff --git a/t/t1501-sink.sh b/t/t1501-sink.sh\nindex ac9e25d..32931cd 100755\n--- a/t/t1501-sink.sh\n+++ b/t/t1501-sink.sh\n@@ -22,7 +22,7 @@ test_expect_success 'sink without applied patches' '\n \n test_expect_success 'sink a specific patch without applied patches' '\n     stg sink y &&\n-    test $(echo $(stg applied)) = \"y\"\n+    test $(echo $(stg series --applied --noprefix)) = \"y\"\n '\n \n test_done\ndiff --git a/t/t1600-delete-one.sh b/t/t1600-delete-one.sh\nindex b526a55..ef0b29d 100755\n--- a/t/t1600-delete-one.sh\n+++ b/t/t1600-delete-one.sh\n@@ -19,27 +19,27 @@ test_expect_success \\\n test_expect_success \\\n     'Try to delete a non-existing patch' \\\n     '\n-    [ $(stg applied | wc -l) -eq 1 ] &&\n+    [ $(stg series --applied -c) -eq 1 ] &&\n     command_error stg delete bar &&\n-    [ $(stg applied | wc -l) -eq 1 ]\n+    [ $(stg series --applied -c) -eq 1 ]\n     '\n \n test_expect_success \\\n     'Try to delete the topmost patch while dirty' \\\n     '\n     echo dirty >> foo.txt &&\n-    [ $(stg applied | wc -l) -eq 1 ] &&\n+    [ $(stg series --applied -c) -eq 1 ] &&\n     command_error stg delete foo &&\n-    [ $(stg applied | wc -l) -eq 1 ] &&\n+    [ $(stg series --applied -c) -eq 1 ] &&\n     git reset --hard\n     '\n \n test_expect_success \\\n     'Delete the topmost patch' \\\n     '\n-    [ $(stg applied | wc -l) -eq 1 ] &&\n+    [ $(stg series --applied -c) -eq 1 ] &&\n     stg delete foo &&\n-    [ $(stg applied | wc -l) -eq 0 ]\n+    [ $(stg series --applied -c) -eq 0 ]\n     '\n \n test_expect_success \\\n@@ -55,9 +55,9 @@ test_expect_success \\\n test_expect_success \\\n     'Delete an unapplied patch' \\\n     '\n-    [ $(stg unapplied | wc -l) -eq 1 ] &&\n+    [ $(stg series --unapplied -c) -eq 1 ] &&\n     stg delete foo &&\n-    [ $(stg unapplied | wc -l) -eq 0 ]\n+    [ $(stg series --unapplied -c) -eq 0 ]\n     '\n \n test_expect_success \\\n@@ -76,9 +76,9 @@ test_expect_success \\\n test_expect_success \\\n     'Try to delete a non-topmost applied patch' \\\n     '\n-    [ $(stg applied | wc -l) -eq 2 ] &&\n+    [ $(stg series --applied -c) -eq 2 ] &&\n     stg delete foo &&\n-    [ $(stg applied | wc -l) -eq 1 ]\n+    [ $(stg series --applied -c) -eq 1 ]\n     '\n \n test_expect_success \\\n@@ -99,11 +99,11 @@ test_expect_success \\\n test_expect_success \\\n     'Delete a patch in another branch' \\\n     '\n-    [ $(stg applied | wc -l) -eq 2 ] &&\n-    [ $(stg applied -b br | wc -l) -eq 1 ] &&\n+    [ $(stg series --applied -c) -eq 2 ] &&\n+    [ $(stg series --applied -b br -c) -eq 1 ] &&\n     stg delete -b br baz &&\n-    [ $(stg applied | wc -l) -eq 2 ] &&\n-    [ $(stg applied -b br | wc -l) -eq 0 ]\n+    [ $(stg series --applied -c) -eq 2 ] &&\n+    [ $(stg series --applied -b br -c) -eq 0 ]\n     '\n \n test_done\ndiff --git a/t/t1601-delete-many.sh b/t/t1601-delete-many.sh\nindex bc5364f..cb7fb0d 100755\n--- a/t/t1601-delete-many.sh\n+++ b/t/t1601-delete-many.sh\n@@ -25,31 +25,31 @@ test_expect_success \\\n test_expect_success \\\n     'Delete some patches' \\\n     '\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2 p3 p4\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p5 p6 p7 p8 p9\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2 p3 p4\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p5 p6 p7 p8 p9\" ] &&\n     stg delete p7 p6 p3 p4 &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p5 p8 p9\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p5 p8 p9\" ]\n     '\n \n test_expect_success \\\n     'Delete some more patches, some of which do not exist' \\\n     '\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p5 p8 p9\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p5 p8 p9\" ] &&\n     command_error stg delete p7 p8 p2 p0 &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p5 p8 p9\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p5 p8 p9\" ]\n     '\n \n test_expect_success \\\n     'Delete a range of patches' \\\n     '\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p5 p8 p9\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p5 p8 p9\" ] &&\n     stg delete p1..p8 &&\n-    [ \"$(echo $(stg applied))\" = \"p0\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p9\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p9\" ]\n     '\n \n test_done\ndiff --git a/t/t2000-sync.sh b/t/t2000-sync.sh\nindex f4e8b07..00ea7bd 100755\n--- a/t/t2000-sync.sh\n+++ b/t/t2000-sync.sh\n@@ -30,8 +30,8 @@ test_expect_success \\\n     stg refresh &&\n     stg export &&\n     stg pop &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p3\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p3\" ]\n     '\n \n test_expect_success \\\n@@ -41,16 +41,16 @@ test_expect_success \\\n     stg new p1 -m p1 &&\n     stg new p2 -m p2 &&\n     stg new p3 -m p3 &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n     '\n \n test_expect_success \\\n     'Synchronise second patch with the master branch' \\\n     '\n     stg sync -B master p2 &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ] &&\n     test $(cat foo2.txt) = \"foo2\"\n     '\n \n@@ -58,8 +58,8 @@ test_expect_success \\\n     'Synchronise the first two patches with the master branch' \\\n     '\n     stg sync -B master -a &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ] &&\n     test $(cat foo1.txt) = \"foo1\" &&\n     test $(cat foo2.txt) = \"foo2\"\n     '\n@@ -68,8 +68,8 @@ test_expect_success \\\n     'Synchronise all the patches with the exported series' \\\n     '\n     stg sync -s patches-master/series -a &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ] &&\n     test $(cat foo1.txt) = \"foo1\" &&\n     test $(cat foo2.txt) = \"foo2\" &&\n     test $(cat foo3.txt) = \"foo3\"\n@@ -79,8 +79,8 @@ test_expect_success \\\n     'Modify the master patches' \\\n     '\n     stg branch master &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p3\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p3\" ] &&\n     stg goto p1 &&\n     echo bar1 >> foo1.txt &&\n     stg refresh &&\n@@ -91,8 +91,8 @@ test_expect_success \\\n     stg goto p3 &&\n     echo bar3 >> foo3.txt &&\n     stg refresh &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ] &&\n     stg export &&\n     stg branch foo\n     '\n@@ -101,8 +101,8 @@ test_expect_success \\\n     'Synchronise second patch with the master branch' \\\n     '\n     stg sync -B master p2 &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ] &&\n     test $(cat bar2.txt) = \"bar2\"\n     '\n \n@@ -115,13 +115,13 @@ test_expect_success \\\n test_expect_success \\\n     'Restore the stack status after the failed sync' \\\n     '\n-    [ \"$(echo $(stg applied))\" = \"p1\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p2 p3\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p2 p3\" ] &&\n     stg resolved -a &&\n     stg refresh &&\n     stg goto p3\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n     '\n \n test_expect_success \\\n@@ -133,12 +133,12 @@ test_expect_success \\\n test_expect_success \\\n     'Restore the stack status after the failed sync' \\\n     '\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ] &&\n     stg resolved -a &&\n     stg refresh &&\n-    [ \"$(echo $(stg applied))\" = \"p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n     '\n \n test_done\ndiff --git a/t/t2200-rebase.sh b/t/t2200-rebase.sh\nindex 256eaaa..adbf242 100755\n--- a/t/t2200-rebase.sh\n+++ b/t/t2200-rebase.sh\n@@ -28,7 +28,7 @@ test_expect_success \\\n \t'\n \tstg rebase master~1 &&\n \ttest `stg id stack:{base}` = `git rev-parse master~1` &&\n-\ttest `stg applied | wc -l` = 1\n+\ttest `stg series --applied -c` = 1\n \t'\n \n test_expect_success \\\n@@ -40,7 +40,7 @@ test_expect_success \\\n test_expect_success \\\n \t'Check patches were re-applied' \\\n \t'\n-\ttest $(stg applied | wc -l) = 1\n+\ttest $(stg series --applied -c) = 1\n \t'\n \n test_done\ndiff --git a/t/t2500-clean.sh b/t/t2500-clean.sh\nindex abde9cf..99fd29f 100755\n--- a/t/t2500-clean.sh\n+++ b/t/t2500-clean.sh\n@@ -17,11 +17,11 @@ test_expect_success 'Initialize StGit stack' '\n '\n \n test_expect_success 'Clean empty patches' '\n-    [ \"$(echo $(stg applied))\" = \"e0 p0 e1\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"e2\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"e0 p0 e1\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"e2\" ] &&\n     stg clean &&\n-    [ \"$(echo $(stg applied))\" = \"p0\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n '\n \n test_expect_success 'Create a conflict' '\n@@ -37,8 +37,8 @@ test_expect_success 'Create a conflict' '\n \n test_expect_success 'Make sure conflicting patches are preserved' '\n     stg clean &&\n-    [ \"$(echo $(stg applied))\" = \"p0 p2 p1\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p2 p1\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n '\n \n test_done\ndiff --git a/t/t2600-coalesce.sh b/t/t2600-coalesce.sh\nindex f13a309..ef5bf99 100755\n--- a/t/t2600-coalesce.sh\n+++ b/t/t2600-coalesce.sh\n@@ -15,17 +15,17 @@ test_expect_success 'Initialize StGit stack' '\n '\n \n test_expect_success 'Coalesce some patches' '\n-    [ \"$(echo $(stg applied))\" = \"p0 p1 p2 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ] &&\n     stg coalesce --name=q0 --message=\"wee woo\" p1 p2 &&\n-    [ \"$(echo $(stg applied))\" = \"p0 q0 p3\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 q0 p3\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n '\n \n test_expect_success 'Coalesce at stack top' '\n     stg coalesce --name=q1 --message=\"wee woo wham\" q0 p3 &&\n-    [ \"$(echo $(stg applied))\" = \"p0 q1\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"\" ]\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 q1\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"\" ]\n '\n \n test_done\ndiff --git a/t/t3000-dirty-merge.sh b/t/t3000-dirty-merge.sh\nindex 4dd6da3..f0f79d5 100755\n--- a/t/t3000-dirty-merge.sh\n+++ b/t/t3000-dirty-merge.sh\n@@ -24,11 +24,11 @@ test_expect_success 'Pop one patch and update the other' '\n \n test_expect_success 'Push with dirty worktree' '\n     echo 4 > a &&\n-    [ \"$(echo $(stg applied))\" = \"p1\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p2\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p2\" ] &&\n     conflict stg goto p2 &&\n-    [ \"$(echo $(stg applied))\" = \"p1\" ] &&\n-    [ \"$(echo $(stg unapplied))\" = \"p2\" ] &&\n+    [ \"$(echo $(stg series --applied --noprefix))\" = \"p1\" ] &&\n+    [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p2\" ] &&\n     [ \"$(echo $(cat a))\" = \"4\" ]\n '\n \ndiff --git a/t/t4000-upgrade.sh b/t/t4000-upgrade.sh\nindex ea9bf0b..b89c720 100755\n--- a/t/t4000-upgrade.sh\n+++ b/t/t4000-upgrade.sh\n@@ -14,8 +14,8 @@ for ver in 0.12 0.8; do\n \n     test_expect_success \\\n         \"v$ver: Check the list of applied and unapplied patches\" '\n-        [ \"$(echo $(stg applied))\" = \"p0 p1 p2\" ] &&\n-        [ \"$(echo $(stg unapplied))\" = \"p3 p4\" ]\n+        [ \"$(echo $(stg series --applied --noprefix))\" = \"p0 p1 p2\" ] &&\n+        [ \"$(echo $(stg series --unapplied --noprefix))\" = \"p3 p4\" ]\n     '\n \n     test_expect_success \\\n"},{"id":"83143","messageId":"b0943d9e0807130442k36a10747q7bcbd996cdc774dd@mail.gmail.com","threadId":"14438","inReplyTo":"20080713113853.18845.37686.stgit@localhost.localdomain","subject":"Re: [PATCH 0/4] Proposed patches","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-13T11:42:22Z","receivedAt":"2008-07-13T11:42:22Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"2008/7/13 Catalin Marinas <catalin.marinas@gmail.com>:\n> A new post of the proposed patches after implementing Karl's comments.\n\nBTW, these are StGIT patches, I forgot to add the prefix in the subject line.\n\n-- \nCatalin\n"},{"id":"83162","messageId":"487A5032.9090307@etek.chalmers.se","threadId":"14438","inReplyTo":"b0943d9e0807130442k36a10747q7bcbd996cdc774dd@mail.gmail.com","subject":"Re: [PATCH 0/4] Proposed patches","fromName":"Lukas Sandström","fromEmail":"lukass@etek.chalmers.se","sentAt":"2008-07-13T18:57:54Z","receivedAt":"2008-07-13T18:57:54Z","isPatch":true,"sender":{"key":"luksan@gmail.com","avatar":"https://avatars.githubusercontent.com/u/152281?v=4"},"body":"Catalin Marinas wrote:\n> 2008/7/13 Catalin Marinas <catalin.marinas@gmail.com>:\n>> A new post of the proposed patches after implementing Karl's comments.\n> \n> BTW, these are StGIT patches, I forgot to add the prefix in the subject line.\n> \nIf you run \"git config format.subjectprefix 'StGIT PATCH'\" in your repo,\ngit format-patch will add the prefix automatically for you.\n\nStGIT might have a similar option.\n\n/Lukas\n"},{"id":"83176","messageId":"b0943d9e0807131410w2c08d55fg68aeb7070b2063cd@mail.gmail.com","threadId":"14438","inReplyTo":"487A5032.9090307@etek.chalmers.se","subject":"Re: [PATCH 0/4] Proposed patches","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-13T21:10:36Z","receivedAt":"2008-07-13T21:10:36Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"2008/7/13 Lukas Sandström <lukass@etek.chalmers.se>:\n> Catalin Marinas wrote:\n>> 2008/7/13 Catalin Marinas <catalin.marinas@gmail.com>:\n>>> A new post of the proposed patches after implementing Karl's comments.\n>>\n>> BTW, these are StGIT patches, I forgot to add the prefix in the subject line.\n>>\n> If you run \"git config format.subjectprefix 'StGIT PATCH'\" in your repo,\n> git format-patch will add the prefix automatically for you.\n>\n> StGIT might have a similar option.\n\nNo, it doesn't, but it would be good to have one. The alternative in\nStGIT is to modify the (local) template file.\n\nThanks,\n\n-- \nCatalin\n"},{"id":"83227","messageId":"20080714065814.GF20751@diana.vm.bytemark.co.uk","threadId":"14438","inReplyTo":"20080713114035.18845.45056.stgit@localhost.localdomain","subject":"Re: [PATCH 2/4] Implement a new patch identification scheme and id command","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-07-14T06:58:14Z","receivedAt":"2008-07-14T06:58:14Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-07-13 12:40:35 +0100, Catalin Marinas wrote:\n\n> The new scheme allows '[<branch>:]<patch>' and '[<branch>:]{base}'\n> (the latter showing the base of a stack). The former format allows\n> symbols like ^ and ^{...}.\n\nYou changed it, so s/The former format allows/You may append/ or\nsomething.\n\n> +    # The stack base\n> +    if patch.startswith('{base}'):\n> +        base_id = repository.get_stack(branch).base.sha1\n> +        return repository.rev_parse(base_id + patch[6:])\n\nWe have a strip_prefix() function precisely so that we can avoid\nerror-prone and not-so-easy-to-read constants like that \"6\" ...\n\nHmm. I see that I feel strongly enough about this that I've defined no\nless than two identical functions in utils.py to do this job:\nstrip_prefix() and strip_leading(). :-)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"83228","messageId":"20080714070739.GG20751@diana.vm.bytemark.co.uk","threadId":"14438","inReplyTo":"20080713114047.18845.34899.stgit@localhost.localdomain","subject":"Re: [PATCH 3/4] Convert git_id() to the new id format","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-07-14T07:07:39Z","receivedAt":"2008-07-14T07:07:39Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-07-13 12:40:48 +0100, Catalin Marinas wrote:\n\n> @@ -67,8 +64,8 @@ def func(parser, options, args):\n>                  rev = strip_suffix('/', rev)\n>                  if rev.endswith('/'):\n>                      rev = strip_suffix('/', rev)\n> -                rev1 = rev + '//bottom'\n> -                rev2 = rev + '//top'\n> +                rev1 = rev + 'HEAD^'\n> +                rev2 = rev + 'HEAD'\n\nThis looks bogus. You probably want to s/HEAD// here.\n\nI guess the test suite doesn't cover this? :-(\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"83229","messageId":"20080714071143.GH20751@diana.vm.bytemark.co.uk","threadId":"14438","inReplyTo":"20080713113853.18845.37686.stgit@localhost.localdomain","subject":"Re: [PATCH 0/4] Proposed patches","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-07-14T07:11:43Z","receivedAt":"2008-07-14T07:11:43Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-07-13 12:40:17 +0100, Catalin Marinas wrote:\n\n> A new post of the proposed patches after implementing Karl's\n> comments.\n\nLooks good -- except for the places where I posted some more comments.\n;-)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"83391","messageId":"20080715122203.GN25448@sirena.org.uk","threadId":"14438","inReplyTo":"20080713114026.18845.77979.stgit@localhost.localdomain","subject":"Re: [PATCH 1/4] Allow e-mails to be sent with the Unix sendmail tool","fromName":"Mark Brown","fromEmail":"broonie@sirena.org.uk","sentAt":"2008-07-15T12:22:20Z","receivedAt":"2008-07-15T12:22:20Z","isPatch":true,"sender":{"key":"broonie@sirena.org.uk","avatar":"https://gravatar.com/avatar/9e798c729a4a709279df497d9608ad68422755c9670e92434a5436f7e607cf86?d=mp&s=160"},"body":"On Sun, Jul 13, 2008 at 12:40:26PM +0100, Catalin Marinas wrote:\n> If the stgit.smtpserver configuration option does not have a host:port\n> format, it is assumed to be an external tool. For example, to use\n> sendmail just set this variable to \"/usr/sbin/sendmail -t -i\" (see the\n> examples/gitconfig file).\n\nI'd really expect to be able to just specify the hostname alone if using\nthe standard SMTP port.  Perhaps checking for a / in the server might be\nless surprising?\n\n-- \n\"You grabbed my hand and we fell into it, like a daydream - or a fever.\"\n"},{"id":"83390","messageId":"20080715123432.GB17008@diana.vm.bytemark.co.uk","threadId":"14438","inReplyTo":"20080715122203.GN25448@sirena.org.uk","subject":"Re: [PATCH 1/4] Allow e-mails to be sent with the Unix sendmail tool","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-07-15T12:34:32Z","receivedAt":"2008-07-15T12:34:32Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2008-07-15 13:22:20 +0100, Mark Brown wrote:\n\n> On Sun, Jul 13, 2008 at 12:40:26PM +0100, Catalin Marinas wrote:\n>\n> > If the stgit.smtpserver configuration option does not have a\n> > host:port format, it is assumed to be an external tool. For\n> > example, to use sendmail just set this variable to\n> > \"/usr/sbin/sendmail -t -i\" (see the examples/gitconfig file).\n>\n> I'd really expect to be able to just specify the hostname alone if\n> using the standard SMTP port. Perhaps checking for a / in the server\n> might be less surprising?\n\nThis is actually what the code does, and what the documentation claims\nit should do. It's just the commit message that's confused. Catalin?\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"83435","messageId":"b0943d9e0807151447s657a6bcao82548c930c0c8c6b@mail.gmail.com","threadId":"14438","inReplyTo":"20080715123432.GB17008@diana.vm.bytemark.co.uk","subject":"Re: [PATCH 1/4] Allow e-mails to be sent with the Unix sendmail tool","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-15T21:47:52Z","receivedAt":"2008-07-15T21:47:52Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"2008/7/15 Karl Hasselström <kha@treskal.com>:\n> On 2008-07-15 13:22:20 +0100, Mark Brown wrote:\n>\n>> On Sun, Jul 13, 2008 at 12:40:26PM +0100, Catalin Marinas wrote:\n>>\n>> > If the stgit.smtpserver configuration option does not have a\n>> > host:port format, it is assumed to be an external tool. For\n>> > example, to use sendmail just set this variable to\n>> > \"/usr/sbin/sendmail -t -i\" (see the examples/gitconfig file).\n>>\n>> I'd really expect to be able to just specify the hostname alone if\n>> using the standard SMTP port. Perhaps checking for a / in the server\n>> might be less surprising?\n>\n> This is actually what the code does, and what the documentation claims\n> it should do. It's just the commit message that's confused. Catalin?\n\nYes, indeed, but too many things to keep in sync :-).\n\n-- \nCatalin\n"},{"id":"84819","messageId":"20080725004430.12440.49829.stgit@yoghurt","threadId":"14438","inReplyTo":"20080713114047.18845.34899.stgit@localhost.localdomain","subject":"[StGit PATCH] Fix some remaining old-style stg id calls","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2008-07-25T00:47:34Z","receivedAt":"2008-07-25T00:47:34Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"Signed-off-by: Karl Hasselström <kha@treskal.com>\n\n---\n\nYou'll want to add this (just squash it into your patch). The calls\nwere failing, but since both sides produced the empty string on\nstdout, the test was happy anyway.\n\n t/t1300-uncommit.sh |   10 +++++-----\n 1 files changed, 5 insertions(+), 5 deletions(-)\n\n\ndiff --git a/t/t1300-uncommit.sh b/t/t1300-uncommit.sh\nindex a906d13..472baa4 100755\n--- a/t/t1300-uncommit.sh\n+++ b/t/t1300-uncommit.sh\n@@ -42,7 +42,7 @@ test_expect_success \\\n \t'Uncommit the patches using names' \\\n \t'\n \tstg uncommit bar foo &&\n-\t[ \"$(stg id foo//top)\" = \"$(stg id bar//bottom)\" ] &&\n+\t[ \"$(stg id foo)\" = \"$(stg id bar^)\" ] &&\n \tstg commit --all\n \t'\n \n@@ -50,7 +50,7 @@ test_expect_success \\\n \t'Uncommit the patches using prefix' \\\n \t'\n \tstg uncommit --number=2 foobar &&\n-\t[ \"$(stg id foobar1//top)\" = \"$(stg id foobar2//bottom)\" ] &&\n+\t[ \"$(stg id foobar1)\" = \"$(stg id foobar2^)\" ] &&\n \tstg commit --all\n \t'\n \n@@ -58,7 +58,7 @@ test_expect_success \\\n \t'Uncommit the patches using auto names' \\\n \t'\n \tstg uncommit --number=2 &&\n-\t[ \"$(stg id foo-patch//top)\" = \"$(stg id bar-patch//bottom)\" ] &&\n+\t[ \"$(stg id foo-patch)\" = \"$(stg id bar-patch^)\" ] &&\n \tstg commit --all\n \t'\n \n@@ -67,14 +67,14 @@ test_expect_success \\\n \t'\n \tstg uncommit &&\n \tstg uncommit &&\n-\t[ \"$(stg id foo-patch//top)\" = \"$(stg id bar-patch//bottom)\" ] &&\n+\t[ \"$(stg id foo-patch)\" = \"$(stg id bar-patch^)\" ] &&\n \tstg commit --all\n \t'\n \n test_expect_success \\\n     'Uncommit the patches with --to' '\n     stg uncommit --to HEAD^ &&\n-    [ \"$(stg id foo-patch//top)\" = \"$(stg id bar-patch//bottom)\" ] &&\n+    [ \"$(stg id foo-patch)\" = \"$(stg id bar-patch^)\" ] &&\n     stg commit --all\n '\n \n"},{"id":"85158","messageId":"b0943d9e0807270124q34d40782o59859d94602ffad7@mail.gmail.com","threadId":"14438","inReplyTo":"20080725004430.12440.49829.stgit@yoghurt","subject":"Re: [StGit PATCH] Fix some remaining old-style stg id calls","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-07-27T08:24:35Z","receivedAt":"2008-07-27T08:24:35Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"2008/7/25 Karl Hasselström <kha@treskal.com>:\n> You'll want to add this (just squash it into your patch). The calls\n> were failing, but since both sides produced the empty string on\n> stdout, the test was happy anyway.\n\nThanks, that's why I haven't noticed it.\n\n-- \nCatalin\n"},{"id":"88047","messageId":"b0943d9e0808211439x748b7b02s8c2fe21c2e9ea719@mail.gmail.com","threadId":"14438","inReplyTo":"20080714070739.GG20751@diana.vm.bytemark.co.uk","subject":"Re: [PATCH 3/4] Convert git_id() to the new id format","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-08-21T21:39:04Z","receivedAt":"2008-08-21T21:39:04Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"2008/7/14 Karl Hasselström <kha@treskal.com>:\n> On 2008-07-13 12:40:48 +0100, Catalin Marinas wrote:\n>\n>> @@ -67,8 +64,8 @@ def func(parser, options, args):\n>>                  rev = strip_suffix('/', rev)\n>>                  if rev.endswith('/'):\n>>                      rev = strip_suffix('/', rev)\n>> -                rev1 = rev + '//bottom'\n>> -                rev2 = rev + '//top'\n>> +                rev1 = rev + 'HEAD^'\n>> +                rev2 = rev + 'HEAD'\n>\n> This looks bogus. You probably want to s/HEAD// here.\n\nActually, the full \"if\" block here is useless. This was to specify\ndiff -r patch/ to show a patch but we now have the \"show\" command.\n\n> I guess the test suite doesn't cover this? :-(\n\nAnd it shouldn't, I removed it :-)\n\n-- \nCatalin\n"}]}