Hi Catalin,

Apologies for the trouble. This was my first attempt at submitting patches
via my gmail account.

See attached. These are outputs from `git format-patch` for the three patch
series I've sent to the list. I verified that I could import them with
`stgit import -M series1.txt`.

Thank you again for taking the time to look at these patches.

Cheers,
Pete


On Thu, Mar 9, 2017 at 12:17 PM, Catalin Marinas <[email protected]>
wrote:

> Hi Peter,
>
> On 27 February 2017 at 14:01, Peter Grayson <[email protected]> wrote:
> > diff --git a/README b/README
> > index 311c08dc..cbe93b7c 100644
> > --- a/README
> > +++ b/README
> > @@ -9,7 +9,7 @@ previously initialised Git repository (unless it is
> > cloned using StGit
> >  directly). For standard SCM operations, use plain Git commands.
>
> Thanks for the patches. However, for whatever reason, your mail client
> corrupts the patches by line-wrapping them (see above). StGit/Git fail
> to apply them. I could try to fix them up though it would take some
> time. Is it possible to send a pull request or maybe export to an mbox
> and send that separately?
>
> Thanks,
>
> Catalin
>
From f7564951760130a6609e27541f9c916a047336e3 Mon Sep 17 00:00:00 2001
Message-Id: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Mon, 2 Jan 2017 12:39:27 -0500
Subject: [PATCH 0/8] Testing Improvements
To: [email protected], [email protected]

I've been an extremely happy StGit user for a couple years, and I want
to see the project remain strong. To that end, I am working on several
series of janitorial patches that I hope will help keep StGit
maintainable into the future.

This first series of patches make several improvements to the test
infrastructure. New features include support for code coverage using the
`coverage` package and support for testing multiple python versions
using tox.

These changes are meant to improve confidence in the tests and thus pave
the way for more substantive changes.

Peter Grayson (8):
  Update URLs and email addresses
  Non-zero return code when tests fail.
  test.py ensures correct working directory
  Minor Makefile cleanups
  Enable tox test environment
  Coverage support
  Add test for `stg import --url`
  Add test for importing an mbox from stdin

 .coveragerc                     |  5 +++++
 .gitignore                      |  3 +++
 Documentation/SubmittingPatches |  8 ++++----
 Documentation/tutorial.txt      |  4 ++--
 Makefile                        | 16 ++++++++++++----
 README                          |  4 ++--
 examples/gitconfig              |  1 +
 stg                             |  4 ++++
 t/Makefile                      |  3 ---
 t/t0002-status.sh               |  2 +-
 t/t1800-import.sh               | 28 ++++++++++++++++++++++++++++
 t/t3100-reset.sh                |  2 +-
 t/t3101-reset-hard.sh           |  2 +-
 t/t3102-undo.sh                 |  2 +-
 t/t3103-undo-hard.sh            |  2 +-
 t/t3104-redo.sh                 |  2 +-
 t/t3105-undo-external-mod.sh    |  2 +-
 t/t3200-non-ascii-filenames.sh  |  2 +-
 t/test-lib.sh                   |  1 +
 t/test.py                       |  9 ++++++++-
 tox.ini                         |  6 ++++++
 21 files changed, 84 insertions(+), 24 deletions(-)
 create mode 100644 .coveragerc
 create mode 100644 tox.ini

From 7bc40be9aeec48304dc37a762efd396d87fabf8d Mon Sep 17 00:00:00 2001
Message-Id: 
<7bc40be9aeec48304dc37a762efd396d87fabf8d.1483378767.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Sat, 20 Feb 2016 18:09:46 -0500
Subject: [PATCH 1/8] Update URLs and email addresses
To: [email protected]

Replace several stale references to the stgit git repo and mailing list.

Signed-off-by: Peter Grayson <[email protected]>
---
 Documentation/SubmittingPatches | 8 ++++----
 Documentation/tutorial.txt      | 4 ++--
 README                          | 4 ++--
 examples/gitconfig              | 1 +
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index ec2d3d65..79a2674f 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -37,7 +37,7 @@ Checklist (and a short version for the impatient):
           documentation should be updated as well.
         - If your name is not writable in ASCII, make sure that
           you send off a message in the correct encoding.
-        - Send the patch to the list ([email protected]) and the
+        - Send the patch to the list ([email protected]) and the
           maintainer ([email protected]) if (and only if) the
           patch is ready for inclusion.
 
@@ -81,8 +81,8 @@ Long version:
 
 3. Sending your patches.
 
-   StGit patches should be sent to the Git mailing list
-   ([email protected]), and preferably CCed to the StGit maintainer
+   StGit patches should be sent to the StGit mailing list
+   ([email protected]), and preferably CCed to the StGit maintainer
    ([email protected]). The recipients need to be able to read
    and comment on the changes you are submitting. It is important for
    a developer to be able to "quote" your changes, using standard
@@ -225,7 +225,7 @@ One test you could do yourself if your MUA is set up 
correctly is:
 * Try to apply to the tip of the "master" branch from the
   public repository:
 
-    $ git fetch http://homepage.ntlworld.com/cmarinas/stgit.git 
master:test-apply
+    $ git fetch http://repo.or.cz/stgit.git master:test-apply
     $ git checkout test-apply
     $ git reset --hard
     $ stg init
diff --git a/Documentation/tutorial.txt b/Documentation/tutorial.txt
index 9dee5d83..d9c88173 100644
--- a/Documentation/tutorial.txt
+++ b/Documentation/tutorial.txt
@@ -211,7 +211,7 @@ Normally, when you pop a patch, change something, and then 
later push
 it again, StGit sorts out everything for you automatically. For
 example, let's create two patches that modify different files:
 
-  $ stg clone http://homepage.ntlworld.com/cmarinas/stgit.git stgit
+  $ stg clone http://repo.or.cz/stgit.git stgit
   $ cd stgit
   $ stg new first --message 'First patch'
   $ echo '- Do something' >> TODO
@@ -532,7 +532,7 @@ history at the time, your stack base will grow ever more 
out of date.
 
 When you clone a repository,
 
-  $ stg clone http://homepage.ntlworld.com/cmarinas/stgit.git stgit
+  $ stg clone http://repo.or.cz/stgit.git stgit
 
 you initially get one local branch, +master+. You also get a number of
 'remote' branches, one for each branch in the repository you cloned.
diff --git a/README b/README
index 311c08dc..cbe93b7c 100644
--- a/README
+++ b/README
@@ -9,7 +9,7 @@ previously initialised Git repository (unless it is cloned 
using StGit
 directly). For standard SCM operations, use plain Git commands.
 
 For the latest version see http://www.procode.org/stgit/
-For a tutorial see http://wiki.procode.org/cgi-bin/wiki.cgi/StGit_Tutorial
+For a tutorial see http://www.procode.org/stgit/doc/tutorial.html
 
-Bugs or feature requests should be sent to the [email protected]
+Bugs or feature requests should be sent to the [email protected]
 mailing list or the StGit project page - http://gna.org/projects/stgit/
diff --git a/examples/gitconfig b/examples/gitconfig
index 48a42468..301c84b4 100644
--- a/examples/gitconfig
+++ b/examples/gitconfig
@@ -92,6 +92,7 @@
 [mail "alias"]
        # E-mail aliases used with the 'mail' command
        git = [email protected]
+       stgit = [email protected]
 
 [stgit "color"]
        # Specify output colors for series commands

From bd5e383a3a2cffea50e3b8e56513ed27776dd774 Mon Sep 17 00:00:00 2001
Message-Id: 
<bd5e383a3a2cffea50e3b8e56513ed27776dd774.1483378767.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Sun, 21 Feb 2016 09:54:40 -0500
Subject: [PATCH 2/8] Non-zero return code when tests fail.
To: [email protected]

Test failures were opaque to make and/or the shell running the tests.
test.py now returns a non-zero return code if any tests fail.

Signed-off-by: Peter Grayson <[email protected]>
---
 t/test.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/t/test.py b/t/test.py
index f9a2ab71..e2241059 100644
--- a/t/test.py
+++ b/t/test.py
@@ -175,6 +175,10 @@ def main():
         for t in sorted(failed):
             print "  ", t
         print "Done"
+        return 1
+    else:
+        return 0
+
 
 if __name__ == "__main__":
-    main()
+    sys.exit(main())

From 7721ff13560f6d7a14e3419f462d2eff838f3064 Mon Sep 17 00:00:00 2001
Message-Id: 
<7721ff13560f6d7a14e3419f462d2eff838f3064.1483378767.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Mon, 26 Dec 2016 17:24:46 -0500
Subject: [PATCH 3/8] test.py ensures correct working directory
To: [email protected]

test.py expects its current working directory to be the directory it exists
in (i.e. t/). test.py now ensures the correct working directory by calling
os.chdir().

Signed-off-by: Peter Grayson <[email protected]>
---
 t/test.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/t/test.py b/t/test.py
index e2241059..7598ebe8 100644
--- a/t/test.py
+++ b/t/test.py
@@ -150,6 +150,9 @@ def start_cleaner(q):
     threading.Thread(target=w).start()
 
 def main():
+    this_dir = os.path.dirname(__file__)
+    if this_dir:
+        os.chdir(this_dir)
     p = optparse.OptionParser()
     p.add_option("-j", "--jobs", type="int",
                  help="number of tests to run in parallel")

From 5d4ce269697ce8a87ad9668282480669b84a1345 Mon Sep 17 00:00:00 2001
Message-Id: 
<5d4ce269697ce8a87ad9668282480669b84a1345.1483378767.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Sun, 21 Feb 2016 10:07:51 -0500
Subject: [PATCH 4/8] Minor Makefile cleanups
To: [email protected]

Use `make -C dir` instead of `cd dir && make` idiom.

Also remove unused variables from t/Makefile

Signed-off-by: Peter Grayson <[email protected]>
---
 Makefile   | 6 +++---
 t/Makefile | 3 ---
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 63a21f34..b05f9f3b 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ install:
        $(PYTHON) setup.py install --prefix=$(prefix) --root=$(DESTDIR) --force
 
 doc:
-       cd Documentation && $(MAKE) all
+       $(MAKE) -C Documentation all
 
 install-doc:
        $(MAKE) -C Documentation install
@@ -23,7 +23,7 @@ install-html:
 
 test:
        $(PYTHON) setup.py build
-       cd t && $(MAKE) all
+       $(MAKE) -C t all
 
 test_patches:
        for patch in $$(stg series --noprefix $(TEST_PATCHES)); do \
@@ -32,7 +32,7 @@ test_patches:
 
 clean:
        for dir in Documentation t; do \
-               (cd $$dir && $(MAKE) clean); \
+               $(MAKE) -C $$dir clean; \
        done
        rm -rf build
        rm -f stgit/*.pyc
diff --git a/t/Makefile b/t/Makefile
index e781131e..9e9be1b7 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -3,9 +3,6 @@
 # Copyright (c) 2005 Junio C Hamano
 #
 
-SHELL_PATH ?= $(SHELL)
-TAR ?= $(TAR)
-
 all:
        $(PYTHON) test.py
 

From 7407e456c2df6a92fd23d3e4ba870083e5757c69 Mon Sep 17 00:00:00 2001
Message-Id: 
<7407e456c2df6a92fd23d3e4ba870083e5757c69.1483378767.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Mon, 26 Dec 2016 23:56:42 -0500
Subject: [PATCH 5/8] Enable tox test environment
To: [email protected]

A tox.ini file is added that specifies Python 2.4, 2.5, 2.6, 2.7, and PyPy
test environments.

Signed-off-by: Peter Grayson <[email protected]>
---
 .gitignore | 1 +
 tox.ini    | 6 ++++++
 2 files changed, 7 insertions(+)
 create mode 100644 tox.ini

diff --git a/.gitignore b/.gitignore
index 42b5727c..70fabe34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ release.sh
 snapshot.sh
 stgit-completion.bash
 ChangeLog
+.tox
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 00000000..9d82f13b
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,6 @@
+[tox]
+envlist = py24,py25,py26,py27,pypy
+skip_missing_interpreters = True
+
+[testenv]
+commands = python t/test.py

From 91f0f5cb60737e85e2964607eb23a6d857df75d9 Mon Sep 17 00:00:00 2001
Message-Id: 
<91f0f5cb60737e85e2964607eb23a6d857df75d9.1483378767.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Sun, 21 Feb 2016 17:57:16 -0500
Subject: [PATCH 6/8] Coverage support
To: [email protected]

Enable code coverage using the `coverage` package. The top-level stg script
tests for the 'COVERAGE_PROCESS_START' environment variable to enable code
coverage mode.

Coverage is configured to generate separate .coverage files for each stg
process. This strategy allows aggregate coverage to be collected from
running the entire test suite.

A new 'make coverage' directive is added that invokes the test suite with
coverage enabled and collects the per-process .coverage files into a single
top-level .coverage file. An html report is generated.

The test system is modified so that the generated .coverage files are
excluded via the .git/info/exclude file. This required several tests to
append to the exclude file instead of overwriting it.

Signed-off-by: Peter Grayson <[email protected]>
---
 .coveragerc                    |  5 +++++
 .gitignore                     |  2 ++
 Makefile                       | 10 +++++++++-
 stg                            |  4 ++++
 t/t0002-status.sh              |  2 +-
 t/t3100-reset.sh               |  2 +-
 t/t3101-reset-hard.sh          |  2 +-
 t/t3102-undo.sh                |  2 +-
 t/t3103-undo-hard.sh           |  2 +-
 t/t3104-redo.sh                |  2 +-
 t/t3105-undo-external-mod.sh   |  2 +-
 t/t3200-non-ascii-filenames.sh |  2 +-
 t/test-lib.sh                  |  1 +
 13 files changed, 29 insertions(+), 9 deletions(-)
 create mode 100644 .coveragerc

diff --git a/.coveragerc b/.coveragerc
new file mode 100644
index 00000000..2680522b
--- /dev/null
+++ b/.coveragerc
@@ -0,0 +1,5 @@
+[run]
+source = stgit
+branch = True
+parallel = True
+data_file = .coverage
diff --git a/.gitignore b/.gitignore
index 70fabe34..e0fc0816 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@ snapshot.sh
 stgit-completion.bash
 ChangeLog
 .tox
+htmlcov/
+.coverage
diff --git a/Makefile b/Makefile
index b05f9f3b..c5c0d513 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,14 @@ test_patches:
                stg goto $$patch && $(MAKE) test || break; \
        done
 
+coverage:
+       $(PYTHON) -m coverage run setup.py build
+       COVERAGE_PROCESS_START=$(PWD)/.coveragerc $(MAKE) -C t all
+       $(PYTHON) -m coverage combine $$(find . -name '.coverage.*')
+       $(PYTHON) -m coverage html --title="stgit coverage"
+       $(PYTHON) -m coverage report
+       @echo "HTML coverage report: file://$(PWD)/htmlcov/index.html"
+
 clean:
        for dir in Documentation t; do \
                $(MAKE) -C $$dir clean; \
@@ -47,4 +55,4 @@ TAGS:
        ctags -e -R stgit/*
 
 .PHONY: all install doc install-doc install-html test test_patches \
-       clean tags TAGS
+       coverage clean tags TAGS
diff --git a/stg b/stg
index 5f0487af..9cbaed2a 100755
--- a/stg
+++ b/stg
@@ -39,4 +39,8 @@ if bin == 'bin' and prefix != sys.prefix:
 from stgit.main import main
 
 if __name__ == '__main__':
+    if os.environ.get('COVERAGE_PROCESS_START'):
+        import coverage
+        coverage.process_startup()
+
     main()
diff --git a/t/t0002-status.sh b/t/t0002-status.sh
index 619d5f4e..433b2d6f 100755
--- a/t/t0002-status.sh
+++ b/t/t0002-status.sh
@@ -11,7 +11,7 @@ Test that "stg status" works.'
 stg init
 
 # Ignore our own output files.
-cat > .git/info/exclude <<EOF
+cat >> .git/info/exclude <<EOF
 /expected.txt
 /output.txt
 EOF
diff --git a/t/t3100-reset.sh b/t/t3100-reset.sh
index 61f303df..cbd4a11d 100755
--- a/t/t3100-reset.sh
+++ b/t/t3100-reset.sh
@@ -5,7 +5,7 @@ test_description='Simple test cases for "stg reset"'
 . ./test-lib.sh
 
 # Ignore our own output files.
-cat > .git/info/exclude <<EOF
+cat >> .git/info/exclude <<EOF
 /expected.txt
 EOF
 
diff --git a/t/t3101-reset-hard.sh b/t/t3101-reset-hard.sh
index 85b5f46a..b279a934 100755
--- a/t/t3101-reset-hard.sh
+++ b/t/t3101-reset-hard.sh
@@ -5,7 +5,7 @@ test_description='Simple test cases for "stg reset"'
 . ./test-lib.sh
 
 # Ignore our own output files.
-cat > .git/info/exclude <<EOF
+cat >> .git/info/exclude <<EOF
 /expected.txt
 /actual.txt
 EOF
diff --git a/t/t3102-undo.sh b/t/t3102-undo.sh
index 010a63dc..c86e2e08 100755
--- a/t/t3102-undo.sh
+++ b/t/t3102-undo.sh
@@ -5,7 +5,7 @@ test_description='Simple test cases for "stg undo"'
 . ./test-lib.sh
 
 # Ignore our own output files.
-cat > .git/info/exclude <<EOF
+cat >> .git/info/exclude <<EOF
 /expected.txt
 EOF
 
diff --git a/t/t3103-undo-hard.sh b/t/t3103-undo-hard.sh
index f91b8c17..a758eab4 100755
--- a/t/t3103-undo-hard.sh
+++ b/t/t3103-undo-hard.sh
@@ -5,7 +5,7 @@ test_description='Simple test cases for "stg undo"'
 . ./test-lib.sh
 
 # Ignore our own output files.
-cat > .git/info/exclude <<EOF
+cat >> .git/info/exclude <<EOF
 /expected.txt
 /actual.txt
 EOF
diff --git a/t/t3104-redo.sh b/t/t3104-redo.sh
index 3d3c617f..ced6c4e2 100755
--- a/t/t3104-redo.sh
+++ b/t/t3104-redo.sh
@@ -5,7 +5,7 @@ test_description='Simple test cases for "stg redo"'
 . ./test-lib.sh
 
 # Ignore our own output files.
-cat > .git/info/exclude <<EOF
+cat >> .git/info/exclude <<EOF
 /expected.txt
 EOF
 
diff --git a/t/t3105-undo-external-mod.sh b/t/t3105-undo-external-mod.sh
index 19801676..880dcd58 100755
--- a/t/t3105-undo-external-mod.sh
+++ b/t/t3105-undo-external-mod.sh
@@ -5,7 +5,7 @@ test_description='Undo external modifications of the stack'
 . ./test-lib.sh
 
 # Ignore our own output files.
-cat > .git/info/exclude <<EOF
+cat >> .git/info/exclude <<EOF
 /expected.txt
 /head?.txt
 EOF
diff --git a/t/t3200-non-ascii-filenames.sh b/t/t3200-non-ascii-filenames.sh
index 748892a0..82bd6e97 100755
--- a/t/t3200-non-ascii-filenames.sh
+++ b/t/t3200-non-ascii-filenames.sh
@@ -4,7 +4,7 @@ test_description='Handle files with non-ASCII characters in 
their names'
 . ./test-lib.sh
 
 # Ignore our own output files.
-cat > .git/info/exclude <<EOF
+cat >> .git/info/exclude <<EOF
 /expected.txt
 /output.txt
 EOF
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 1f5a90d4..57cd131f 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -339,6 +339,7 @@ test_create_repo () {
            git commit-tree $(git write-tree) >.git/refs/heads/master 2>&4 || \
            error "cannot run git commit"
        mv .git/hooks .git/hooks-disabled
+       echo ".coverage.*" >> .git/info/exclude
        cd "$owd"
 }
 

From 66aa000f5e3b7daf62750d241b593596fd5e8f8d Mon Sep 17 00:00:00 2001
Message-Id: 
<66aa000f5e3b7daf62750d241b593596fd5e8f8d.1483378767.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Fri, 30 Dec 2016 10:25:13 -0500
Subject: [PATCH 7/8] Add test for `stg import --url`
To: [email protected]

This adds test coverage to an otherwise uncovered path.

Signed-off-by: Peter Grayson <[email protected]>
---
 t/t1800-import.sh | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/t/t1800-import.sh b/t/t1800-import.sh
index 7789a912..8539d97d 100755
--- a/t/t1800-import.sh
+++ b/t/t1800-import.sh
@@ -21,6 +21,15 @@ test_expect_success \
     stg delete ..
     '
 
+test_expect_success \
+    'Apply a patch from a URL' \
+    '
+    stg import -u file://$STG_ROOT/t/t1800-import/git-diff &&
+    [ $(git cat-file -p $(stg id) \
+      | grep -c "tree e96b1fba2160890ff600b675d7140d46b022b155") = 1 ] &&
+    stg delete ..
+    '
+
 test_expect_success \
     'Apply a patch created with "git diff" using -p1' \
     '

From f7564951760130a6609e27541f9c916a047336e3 Mon Sep 17 00:00:00 2001
Message-Id: 
<f7564951760130a6609e27541f9c916a047336e3.1483378767.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Fri, 30 Dec 2016 11:00:17 -0500
Subject: [PATCH 8/8] Add test for importing an mbox from stdin
To: [email protected]

The import command supports importing mbox from stdin using the deprecated
mailbox.UnixMailbox interface.

Signed-off-by: Peter Grayson <[email protected]>
---
 t/t1800-import.sh | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/t/t1800-import.sh b/t/t1800-import.sh
index 8539d97d..dc63c2a0 100755
--- a/t/t1800-import.sh
+++ b/t/t1800-import.sh
@@ -127,6 +127,25 @@ test_expect_success \
     stg delete ..
     '
 
+test_expect_success \
+    'Apply several patches from an mbox file from stdin' \
+    '
+    cat $STG_ROOT/t/t1800-import/email-mbox | stg import -M &&
+    [ $(git cat-file -p $(stg id change-1) \
+        | grep -c "tree 401bef82cd9fb403aba18f480a63844416a2e023") = 1 ] &&
+    [ $(git cat-file -p $(stg id change-1) \
+        | grep -c "author Inge Ström <[email protected]>") = 1 ] &&
+    [ $(git cat-file -p $(stg id change-2) \
+        | grep -c "tree e49dbce010ec7f441015a8c64bce0b99108af4cc") = 1 ] &&
+    [ $(git cat-file -p $(stg id change-2) \
+        | grep -c "author Inge Ström <[email protected]>") = 1 ] &&
+    [ $(git cat-file -p $(stg id change-3) \
+        | grep -c "tree 166bbaf27a44aee21ba78c98822a741e6f7d78f5") = 1 ] &&
+    [ $(git cat-file -p $(stg id change-3) \
+        | grep -c "author Inge Ström <[email protected]>") = 1 ] &&
+    stg delete ..
+    '
+
 test_expect_success \
     'Apply a bzip2 patch created with "git diff"' \
     '
From c53e920fa1aafa709bc2e394bbdb362dd682fb45 Mon Sep 17 00:00:00 2001
Message-Id: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Mon, 2 Jan 2017 12:41:00 -0500
Subject: [PATCH 0/4] Various Minor Bugfixes
To: [email protected]

This patch series contains repairs to various minor bugs. Most of these
bugs only affect rarely encountered error paths.

Peter Grayson (4):
  Deterministic email address order
  Repair undefined variable references
  Repair CmdException typo
  Repair StackException circular dependency

 stgit/commands/branch.py  |  2 +-
 stgit/commands/mail.py    | 20 +++++++++-----------
 stgit/exception.py        |  5 ++++-
 stgit/git.py              |  4 ++--
 stgit/lib/log.py          |  9 +++++----
 stgit/lib/stack.py        |  5 ++---
 stgit/lib/stackupgrade.py |  1 +
 stgit/stack.py            |  5 +----
 t/t1900-mail.sh           |  2 +-
 9 files changed, 26 insertions(+), 27 deletions(-)

From d7b776dfcaa27713497d31a144c607ad32803bf1 Mon Sep 17 00:00:00 2001
Message-Id: 
<d7b776dfcaa27713497d31a144c607ad32803bf1.1483378860.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Mon, 26 Dec 2016 22:33:43 -0500
Subject: [PATCH 1/4] Deterministic email address order
To: [email protected]

The email duplicates test in the t1900-mail.sh test script could fail
sporadically due to `stg email` arbitrarily ordering email addresses.

The root cause was __update_header() iterating a dict. The solution is to
modify __update_header() to collect email addresses in a list instead of a
dict to ensure deterministic ordering.

t1900-mail.sh is updated to expect the new deterministic ordering.

Signed-off-by: Peter Grayson <[email protected]>
---
 stgit/commands/mail.py | 20 +++++++++-----------
 t/t1900-mail.sh        |  2 +-
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index 2dc3dba6..4a18dba1 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -324,19 +324,17 @@ def __send_message(type, tmpl, options, *args):
     return msg_id
 
 def __update_header(msg, header, addr = '', ignore = ()):
-    def __addr_pairs(msg, header, extra):
-        pairs = email.Utils.getaddresses(msg.get_all(header, []) + extra)
-        # remove pairs without an address and resolve the aliases
-        return [address_or_alias(p) for p in pairs if p[1]]
-
-    addr_pairs = __addr_pairs(msg, header, [addr])
+    addr_pairs = email.Utils.getaddresses(msg.get_all(header, []) + [addr])
     del msg[header]
+    # remove pairs without an address and resolve the aliases
+    addr_pairs = [address_or_alias(name_addr) for name_addr in addr_pairs
+                  if name_addr[1]]
     # remove the duplicates and filter the addresses
-    addr_dict = dict((addr, email.Utils.formataddr((name, addr)))
-                     for name, addr in addr_pairs if addr not in ignore)
-    if addr_dict:
-        msg[header] = ', '.join(addr_dict.itervalues())
-    return set(addr_dict.iterkeys())
+    addr_pairs = [name_addr for name_addr in addr_pairs
+                  if name_addr[1] not in ignore]
+    if addr_pairs:
+        msg[header] = ', '.join(map(email.Utils.formataddr, addr_pairs))
+    return set(addr for _, addr in addr_pairs)
 
 def __build_address_headers(msg, options, extra_cc = []):
     """Build the address headers and check existing headers in the
diff --git a/t/t1900-mail.sh b/t/t1900-mail.sh
index 10cb7f9d..987beaef 100755
--- a/t/t1900-mail.sh
+++ b/t/t1900-mail.sh
@@ -75,7 +75,7 @@ test_expect_success \
     stg mail --to="a@a, b b <b@b>" --cc="b@b, c@c" \
         --bcc="c@c, d@d, [email protected]" --auto $(stg top) -m \
         -t $STG_ROOT/templates/patchmail.tmpl > mbox &&
-    test "$(cat mbox | grep -e "^To:")" = "To: b b <b@b>, a@a" &&
+    test "$(cat mbox | grep -e "^To:")" = "To: a@a, b b <b@b>" &&
     test "$(cat mbox | grep -e "^Cc:")" = \
         "Cc: C O Mitter <[email protected]>, c@c" &&
     test "$(cat mbox | grep -e "^Bcc:")" = "Bcc: d@d"

From 400e3e633e695e44dc8600c50f039331658ef89e Mon Sep 17 00:00:00 2001
Message-Id: 
<400e3e633e695e44dc8600c50f039331658ef89e.1483378860.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Sun, 21 Feb 2016 01:59:13 -0500
Subject: [PATCH 2/4] Repair undefined variable references
To: [email protected]

stgit.git.refspec_localpart() and stgit.git.refspec_remotepart() referenced
undefined variables in their error paths.

Signed-off-by: Peter Grayson <[email protected]>
---
 stgit/git.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/stgit/git.py b/stgit/git.py
index 0ba86bad..7ad2295a 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -864,14 +864,14 @@ def refspec_localpart(refspec):
     if m:
         return m.group(1)
     else:
-        raise GitException, 'Cannot parse refspec "%s"' % line
+        raise GitException('Cannot parse refspec "%s"' % refspec)
 
 def refspec_remotepart(refspec):
     m = re.match('^([^:]*):[^:]*$', refspec)
     if m:
         return m.group(1)
     else:
-        raise GitException, 'Cannot parse refspec "%s"' % line
+        raise GitException('Cannot parse refspec "%s"' % refspec)
 
 def __remotes_from_config():
     return config.sections_matching(r'remote\.(.*)\.url')

From b3b6ed21971907562274b84a684f590e64667089 Mon Sep 17 00:00:00 2001
Message-Id: 
<b3b6ed21971907562274b84a684f590e64667089.1483378860.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Tue, 27 Dec 2016 01:21:09 -0500
Subject: [PATCH 3/4] Repair CmdException typo
To: [email protected]

CmdExpection --> CmdException

Signed-off-by: Peter Grayson <[email protected]>
---
 stgit/commands/branch.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py
index fd0eb263..13a9f5ad 100644
--- a/stgit/commands/branch.py
+++ b/stgit/commands/branch.py
@@ -153,7 +153,7 @@ def __delete_branch(doomed_name, force = False):
 def __cleanup_branch(name, force = False):
     branch = stack.Series(name)
     if branch.get_protected():
-        raise CmdExcpetion('This branch is protected. Clean up is not 
permitted')
+        raise CmdException('This branch is protected. Clean up is not 
permitted')
 
     out.start('Cleaning up branch "%s"' % name)
     branch.delete(force = force, cleanup = True)

From c53e920fa1aafa709bc2e394bbdb362dd682fb45 Mon Sep 17 00:00:00 2001
Message-Id: 
<c53e920fa1aafa709bc2e394bbdb362dd682fb45.1483378860.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Tue, 27 Dec 2016 17:15:46 -0500
Subject: [PATCH 4/4] Repair StackException circular dependency
To: [email protected]

stackupgrade.py had an undefined reference to StackException.
stgit/stack.py and stgit/lib/stack.py both defined StackException classes.
To untangle potential circular dependencies between stack, lib.stack and
lib.stackupgrade, we move StackException to the dependency-less
stgit.exception module where it can be imported by all modules.

Signed-off-by: Peter Grayson <[email protected]>
---
 stgit/exception.py        | 5 ++++-
 stgit/lib/log.py          | 9 +++++----
 stgit/lib/stack.py        | 5 ++---
 stgit/lib/stackupgrade.py | 1 +
 stgit/stack.py            | 5 +----
 5 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/stgit/exception.py b/stgit/exception.py
index 9933e641..e26da84e 100644
--- a/stgit/exception.py
+++ b/stgit/exception.py
@@ -1,3 +1,6 @@
 class StgException(Exception):
     """Base class for all StGit exceptions."""
-    pass
+
+
+class StackException(StgException):
+    """Exception raised by L{stack} objects."""
diff --git a/stgit/lib/log.py b/stgit/lib/log.py
index d876ff60..6c707f2a 100644
--- a/stgit/lib/log.py
+++ b/stgit/lib/log.py
@@ -101,11 +101,12 @@ mainly ease of visualization."""
 
 import re
 from stgit.lib import git, stack as libstack
-from stgit import exception, utils
+from stgit import utils
+from stgit.exception import StgException, StackException
 from stgit.out import out
 import StringIO
 
-class LogException(exception.StgException):
+class LogException(StgException):
     pass
 
 class LogParseException(LogException):
@@ -362,7 +363,7 @@ def compat_log_entry(msg):
     try:
         repo = default_repo()
         stack = repo.get_stack(repo.current_branch_name)
-    except (libstack.StackException, git.RepositoryException), e:
+    except (StackException, git.RepositoryException) as e:
         out.warn(str(e), 'Could not write to stack log')
     else:
         if repo.default_index.conflicts() and stack.patchorder.applied:
@@ -518,7 +519,7 @@ def compat_log_external_mods():
         return
     try:
         stack = repo.get_stack(repo.current_branch_name)
-    except exception.StgException:
+    except StgException:
         # Stack doesn't exist, so we can't log.
         return
     log_external_mods(stack)
diff --git a/stgit/lib/stack.py b/stgit/lib/stack.py
index a72ee229..f9a4454b 100644
--- a/stgit/lib/stack.py
+++ b/stgit/lib/stack.py
@@ -1,12 +1,11 @@
 """A Python class hierarchy wrapping the StGit on-disk metadata."""
 
 import os.path
-from stgit import exception, utils
+from stgit import utils
+from stgit.exception import StackException
 from stgit.lib import git, stackupgrade
 from stgit.config import config
 
-class StackException(exception.StgException):
-    """Exception raised by L{stack} objects."""
 
 class Patch(object):
     """Represents an StGit patch. This class is mainly concerned with
diff --git a/stgit/lib/stackupgrade.py b/stgit/lib/stackupgrade.py
index 4b437dc0..daa176ba 100644
--- a/stgit/lib/stackupgrade.py
+++ b/stgit/lib/stackupgrade.py
@@ -2,6 +2,7 @@ import os.path
 from stgit import utils
 from stgit.out import out
 from stgit.config import config
+from stgit.exception import StackException
 
 # The current StGit metadata format version.
 FORMAT_VERSION = 2
diff --git a/stgit/stack.py b/stgit/stack.py
index f79f76fe..7782f3ff 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -20,7 +20,7 @@ along with this program; if not, see 
http://www.gnu.org/licenses/.
 import sys, os, re
 from email.Utils import formatdate
 
-from stgit.exception import *
+from stgit.exception import StackException
 from stgit.utils import *
 from stgit.out import *
 from stgit.run import *
@@ -29,9 +29,6 @@ from stgit.config import config
 from shutil import copyfile
 from stgit.lib import git as libgit, stackupgrade
 
-# stack exception class
-class StackException(StgException):
-    pass
 
 class FilterUntil:
     def __init__(self):
From 215ad54a03cb97336402851a8d7a90255b53dc2a Mon Sep 17 00:00:00 2001
Message-Id: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Mon, 2 Jan 2017 12:42:03 -0500
Subject: [PATCH 0/4] Python 2.4/2.5 and PyPy Support
To: [email protected]

I am actually not at all interested in support for Python 2.4 (or 2.5 or
2.6). My real objective is for StGit to support Python 2.7 and 3.x
out of the same code base. But experience indicates that old Python
versions die hard. So as an intermediate goal, I want to establish a
final version of StGit that supports legacy Python 2.x versions so that
we can make the breaking changes required to simultaneously support
Python 2.7 and 3.x.

Some idioms have snuck in that break support for Python 2.4 (and
probably 2.5). Also, PyPy 5.6 (implementing Python 2.7) was broken due
to a subtle StGit bug along with a subtle difference between CPython and
PyPy semantics concerning builtin functions.

These patches enable full support of PyPy and restore basic Python 2.4
compatibility, although not all tests pass with Python 2.4 and I have
not deep-dived the remaining problems. The following tests still fail
with Python 2.4:

   t1000-branch-create.sh
   t1800-import.sh
   t1900-mail.sh
   t3300-edit.sh
   t4100-publish.sh

Peter Grayson (4):
  Repair support for Python 2.4
  Python 2.4 compatibility for test.py
  Repair custom any() and all() implementations
  Add classifiers and download_url to setup.py

 setup.py                 | 21 +++++++++++-
 stgit/lib/git.py         |  4 ++-
 stgit/lib/transaction.py |  2 +-
 stgit/utils.py           |  9 ++++--
 t/test.py                | 84 ++++++++++++++++++++++++++++++++----------------
 5 files changed, 87 insertions(+), 33 deletions(-)

From ff195ff9d71540291d43ff99e6b0d996696698b7 Mon Sep 17 00:00:00 2001
Message-Id: 
<ff195ff9d71540291d43ff99e6b0d996696698b7.1483378923.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Thu, 29 Dec 2016 18:31:33 -0500
Subject: [PATCH 1/4] Repair support for Python 2.4
To: [email protected]

Replace a use of a keyword argument after splatted positional arguments
(*args) which is not supported by Python 2.4. Using explicit positional
arguments instead of the splat allows Python 2.4 to work for most stg
commands.

Signed-off-by: Peter Grayson <[email protected]>
---
 stgit/lib/git.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/stgit/lib/git.py b/stgit/lib/git.py
index c1565250..cf9f720d 100644
--- a/stgit/lib/git.py
+++ b/stgit/lib/git.py
@@ -106,8 +106,10 @@ def system_date(datestring):
         except run.RunException:
             return None
         (t, z) = d.split("_")
+    year, month, day, hour, minute, second = [int(x) for x in t.split("-")]
     try:
-        return datetime(*[int(x) for x in t.split("-")], tzinfo=TimeZone(z))
+        return datetime(year, month, day, hour, minute, second,
+                        tzinfo=TimeZone(z))
     except ValueError:
         raise DateException(datestring, "date")
 

From 67e112d4647c8b2c728b8b86a7ca4dad454e1aa8 Mon Sep 17 00:00:00 2001
Message-Id: 
<67e112d4647c8b2c728b8b86a7ca4dad454e1aa8.1483378923.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Sun, 1 Jan 2017 17:53:36 -0500
Subject: [PATCH 2/4] Python 2.4 compatibility for test.py
To: [email protected]

This replaces uses of try/except/finally, context managers, and the ternary
operator that prevented test.py from being runnable with Python 2.4.

The intent is for this patch to be reverted once Python 2.4/2.5 support is
officially abandoned.

Signed-off-by: Peter Grayson <[email protected]>
---
 t/test.py | 84 ++++++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 56 insertions(+), 28 deletions(-)

diff --git a/t/test.py b/t/test.py
index 7598ebe8..855b2302 100644
--- a/t/test.py
+++ b/t/test.py
@@ -70,72 +70,97 @@ class TestQueue(object):
 
     # Yield free jobs until none are left.
     def next(self):
-        with self.lock:
+        self.lock.acquire()
+        try:
             if not self.__remaining:
                 raise StopIteration
             t = self.__remaining.pop()
             self.__running.add(t)
             self.__report()
             return t
+        finally:
+            self.lock.release()
 
     # Report that a job has completed.
     def finished(self, t, success):
-        with self.lock:
+        self.lock.acquire()
+        try:
             self.__running.remove(t)
-            (self.__success if success else self.__fail).add(t)
+            if success:
+                self.__success.add(t)
+            else:
+                self.__fail.add(t)
             self.__report()
+        finally:
+            self.lock.release()
 
     # Yield free cleaning jobs until none are left.
     def cleaning_jobs(self):
         while True:
-            with self.lock:
+            self.lock.acquire()
+            try:
                 if not self.__clean_todo:
                     return
                 c = self.__clean_todo.pop()
                 self.__clean_running.add(c)
+            finally:
+                self.lock.release()
             yield c
 
     # Report that a cleaning job has completed.
     def deleted(self, c):
-        with self.lock:
+        self.lock.acquire()
+        try:
             self.__clean_running.remove(c)
             self.__clean_done.add(c)
             self.__report()
+        finally:
+            self.lock.release()
 
     # Wait for all jobs to complete.
     def wait(self):
-        with self.lock:
+        self.lock.acquire()
+        try:
             while not self.__done():
                 self.__cv.wait()
             for c in self.__clean_jobs:
                 os.rmdir(c)
             return set(self.__fail)
+        finally:
+            self.lock.release()
 
 def start_worker(q):
     def w():
         for t in q:
             try:
-                ok = False  # assume the worst until proven otherwise
-                s = os.path.join("trash", t)
-                e = dict(os.environ)
-                e["SCRATCHDIR"] = s
-                p = subprocess.Popen([os.path.join(os.getcwd(), t), "-v"],
-                                     stdout=subprocess.PIPE,
-                                     stderr=subprocess.STDOUT,
-                                     env=e)
-                (out, err) = p.communicate()
-                assert err is None
-                with open(os.path.join(s, "output"), "w") as f:
-                    f.write(out)
-                    f.write("\nExited with code %d\n" % p.returncode)
-                if p.returncode == 0:
-                    ok = True
-            except:
-                # Log the traceback. Use the mutex so that we
-                # won't write multiple tracebacks to stderr at the
-                # same time.
-                with q.lock:
-                    traceback.print_exc()
+                try:
+                    ok = False  # assume the worst until proven otherwise
+                    s = os.path.join("trash", t)
+                    e = dict(os.environ)
+                    e["SCRATCHDIR"] = s
+                    p = subprocess.Popen([os.path.join(os.getcwd(), t), "-v"],
+                                         stdout=subprocess.PIPE,
+                                         stderr=subprocess.STDOUT,
+                                         env=e)
+                    (out, err) = p.communicate()
+                    assert err is None
+                    f = open(os.path.join(s, "output"), "w")
+                    try:
+                        f.write(out)
+                        f.write("\nExited with code %d\n" % p.returncode)
+                    finally:
+                        f.close()
+                    if p.returncode == 0:
+                        ok = True
+                except:
+                    # Log the traceback. Use the mutex so that we
+                    # won't write multiple tracebacks to stderr at the
+                    # same time.
+                    q.lock.acquire()
+                    try:
+                        traceback.print_exc()
+                    finally:
+                        q.lock.release()
             finally:
                 q.finished(t, ok)
     threading.Thread(target=w).start()
@@ -144,7 +169,10 @@ def start_cleaner(q):
     def w():
         for c in q.cleaning_jobs():
             try:
-                (shutil.rmtree if os.path.isdir(c) else os.remove)(c)
+                if os.path.isdir(c):
+                    shutil.rmtree(c)
+                else:
+                    os.remove(c)
             finally:
                 q.deleted(c)
     threading.Thread(target=w).start()

From fdb62c3bb0e5c607f0fb379957693f6385624e96 Mon Sep 17 00:00:00 2001
Message-Id: 
<fdb62c3bb0e5c607f0fb379957693f6385624e96.1483378923.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Thu, 29 Dec 2016 20:42:44 -0500
Subject: [PATCH 3/4] Repair custom any() and all() implementations
To: [email protected]

These functions were only defined in the the stgit.utils module when they
were not present in __builtins__, however transaction.py unconditionally
imported these symbols. This was breaking PyPy since builtins are not
assumed to be in the stgit.transaction module namespace. Apparently in
CPython, builtins are implicitly in modules' namespaces.

Signed-off-by: Peter Grayson <[email protected]>
---
 stgit/lib/transaction.py | 2 +-
 stgit/utils.py           | 9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index 4d7214e9..4532acba 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -5,7 +5,7 @@ import atexit
 import itertools as it
 
 from stgit import exception, utils
-from stgit.utils import any, all
+from stgit.utils import any
 from stgit.out import *
 from stgit.lib import git, log
 from stgit.config import config
diff --git a/stgit/utils.py b/stgit/utils.py
index 83679d47..3159b12f 100644
--- a/stgit/utils.py
+++ b/stgit/utils.py
@@ -293,13 +293,18 @@ def make_patch_name(msg, unacceptable, default_name = 
'patch'):
 
 # any and all functions are builtin in Python 2.5 and higher, but not
 # in 2.4.
-if not 'any' in dir(__builtins__):
+if 'any' in dir(__builtins__):
+    any = getattr(__builtins__, 'any')
+else:
     def any(bools):
         for b in bools:
             if b:
                 return True
         return False
-if not 'all' in dir(__builtins__):
+
+if 'all' in dir(__builtins__):
+    all = getattr(__builtins__, 'all')
+else:
     def all(bools):
         for b in bools:
             if not b:

From 215ad54a03cb97336402851a8d7a90255b53dc2a Mon Sep 17 00:00:00 2001
Message-Id: 
<215ad54a03cb97336402851a8d7a90255b53dc2a.1483378923.git.jpgray...@gmail.com>
In-Reply-To: <[email protected]>
References: <[email protected]>
From: Peter Grayson <[email protected]>
Date: Wed, 28 Dec 2016 22:55:47 -0500
Subject: [PATCH 4/4] Add classifiers and download_url to setup.py
To: [email protected]

The classifiers are used by PyPI in case StGit is ever published there. The
classifiers specify compatibility with CPython 2.4 through 2.7 along with
PyPy.

Signed-off-by: Peter Grayson <[email protected]>
---
 setup.py | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/setup.py b/setup.py
index e765e3d7..139f3958 100755
--- a/setup.py
+++ b/setup.py
@@ -51,6 +51,7 @@ def __run_setup():
           author = 'Catalin Marinas',
           author_email = '[email protected]',
           url = 'http://www.procode.org/stgit/',
+          download_url = 'http://repo.or.cz/stgit.git',
           description = 'Stacked GIT',
           long_description = 'Push/pop utility on top of GIT',
           scripts = ['stg'],
@@ -61,7 +62,25 @@ def __run_setup():
             ('share/stgit/examples', ['examples/gitconfig']),
             ('share/stgit/contrib', ['contrib/stgbashprompt.sh']),
             ('share/stgit/completion', ['stgit-completion.bash'])
-            ])
+          ],
+          classifiers = [
+              'Development Status :: 5 - Production/Stable',
+              'Environment :: Console',
+              'Intended Audience :: Developers',
+              'License :: OSI Approved :: GNU General Public License v2 
(GPLv2)'
+              'Natural Language :: English',
+              'Operating System :: OS Independent',
+              'Programming Language :: Python',
+              'Programming Language :: Python :: 2',
+              'Programming Language :: Python :: 2.4',
+              'Programming Language :: Python :: 2.5',
+              'Programming Language :: Python :: 2.6',
+              'Programming Language :: Python :: 2.7',
+              'Programming Language :: Python :: Implementation :: CPython',
+              'Programming Language :: Python :: Implementation :: PyPy',
+              'Topic :: Software Development :: Version Control',
+          ])
+
 
 # Check the minimum versions required
 __check_python_version()
_______________________________________________
stgit-users mailing list
[email protected]
https://mail.gna.org/listinfo/stgit-users

Reply via email to