Your message dated Sun, 18 Jan 2015 15:33:55 +0000
with message-id <e1ycrrp-0000jv...@franck.debian.org>
and subject line Bug#771215: fixed in git-buildpackage 0.6.23
has caused the Debian Bug report #771215,
regarding git-buildpackage: please merge support for gbp pq-rpm
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
771215: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=771215
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Source: git-buildpackage
Version: 0.6.22
Severity: wishlist

Dear Maintainer,

I attach a pretty trivial merge of the command gbp pq-rpm from the
git-buildpackage-rpm tree. I basically included the script itself and
added two patches it depended on. Those two patches are intended to
make the patch queue branch name more configurable.

If those patches are not acceptable, I'll try rewriting the script to
avoid them.

-- 
Tzafrir Cohen         | tzaf...@jabber.org | VIM is
http://tzafrir.org.il |                    | a Mutt's
tzaf...@cohens.org.il |                    |  best
tzaf...@debian.org    |                    | friend
>From 4da187b8880d3a27c29bec7163feb4a499a95fa6 Mon Sep 17 00:00:00 2001
From: Markus Lehtonen <markus.lehto...@linux.intel.com>
Date: Fri, 6 Sep 2013 14:23:03 +0300
Subject: [PATCH 2/3] common/pq: support more flexible pq-branch naming

Now any string fields (e.g. '%(version)s') can be used in the pq-branch
format strings - in addition to the '%(branch)s' supported before.

Signed-off-by: Markus Lehtonen <markus.lehto...@linux.intel.com>
---
 gbp/scripts/common/pq.py | 67 +++++++++++++++++++++++++++++++-----------------
 1 file changed, 43 insertions(+), 24 deletions(-)

diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py
index 9bc04e3..096469d 100644
--- a/gbp/scripts/common/pq.py
+++ b/gbp/scripts/common/pq.py
@@ -35,6 +35,22 @@ import gbp.log
 DEFAULT_PQ_BRANCH_NAME = "patch-queue/%(branch)s"
 
 
+def pq_branch_match(branch, pq_fmt_str):
+    """
+    Match branch name with pq branch name pattern
+
+    >>> pq_branch_match('patch-queue/foo', 'patch-queue/%(br)s').groupdict()
+    {'br': 'foo'}
+    >>> pq_branch_match('pq/foo/bar', 'pq/%(br)s/baz')
+    >>> pq_branch_match('pq/foo/bar', 'pq/%(br)s/bar').groupdict()
+    {'br': 'foo'}
+    >>> pq_branch_match('foo/bar/1.0/pq', 'foo/%(br)s/%(ver)s/pq').groupdict()
+    {'ver': '1.0', 'br': 'bar'}
+    """
+    pq_re = '^%s$' % re.sub('%\(([a-z_\-]+)\)s', r'(?P<\1>\S+)', pq_fmt_str)
+    return  re.match(pq_re, branch)
+
+
 def is_pq_branch(branch, options):
     """
     is branch a patch-queue branch?
@@ -58,18 +74,20 @@ def is_pq_branch(branch, options):
     False
     >>> is_pq_branch("my/foo/pq", opts)
     True
+    >>> opts.pq_branch = "my/%(branch)s/%(version)s"
+    >>> is_pq_branch("my/foo", opts)
+    False
+    >>> is_pq_branch("my/foo/1.0", opts)
+    True
     """
-    pq_format_str = DEFAULT_PQ_BRANCH_NAME
-    if hasattr(options, 'pq_branch'):
-        pq_format_str = options.pq_branch
-
-    pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P<base>\S+)")))
-    if pq_re.match(branch):
+    pq_format_str = (options.pq_branch if hasattr(options, 'pq_branch')
+                                       else DEFAULT_PQ_BRANCH_NAME)
+    if pq_branch_match(branch, pq_format_str):
         return True
     return False
 
 
-def pq_branch_name(branch, options):
+def pq_branch_name(branch, options, extra_keys=None):
     """
     get the patch queue branch corresponding to branch
 
@@ -84,13 +102,17 @@ def pq_branch_name(branch, options):
     >>> opts.pq_branch = "development"
     >>> pq_branch_name("foo", opts)
     'development'
+    >>> opts.pq_branch = "pq/%(branch)s/%(ver)s"
+    >>> pq_branch_name("foo", opts, {'ver': '1.0'})
+    'pq/foo/1.0'
     """
-    pq_format_str = DEFAULT_PQ_BRANCH_NAME
-    if hasattr(options, 'pq_branch'):
-        pq_format_str = options.pq_branch
-
+    pq_format_str = (options.pq_branch if hasattr(options, 'pq_branch')
+                                       else DEFAULT_PQ_BRANCH_NAME)
+    format_fields = {'branch': branch}
+    if extra_keys:
+        format_fields.update(extra_keys)
     if not is_pq_branch(branch, options):
-        return pq_format_str % dict(branch=branch)
+        return pq_format_str % format_fields
 
 
 def pq_branch_base(pq_branch, options):
@@ -115,15 +137,12 @@ def pq_branch_base(pq_branch, options):
     >>> pq_branch_base("development", opts)
     'packaging'
     """
-    pq_format_str = DEFAULT_PQ_BRANCH_NAME
-    if hasattr(options, 'pq_branch'):
-        pq_format_str = options.pq_branch
-
-    pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P<base>\S+)")))
-    m = pq_re.match(pq_branch)
+    pq_format_str = (options.pq_branch if hasattr(options, 'pq_branch')
+                                       else DEFAULT_PQ_BRANCH_NAME)
+    m = pq_branch_match(pq_branch, pq_format_str)
     if m:
-        if 'base' in m.groupdict():
-            return m.group('base')
+        if 'branch' in m.groupdict():
+            return m.group('branch')
         return options.packaging_branch
 
 
@@ -298,7 +317,7 @@ def get_maintainer_from_control(repo):
     return GitModifier()
 
 
-def switch_to_pq_branch(repo, branch, options):
+def switch_to_pq_branch(repo, branch, options, name_keys=None):
     """
     Switch to patch-queue branch if not already there, create it if it
     doesn't exist yet
@@ -306,7 +325,7 @@ def switch_to_pq_branch(repo, branch, options):
     if is_pq_branch(branch, options):
         return
 
-    pq_branch = pq_branch_name(branch, options)
+    pq_branch = pq_branch_name(branch, options, name_keys)
     if not repo.has_branch(pq_branch):
         try:
             repo.create_branch(pq_branch)
@@ -349,12 +368,12 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None):
     repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path)
 
 
-def drop_pq(repo, branch, options):
+def drop_pq(repo, branch, options, name_keys=None):
     if is_pq_branch(branch, options):
         gbp.log.err("On a patch-queue branch, can't drop it.")
         raise GbpError
     else:
-        pq_branch = pq_branch_name(branch, options)
+        pq_branch = pq_branch_name(branch, options, name_keys)
 
     if repo.has_branch(pq_branch):
         repo.delete_branch(pq_branch)
-- 
2.1.3

>From d99ca225c15f927f9acf61cac4ffd81263ca9067 Mon Sep 17 00:00:00 2001
From: Markus Lehtonen <markus.lehto...@linux.intel.com>
Date: Fri, 11 May 2012 10:56:17 +0300
Subject: [PATCH 1/3] gbp-pq: readiness to configure the pq branch name

All other gbp branches have configurable names. This commit adds the
readiness for user to configure/change the name of the patch-queue
branches, as well.

Patch-queue is defined in options as a format string, where '%(branch)s'
refers to the debian/packaging branch. If the pq-branch format string
does not contain '%(branch)s', there is only one patch-queue branch and
the debian/packaging branch is used as its base branch. That is, e.g. a
'gbp-pq switch' operation from the patch-queue branch always switches to
the debian/packaging branch.

Signed-off-by: Markus Lehtonen <markus.lehto...@linux.intel.com>
Signed-off-by: Olev Kartau <olev.kar...@intel.com>
---
 gbp/scripts/common/pq.py | 107 ++++++++++++++++++++++++++++++++++++-----------
 gbp/scripts/pq.py        |  52 +++++++++++------------
 tests/13_test_gbp_pq.py  |   5 ++-
 3 files changed, 111 insertions(+), 53 deletions(-)

diff --git a/gbp/scripts/common/pq.py b/gbp/scripts/common/pq.py
index d3c07d1..9bc04e3 100644
--- a/gbp/scripts/common/pq.py
+++ b/gbp/scripts/common/pq.py
@@ -32,43 +32,99 @@ from gbp.git.modifier import GitModifier, GitTz
 from gbp.errors import GbpError
 import gbp.log
 
-PQ_BRANCH_PREFIX = "patch-queue/"
+DEFAULT_PQ_BRANCH_NAME = "patch-queue/%(branch)s"
 
 
-def is_pq_branch(branch):
+def is_pq_branch(branch, options):
     """
     is branch a patch-queue branch?
 
-    >>> is_pq_branch("foo")
+    >>> from optparse import OptionParser
+    >>> (opts, args) = OptionParser().parse_args([])
+    >>> is_pq_branch("foo", opts)
     False
-    >>> is_pq_branch("patch-queue/foo")
+    >>> is_pq_branch("patch-queue/foo", opts)
+    True
+    >>> opts.pq_branch = "%(branch)s/development"
+    >>> is_pq_branch("foo/development/bar", opts)
+    False
+    >>> is_pq_branch("bar/foo/development", opts)
+    True
+    >>> opts.pq_branch = "development"
+    >>> is_pq_branch("development", opts)
+    True
+    >>> opts.pq_branch = "my/%(branch)s/pq"
+    >>> is_pq_branch("my/foo/pqb", opts)
+    False
+    >>> is_pq_branch("my/foo/pq", opts)
     True
     """
-    return [False, True][branch.startswith(PQ_BRANCH_PREFIX)]
+    pq_format_str = DEFAULT_PQ_BRANCH_NAME
+    if hasattr(options, 'pq_branch'):
+        pq_format_str = options.pq_branch
 
+    pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P<base>\S+)")))
+    if pq_re.match(branch):
+        return True
+    return False
 
-def pq_branch_name(branch):
+
+def pq_branch_name(branch, options):
     """
     get the patch queue branch corresponding to branch
 
-    >>> pq_branch_name("patch-queue/master")
-    >>> pq_branch_name("foo")
+    >>> from optparse import OptionParser
+    >>> (opts, args) = OptionParser().parse_args([])
+    >>> pq_branch_name("patch-queue/master", opts)
+    >>> pq_branch_name("foo", opts)
     'patch-queue/foo'
+    >>> opts.pq_branch = "%(branch)s/development"
+    >>> pq_branch_name("foo", opts)
+    'foo/development'
+    >>> opts.pq_branch = "development"
+    >>> pq_branch_name("foo", opts)
+    'development'
     """
-    if not is_pq_branch(branch):
-        return PQ_BRANCH_PREFIX + branch
+    pq_format_str = DEFAULT_PQ_BRANCH_NAME
+    if hasattr(options, 'pq_branch'):
+        pq_format_str = options.pq_branch
 
+    if not is_pq_branch(branch, options):
+        return pq_format_str % dict(branch=branch)
 
-def pq_branch_base(pq_branch):
-    """
-    get the branch corresponding to the given patch queue branch
 
-    >>> pq_branch_base("patch-queue/master")
+def pq_branch_base(pq_branch, options):
+    """
+    Get the branch corresponding to the given patch queue branch.
+    Returns the packaging/debian branch if pq format string doesn't contain
+    '%(branch)s' key.
+
+    >>> from optparse import OptionParser
+    >>> (opts, args) = OptionParser().parse_args([])
+    >>> opts.packaging_branch = "packaging"
+    >>> pq_branch_base("patch-queue/master", opts)
     'master'
-    >>> pq_branch_base("foo")
+    >>> pq_branch_base("foo", opts)
+    >>> opts.pq_branch = "my/%(branch)s/development"
+    >>> pq_branch_base("foo/development", opts)
+    >>> pq_branch_base("my/foo/development/bar", opts)
+    >>> pq_branch_base("my/foo/development", opts)
+    'foo'
+    >>> opts.pq_branch = "development"
+    >>> pq_branch_base("foo/development", opts)
+    >>> pq_branch_base("development", opts)
+    'packaging'
     """
-    if is_pq_branch(pq_branch):
-        return pq_branch[len(PQ_BRANCH_PREFIX):]
+    pq_format_str = DEFAULT_PQ_BRANCH_NAME
+    if hasattr(options, 'pq_branch'):
+        pq_format_str = options.pq_branch
+
+    pq_re = re.compile(r'^%s$' % (pq_format_str % dict(branch="(?P<base>\S+)")))
+    m = pq_re.match(pq_branch)
+    if m:
+        if 'base' in m.groupdict():
+            return m.group('base')
+        return options.packaging_branch
 
 
 def parse_gbp_commands(info, cmd_tag, noarg_cmds, arg_cmds):
@@ -242,15 +298,15 @@ def get_maintainer_from_control(repo):
     return GitModifier()
 
 
-def switch_to_pq_branch(repo, branch):
+def switch_to_pq_branch(repo, branch, options):
     """
     Switch to patch-queue branch if not already there, create it if it
     doesn't exist yet
     """
-    if is_pq_branch(branch):
+    if is_pq_branch(branch, options):
         return
 
-    pq_branch = pq_branch_name(branch)
+    pq_branch = pq_branch_name(branch, options)
     if not repo.has_branch(pq_branch):
         try:
             repo.create_branch(pq_branch)
@@ -262,8 +318,9 @@ def switch_to_pq_branch(repo, branch):
     repo.set_branch(pq_branch)
 
 
-def apply_single_patch(repo, branch, patch, fallback_author, topic=None):
-    switch_to_pq_branch(repo, branch)
+def apply_single_patch(repo, branch, patch, fallback_author, options):
+    switch_to_pq_branch(repo, branch, options)
+    topic = None if not hasattr(options, 'topic') else options.topic
     apply_and_commit_patch(repo, patch, fallback_author, topic)
 
 
@@ -292,12 +349,12 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None):
     repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path)
 
 
-def drop_pq(repo, branch):
-    if is_pq_branch(branch):
+def drop_pq(repo, branch, options):
+    if is_pq_branch(branch, options):
         gbp.log.err("On a patch-queue branch, can't drop it.")
         raise GbpError
     else:
-        pq_branch = pq_branch_name(branch)
+        pq_branch = pq_branch_name(branch, options)
 
     if repo.has_branch(pq_branch):
         repo.delete_branch(pq_branch)
diff --git a/gbp/scripts/pq.py b/gbp/scripts/pq.py
index 194145e..34d8e0a 100755
--- a/gbp/scripts/pq.py
+++ b/gbp/scripts/pq.py
@@ -135,13 +135,13 @@ def commit_patches(repo, branch, patches, options):
 
 def export_patches(repo, branch, options):
     """Export patches from the pq branch into a patch series"""
-    if is_pq_branch(branch):
-        base = pq_branch_base(branch)
+    if is_pq_branch(branch, options):
+        base = pq_branch_base(branch, options)
         gbp.log.info("On '%s', switching to '%s'" % (branch, base))
         branch = base
         repo.set_branch(branch)
 
-    pq_branch = pq_branch_name(branch)
+    pq_branch = pq_branch_name(branch, options)
     try:
         shutil.rmtree(PATCH_DIR)
     except OSError as (e, msg):
@@ -170,7 +170,7 @@ def export_patches(repo, branch, options):
         gbp.log.info("No patches on '%s' - nothing to do." % pq_branch)
 
     if options.drop:
-        drop_pq(repo, branch)
+        drop_pq(repo, branch, options)
 
 
 def safe_patches(series):
@@ -196,7 +196,7 @@ def safe_patches(series):
     return (tmpdir, series)
 
 
-def import_quilt_patches(repo, branch, series, tries, force):
+def import_quilt_patches(repo, branch, series, tries, options):
     """
     apply a series of quilt patches in the series file 'series' to branch
     the patch-queue branch for 'branch'
@@ -206,24 +206,24 @@ def import_quilt_patches(repo, branch, series, tries, force):
     @param series; series file to read patches from
     @param tries: try that many times to apply the patches going back one
                   commit in the branches history after each failure.
-    @param force: import the patch series even if the branch already exists
+    @param options: gbp-pq command options
     """
     tmpdir = None
 
-    if is_pq_branch(branch):
-        if force:
-            branch = pq_branch_base(branch)
-            pq_branch = pq_branch_name(branch)
+    if is_pq_branch(branch, options):
+        if options.force:
+            branch = pq_branch_base(branch, options)
+            pq_branch = pq_branch_name(branch, options)
             repo.checkout(branch)
         else:
             gbp.log.err("Already on a patch-queue branch '%s' - doing nothing." % branch)
             raise GbpError
     else:
-        pq_branch = pq_branch_name(branch)
+        pq_branch = pq_branch_name(branch, options)
 
     if repo.has_branch(pq_branch):
-        if force:
-            drop_pq(repo, branch)
+        if options.force:
+            drop_pq(repo, branch, options)
         else:
             raise GbpError("Patch queue branch '%s'. already exists. Try 'rebase' instead."
                            % pq_branch)
@@ -270,23 +270,23 @@ def import_quilt_patches(repo, branch, series, tries, force):
         shutil.rmtree(tmpdir)
 
 
-def rebase_pq(repo, branch):
-    if is_pq_branch(branch):
-        base = pq_branch_base(branch)
+def rebase_pq(repo, branch, options):
+    if is_pq_branch(branch, options):
+        base = pq_branch_base(branch, options)
     else:
-        switch_to_pq_branch(repo, branch)
+        switch_to_pq_branch(repo, branch, options)
         base = branch
     GitCommand("rebase")([base])
 
 
-def switch_pq(repo, current):
+def switch_pq(repo, current, options):
     """Switch to patch-queue branch if on base branch and vice versa"""
-    if is_pq_branch(current):
-        base = pq_branch_base(current)
+    if is_pq_branch(current, options):
+        base = pq_branch_base(current, options)
         gbp.log.info("Switching to %s" % base)
         repo.checkout(base)
     else:
-        switch_to_pq_branch(repo, current)
+        switch_to_pq_branch(repo, current, options)
 
 
 def build_parser(name):
@@ -370,20 +370,20 @@ def main(argv):
         elif action == "import":
             series = SERIES_FILE
             tries = options.time_machine if (options.time_machine > 0) else 1
-            import_quilt_patches(repo, current, series, tries, options.force)
+            import_quilt_patches(repo, current, series, tries, options)
             current = repo.get_branch()
             gbp.log.info("Patches listed in '%s' imported on '%s'" %
                           (series, current))
         elif action == "drop":
-            drop_pq(repo, current)
+            drop_pq(repo, current, options)
         elif action == "rebase":
-            rebase_pq(repo, current)
+            rebase_pq(repo, current, options)
         elif action == "apply":
             patch = Patch(patchfile)
             maintainer = get_maintainer_from_control(repo)
-            apply_single_patch(repo, current, patch, maintainer, options.topic)
+            apply_single_patch(repo, current, patch, maintainer, options)
         elif action == "switch":
-            switch_pq(repo, current)
+            switch_pq(repo, current, options)
     except CommandExecFailed:
         retval = 1
     except (GbpError, GitRepositoryError) as err:
diff --git a/tests/13_test_gbp_pq.py b/tests/13_test_gbp_pq.py
index 910ce20..1ae4b62 100644
--- a/tests/13_test_gbp_pq.py
+++ b/tests/13_test_gbp_pq.py
@@ -91,7 +91,8 @@ class TestApplySinglePatch(testutils.DebianGitTestRepo):
 
         patch = gbp.patch_series.Patch(_patch_path('foo.patch'))
 
-        pq.apply_single_patch(self.repo, 'master', patch, None)
+        dummy_opts = object()
+        pq.apply_single_patch(self.repo, 'master', patch, None, dummy_opts)
         self.assertIn('foo', self.repo.list_files())
 
 class TestWritePatch(testutils.DebianGitTestRepo):
@@ -146,7 +147,7 @@ class TestExport(testutils.DebianGitTestRepo):
         repo = self.repo
         start = repo.get_branch()
         pq = os.path.join('patch-queue', start)
-        switch_pq(repo, start)
+        switch_pq(repo, start, TestExport.Options)
         self.assertEqual(repo.get_branch(), pq)
         export_patches(repo, pq, TestExport.Options)
         self.assertEqual(repo.get_branch(), start)
-- 
2.1.3

>From 54d947cbbfeff51afc8d6e8377134d45393723e4 Mon Sep 17 00:00:00 2001
From: Tzafrir Cohen <tzaf...@debian.org>
Date: Thu, 27 Nov 2014 14:41:28 +0200
Subject: [PATCH 3/3] add script pq_rpm

---
 debian/git-buildpackage-rpm.install |   1 +
 gbp/config.py                       |  33 ++
 gbp/scripts/pq_rpm.py               | 731 ++++++++++++++++++++++++++++++++++++
 3 files changed, 765 insertions(+)
 create mode 100644 gbp/scripts/pq_rpm.py

diff --git a/debian/git-buildpackage-rpm.install b/debian/git-buildpackage-rpm.install
index 67c0309..2568b4c 100644
--- a/debian/git-buildpackage-rpm.install
+++ b/debian/git-buildpackage-rpm.install
@@ -1,2 +1,3 @@
 usr/lib/python2.?/dist-packages/gbp/rpm/
 usr/lib/python2.7/dist-packages/gbp/scripts/import_srpm.py
+usr/lib/python2.7/dist-packages/gbp/scripts/pq_rpm.py
diff --git a/gbp/config.py b/gbp/config.py
index 174eba4..167ee7e 100644
--- a/gbp/config.py
+++ b/gbp/config.py
@@ -541,6 +541,14 @@ class GbpOptionParserRpm(GbpOptionParser):
             'packaging-branch'          : 'master',
             'packaging-dir'             : '',
             'packaging-tag'             : 'packaging/%(version)s',
+            'pq-branch'                 : 'development/%(branch)s',
+            'import-files'              : ['.gbp.conf',
+                                           'debian/gbp.conf'],
+            'spec-file'                 : 'auto',
+            'patch-export'              : 'False',
+            'patch-export-compress'     : '0',
+            'patch-export-ignore-path'  : '',
+            'patch-export-squash-until' : '',
                     })
 
     help = dict(GbpOptionParser.help)
@@ -560,6 +568,31 @@ class GbpOptionParserRpm(GbpOptionParser):
             'packaging-tag':
                 "Format string for packaging tags, RPM counterpart of the "
                 "'debian-tag' option, default is '%(packaging-tag)s'",
+            'pq-branch':
+                "format string for the patch-queue branch name, default is "
+                "'%(pq-branch)s'",
+            'import-files':
+                "Comma-separated list of additional file(s) to import from "
+                "packaging branch. These will appear as one monolithic patch "
+                "in the pq/development branch. Default is %(import-files)s",
+            'spec-file':
+                "Spec file to use, 'auto' makes gbp to guess, other values "
+                "make the packaging-dir option to be ignored, default is "
+                "'%(spec-file)s'",
+            'patch-export':
+                "Create patches between upstream and export-treeish, default "
+                "is '%(patch-export)s'",
+            'patch-export-compress':
+                "Compress (auto-generated) patches larger than given number of "
+                "bytes, 0 never compresses, default is "
+                "'%(patch-export-compress)s'",
+            'patch-export-ignore-path':
+                "Exclude changes to path(s) matching regex, default is "
+                "'%(patch-export-ignore-path)s'",
+            'patch-export-squash-until':
+                "Squash commits (from upstream) until given tree-ish into one "
+                "big diff, format is '<commit_ish>[:<filename_base>]'. "
+                "Default is '%(patch-export-squash-until)s'",
                  })
 
 # vim:et:ts=4:sw=4:et:sts=4:ai:set list listchars=tab\:»·,trail\:·:
diff --git a/gbp/scripts/pq_rpm.py b/gbp/scripts/pq_rpm.py
new file mode 100644
index 0000000..ee076aa
--- /dev/null
+++ b/gbp/scripts/pq_rpm.py
@@ -0,0 +1,731 @@
+# vim: set fileencoding=utf-8 :
+#
+# (C) 2011 Guido Günther <a...@sigxcpu.org>
+# (C) 2012 Intel Corporation <markus.lehto...@linux.intel.com>
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+"""manage patches in a patch queue"""
+
+import ConfigParser
+import errno
+import os
+import shutil
+import sys
+import re
+import gzip
+import bz2
+import subprocess
+
+import gbp.tmpfile as tempfile
+from gbp.config import GbpOptionParserRpm
+from gbp.rpm.git import GitRepositoryError, RpmGitRepository
+from gbp.git.modifier import GitModifier
+from gbp.command_wrappers import GitCommand, CommandExecFailed
+from gbp.errors import GbpError
+import gbp.log
+from gbp.patch_series import PatchSeries, Patch
+from gbp.pkg import parse_archive_filename
+from gbp.rpm import (SpecFile, NoSpecError, guess_spec, guess_spec_repo,
+                     spec_from_repo, string_to_int)
+from gbp.scripts.common.pq import (is_pq_branch, pq_branch_name, pq_branch_base,
+                                   parse_gbp_commands, format_patch,
+                                   format_diff, apply_and_commit_patch, drop_pq)
+from gbp.scripts.common.buildpackage import dump_tree
+
+USAGE_STRING = \
+"""%prog [options] action - maintain patches on a patch queue branch
+tions:
+export         Export the patch queue / devel branch associated to the
+               current branch into a patch series in and update the spec file
+import         Create a patch queue / devel branch from spec file
+               and patches in current dir.
+rebase         Switch to patch queue / devel branch associated to the current
+               branch and rebase against upstream.
+drop           Drop (delete) the patch queue /devel branch associated to
+               the current branch.
+apply          Apply a patch
+switch         Switch to patch-queue branch and vice versa.
+convert        [experimental] Convert package from single-branch development
+               model (packaging and source code changes in the same branch)
+               into the orphan-packaging plus patch-queue / development branch
+               development model."""
+
+def compress_patches(patches, compress_size=0):
+    """
+    Rename and/or compress patches
+    """
+    ret_patches = []
+    for patch in patches:
+        # Compress if patch file is larger than "threshold" value
+        suffix = ''
+        if compress_size and os.path.getsize(patch) > compress_size:
+            gbp.log.debug("Compressing %s" % os.path.basename(patch))
+            subprocess.Popen(['gzip', '-n', patch]).communicate()
+            suffix = '.gz'
+
+        ret_patches.append(os.path.basename(patch) + suffix)
+    return ret_patches
+
+def is_ancestor(repo, parent, child):
+    """Check if commit is ancestor of another"""
+    parent_sha1 = repo.rev_parse("%s^0" % parent)
+    child_sha1 = repo.rev_parse("%s^0" % child)
+    try:
+        merge_base = repo.get_merge_base(parent_sha1, child_sha1)
+    except GitRepositoryError:
+        merge_base = None
+    return merge_base == parent_sha1
+
+def generate_patches(repo, start, squash, end, outdir, options):
+    """
+    Generate patch files from git
+    """
+    gbp.log.info("Generating patches from git (%s..%s)" % (start, end))
+    patches = []
+    commands = {}
+    for treeish in [start, end]:
+        if not repo.has_treeish(treeish):
+            raise GbpError('Invalid treeish object %s' % treeish)
+
+    start_sha1 = repo.rev_parse("%s^0" % start)
+    try:
+        end_commit = end
+        end_commit_sha1 = repo.rev_parse("%s^0" % end_commit)
+    except GitRepositoryError:
+        # In case of plain tree-ish objects, assume current branch head is the
+        # last commit
+        end_commit = "HEAD"
+        end_commit_sha1 = repo.rev_parse("%s^0" % end_commit)
+
+    start_sha1 = repo.rev_parse("%s^0" % start)
+
+    if not is_ancestor(repo, start_sha1, end_commit_sha1):
+        raise GbpError("Start commit '%s' not an ancestor of end commit "
+                       "'%s'" % (start, end_commit))
+    # Squash commits, if requested
+    if squash[0]:
+        if squash[0] == 'HEAD':
+            squash[0] = end_commit
+        squash_sha1 = repo.rev_parse("%s^0" % squash[0])
+        if start_sha1 != squash_sha1:
+            if not squash_sha1 in repo.get_commits(start, end_commit):
+                raise GbpError("Given squash point '%s' not in the history "
+                               "of end commit '%s'" % (squash[0], end_commit))
+            # Shorten SHA1s
+            squash_sha1 = repo.rev_parse(squash_sha1, short=7)
+            start_sha1 = repo.rev_parse(start_sha1, short=7)
+            gbp.log.info("Squashing commits %s..%s into one monolithic diff" %
+                         (start_sha1, squash_sha1))
+            patch_fn = format_diff(outdir, squash[1], repo,
+                                   start_sha1, squash_sha1,
+                                   options.patch_export_ignore_path)
+            if patch_fn:
+                patches.append(patch_fn)
+                start = squash_sha1
+    # Check for merge commits, yet another squash if merges found
+    merges = repo.get_commits(start, end_commit, options=['--merges'])
+    if merges:
+        # Shorten SHA1s
+        start_sha1 = repo.rev_parse(start, short=7)
+        merge_sha1 = repo.rev_parse(merges[0], short=7)
+        patch_fn = format_diff(outdir, None, repo, start_sha1, merge_sha1,
+                               options.patch_export_ignore_path)
+        if patch_fn:
+            gbp.log.info("Merge commits found! Diff between %s..%s written "
+                         "into one monolithic diff" % (start_sha1, merge_sha1))
+            patches.append(patch_fn)
+            start = merge_sha1
+            print start
+
+    # Generate patches
+    for commit in reversed(repo.get_commits(start, end_commit)):
+        info = repo.get_commit_info(commit)
+        cmds = parse_gbp_commands(info, 'gbp-rpm', ('ignore'),
+                                  ('if', 'ifarch'))[0]
+        if not 'ignore' in cmds:
+            patch_fn = format_patch(outdir, repo, info, patches,
+                                    options.patch_numbers,
+                                    options.patch_export_ignore_path)
+            if patch_fn:
+                commands[os.path.basename(patch_fn)] = cmds
+        else:
+            gbp.log.info('Ignoring commit %s' % info['id'])
+
+    # Generate diff to the tree-ish object
+    if end_commit != end:
+        gbp.log.info("Generating diff file %s..%s" % (end_commit, end))
+        patch_fn = format_diff(outdir, None, repo, end_commit, end,
+                               options.patch_export_ignore_path)
+        if patch_fn:
+            patches.append(patch_fn)
+
+    # Compress
+    patches = compress_patches(patches, options.patch_export_compress)
+
+    return patches, commands
+
+
+def rm_patch_files(spec):
+    """
+    Delete the patch files listed in the spec files. Doesn't delete patches
+    marked as not maintained by gbp.
+    """
+    # Remove all old patches from the spec dir
+    for patch in spec.patchseries(unapplied=True):
+        gbp.log.debug("Removing '%s'" % patch.path)
+        try:
+            os.unlink(patch.path)
+        except OSError as err:
+            if err.errno != errno.ENOENT:
+                raise GbpError("Failed to remove patch: %s" % err)
+            else:
+                gbp.log.debug("Patch %s does not exist." % patch.path)
+
+
+def update_patch_series(repo, spec, start, end, options):
+    """
+    Export patches to packaging directory and update spec file accordingly.
+    """
+    squash = options.patch_export_squash_until.split(':', 1)
+    if len(squash) == 1:
+        squash.append(None)
+    else:
+        squash[1] += '.diff'
+
+    # Unlink old patch files and generate new patches
+    rm_patch_files(spec)
+
+    patches, commands = generate_patches(repo, start, squash, end,
+                                         spec.specdir, options)
+    spec.update_patches(patches, commands)
+    spec.write_spec_file()
+    return patches
+
+
+def parse_spec(options, repo, treeish=None):
+    """
+    Find and parse spec file.
+
+    If treeish is given, try to find the spec file from that. Otherwise, search
+    for the spec file in the working copy.
+    """
+    try:
+        if options.spec_file != 'auto':
+            options.packaging_dir = os.path.dirname(options.spec_file)
+            if not treeish:
+                spec = SpecFile(options.spec_file)
+            else:
+                spec = spec_from_repo(repo, treeish, options.spec_file)
+        else:
+            preferred_name = os.path.basename(repo.path) + '.spec'
+            if not treeish:
+                spec = guess_spec(options.packaging_dir, True, preferred_name)
+            else:
+                spec = guess_spec_repo(repo, treeish, options.packaging_dir,
+                                       True, preferred_name)
+    except NoSpecError as err:
+        raise GbpError("Can't parse spec: %s" % err)
+    relpath = spec.specpath if treeish else os.path.relpath(spec.specpath,
+                                                            repo.path)
+    gbp.log.debug("Using '%s' from '%s'" % (relpath, treeish or 'working copy'))
+    return spec
+
+
+def find_upstream_commit(repo, spec, upstream_tag):
+    """Find commit corresponding upstream version"""
+    tag_str_fields = {'upstreamversion': spec.upstreamversion,
+                      'vendor': 'Upstream'}
+    upstream_commit = repo.find_version(upstream_tag, tag_str_fields)
+    if not upstream_commit:
+        raise GbpError("Couldn't find upstream version %s" %
+                       spec.upstreamversion)
+    return upstream_commit
+
+
+def export_patches(repo, options):
+    """Export patches from the pq branch into a packaging branch"""
+    current = repo.get_branch()
+    if is_pq_branch(current, options):
+        base = pq_branch_base(current, options)
+        gbp.log.info("On branch '%s', switching to '%s'" % (current, base))
+        repo.set_branch(base)
+        spec = parse_spec(options, repo)
+        pq_branch = current
+    else:
+        spec = parse_spec(options, repo)
+        pq_branch = pq_branch_name(current, options, spec.version)
+    upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
+
+    export_treeish = options.export_rev if options.export_rev else pq_branch
+
+    update_patch_series(repo, spec, upstream_commit, export_treeish, options)
+
+    GitCommand('status')(['--', spec.specdir])
+
+
+def safe_patches(queue, tmpdir_base):
+    """
+    Safe the current patches in a temporary directory
+    below 'tmpdir_base'. Also, uncompress compressed patches here.
+
+    @param queue: an existing patch queue
+    @param tmpdir_base: base under which to create tmpdir
+    @return: tmpdir and a safed queue (with patches in tmpdir)
+    @rtype: tuple
+    """
+
+    tmpdir = tempfile.mkdtemp(dir=tmpdir_base, prefix='patchimport_')
+    safequeue = PatchSeries()
+
+    if len(queue) > 0:
+        gbp.log.debug("Safeing patches '%s' in '%s'" %
+                        (os.path.dirname(queue[0].path), tmpdir))
+    for patch in queue:
+        base, _archive_fmt, comp = parse_archive_filename(patch.path)
+        uncompressors = {'gzip': gzip.open, 'bzip2': bz2.BZ2File}
+        if comp in uncompressors:
+            gbp.log.debug("Uncompressing '%s'" % os.path.basename(patch.path))
+            src = uncompressors[comp](patch.path, 'r')
+            dst_name = os.path.join(tmpdir, os.path.basename(base))
+        elif comp:
+            raise GbpError("Unsupported patch compression '%s', giving up"
+                           % comp)
+        else:
+            src = open(patch.path, 'r')
+            dst_name = os.path.join(tmpdir, os.path.basename(patch.path))
+
+        dst = open(dst_name, 'w')
+        dst.writelines(src)
+        src.close()
+        dst.close()
+
+        safequeue.append(patch)
+        safequeue[-1].path = dst_name
+
+    return safequeue
+
+
+def get_packager(spec):
+    """Get packager information from spec"""
+    if spec.packager:
+        match = re.match(r'(?P<name>.*[^ ])\s*<(?P<email>\S*)>',
+                         spec.packager.strip())
+        if match:
+            return GitModifier(match.group('name'), match.group('email'))
+    return GitModifier()
+
+def import_extra_files(repo, commitish, files, patch_ignore=True):
+    """Import branch-specific gbp.conf files to current branch"""
+    found = {}
+    for fname in files:
+        if fname:
+            try:
+                found[fname] = repo.show('%s:%s' % (commitish, fname))
+            except GitRepositoryError:
+                pass
+    if found:
+        gbp.log.info("Importing additional file(s) from branch '%s' into '%s'" %
+                     (commitish, repo.get_branch()))
+        for fname, content in found.iteritems():
+            dirname = os.path.dirname(fname)
+            if dirname and not os.path.exists(dirname):
+                os.makedirs(dirname)
+            with open(fname, 'w') as fobj:
+                fobj.write(content)
+
+        files = found.keys()
+        gbp.log.debug('Adding/commiting %s' % files)
+        repo.add_files(files, force=True)
+        commit_msg = ("Auto-import file(s) from branch '%s':\n    %s\n" %
+                      (commitish, '    '.join(files)))
+        if patch_ignore:
+            commit_msg += "\nGbp: Ignore\nGbp-Rpm: Ignore"
+        repo.commit_files(files, msg=commit_msg)
+    return found.keys()
+
+def import_spec_patches(repo, options):
+    """
+    apply a series of patches in a spec/packaging dir to branch
+    the patch-queue branch for 'branch'
+
+    @param repo: git repository to work on
+    @param options: command options
+    """
+    current = repo.get_branch()
+    # Get spec and related information
+    if is_pq_branch(current, options):
+        base = pq_branch_base(current, options)
+        if options.force:
+            spec = parse_spec(options, repo, base)
+            spec_treeish = base
+        else:
+            raise GbpError("Already on a patch-queue branch '%s' - doing "
+                           "nothing." % current)
+    else:
+        spec = parse_spec(options, repo)
+        spec_treeish = None
+        base = current
+    upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
+    packager = get_packager(spec)
+    pq_branch = pq_branch_name(base, options, spec.version)
+
+    # Create pq-branch
+    if repo.has_branch(pq_branch) and not options.force:
+        raise GbpError("Patch-queue branch '%s' already exists. "
+                       "Try 'switch' instead." % pq_branch)
+    try:
+        if repo.get_branch() == pq_branch:
+            repo.force_head(upstream_commit, hard=True)
+        else:
+            repo.create_branch(pq_branch, upstream_commit, force=True)
+    except GitRepositoryError as err:
+        raise GbpError("Cannot create patch-queue branch '%s': %s" %
+                        (pq_branch, err))
+
+    # Put patches in a safe place
+    if spec_treeish:
+        packaging_tmp = tempfile.mkdtemp(prefix='dump_', dir=options.tmp_dir)
+        packaging_tree = '%s:%s' % (spec_treeish, options.packaging_dir)
+        dump_tree(repo, packaging_tmp, packaging_tree, with_submodules=False,
+                  recursive=False)
+        spec.specdir = packaging_tmp
+    in_queue = spec.patchseries()
+    queue = safe_patches(in_queue, options.tmp_dir)
+    # Do import
+    try:
+        gbp.log.info("Switching to branch '%s'" % pq_branch)
+        repo.set_branch(pq_branch)
+        import_extra_files(repo, base, options.import_files)
+
+        if not queue:
+            return
+        gbp.log.info("Trying to apply patches from branch '%s' onto '%s'" %
+                        (base, upstream_commit))
+        for patch in queue:
+            gbp.log.debug("Applying %s" % patch.path)
+            apply_and_commit_patch(repo, patch, packager)
+    except (GbpError, GitRepositoryError) as err:
+        repo.set_branch(base)
+        repo.delete_branch(pq_branch)
+        raise GbpError('Import failed: %s' % err)
+
+    gbp.log.info("Patches listed in '%s' imported on '%s'" % (spec.specfile,
+                                                              pq_branch))
+
+
+def rebase_pq(repo, options):
+    """Rebase pq branch on the correct upstream version (from spec file)."""
+    current = repo.get_branch()
+    if is_pq_branch(current, options):
+        base = pq_branch_base(current, options)
+        spec = parse_spec(options, repo, base)
+    else:
+        base = current
+        spec = parse_spec(options, repo)
+    upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
+
+    switch_to_pq_branch(repo, base, options)
+    GitCommand("rebase")([upstream_commit])
+
+
+def switch_pq(repo, options):
+    """Switch to patch-queue branch if on base branch and vice versa"""
+    current = repo.get_branch()
+    if is_pq_branch(current, options):
+        base = pq_branch_base(current, options)
+        gbp.log.info("Switching to branch '%s'" % base)
+        repo.checkout(base)
+    else:
+        switch_to_pq_branch(repo, current, options)
+
+
+def drop_pq_rpm(repo, options):
+    """Remove pq branch"""
+    current = repo.get_branch()
+    if is_pq_branch(current, options):
+        base = pq_branch_base(current, options)
+        spec = parse_spec(options, repo, base)
+    else:
+        spec = parse_spec(options, repo)
+    drop_pq(repo, current, options, spec.version)
+
+
+def switch_to_pq_branch(repo, branch, options):
+    """
+    Switch to patch-queue branch if not already there, create it if it
+    doesn't exist yet
+    """
+    if is_pq_branch(branch, options):
+        return
+
+    spec = parse_spec(options, repo, branch)
+    pq_branch = pq_branch_name(branch, options, spec.version)
+    if not repo.has_branch(pq_branch):
+        raise GbpError("Branch '%s' does not exist" % pq_branch)
+
+    gbp.log.info("Switching to branch '%s'" % pq_branch)
+    repo.set_branch(pq_branch)
+
+def apply_single_patch(repo, patchfile, options):
+    """Apply a single patch onto the pq branch"""
+    current = repo.get_branch()
+    if not is_pq_branch(current, options):
+        switch_to_pq_branch(repo, current, options)
+    patch = Patch(patchfile)
+    apply_and_commit_patch(repo, patch, fallback_author=None)
+
+def convert_package(repo, options):
+    """Convert package to orphan-packaging model"""
+    old_packaging = repo.get_branch()
+    # Check if we're on pq branch, already
+    err_msg_base = "Seems you're already using orphan-packaging model - "
+    if is_pq_branch(old_packaging, options):
+        raise GbpError(err_msg_base + "you're on patch-queue branch")
+    # Check if a pq branch already exists
+    spec = parse_spec(options, repo, treeish=old_packaging)
+    pq_branch = pq_branch_name(old_packaging, options, spec.version)
+    if repo.has_branch(pq_branch):
+        pq_branch = pq_branch_name(old_packaging, options, spec.version)
+        raise GbpError(err_msg_base + "pq branch %s already exists" % pq_branch)
+    # Check that the current branch is based on upstream
+    upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
+    if not is_ancestor(repo, upstream_commit, old_packaging):
+        raise GbpError(err_msg_base + "%s is not based on upstream version %s" %
+                       (old_packaging, spec.upstreamversion))
+    # Check new branch
+    new_branch = old_packaging + "-orphan"
+    if repo.has_branch(new_branch):
+        if not options.force:
+            raise GbpError("Branch '%s' already exists!" % new_branch)
+        else:
+            gbp.log.info("Dropping branch '%s'" % new_branch)
+            repo.delete_branch(new_branch)
+
+    # Determine "history"
+    if options.retain_history:
+        # Find first commit that has the spec file and list commits from there
+        try:
+            repo.show('%s:%s' % (upstream_commit, spec.specpath))
+            history = repo.get_commits(upstream_commit, old_packaging)
+        except GitRepositoryError:
+            history_start = repo.get_commits(upstream_commit, old_packaging,
+                                             spec.specpath)[-1]
+            history = repo.get_commits('%s^' % history_start, old_packaging)
+    else:
+        history = [repo.rev_parse(old_packaging)]
+    history.reverse()
+
+    # Do import
+    gbp.log.info("Importing packaging files from branch '%s' to '%s'" %
+                 (old_packaging, new_branch))
+    convert_with_history(repo, upstream_commit, history, new_branch,
+                         spec.specfile, options)
+    # Copy extra files
+    import_extra_files(repo, old_packaging, options.import_files,
+                       patch_ignore=False)
+
+    gbp.log.info("Package successfully converted to orphan-packaging.")
+    gbp.log.info("You're now on the new '%s' packaging branch (the old "
+            "packaging branch '%s' was left intact)." %
+            (new_branch, old_packaging))
+    gbp.log.info("Please check all files and test building the package!")
+
+
+def convert_with_history(repo, upstream, commits, new_branch, spec_fn, options):
+    """Auto-import packaging files and (auto-generated) patches"""
+
+    # Dump and commit packaging files
+    packaging_tree = '%s:%s' % (commits[0], options.packaging_dir)
+    packaging_tmp = tempfile.mkdtemp(prefix='pack_', dir=options.tmp_dir)
+    dump_packaging_dir = os.path.join(packaging_tmp, options.new_packaging_dir)
+    dump_tree(repo, dump_packaging_dir, packaging_tree, with_submodules=False,
+              recursive=False)
+
+    msg = "Auto-import packaging files\n\n" \
+          "Imported initial packaging files from commit '%s'" % (commits[0])
+    new_tree = repo.create_tree(packaging_tmp)
+    tip_commit = repo.commit_tree(new_tree, msg, [])
+
+    # Generate initial patches
+    spec = SpecFile(os.path.join(dump_packaging_dir, spec_fn))
+    update_patch_series(repo, spec, upstream, commits[0], options)
+    # Commit updated packaging files only if something was changed
+    new_tree = repo.create_tree(packaging_tmp)
+    if new_tree != repo.rev_parse(tip_commit + ':'):
+        msg = "Auto-generate patches\n\n" \
+              "Generated patches from\n'%s..%s'\n\n" \
+              "updating spec file and possibly removing old patches." \
+              % (upstream, commits[0])
+        tip_commit = repo.commit_tree(new_tree, msg, [tip_commit])
+
+    # Import rest of the commits
+    for commit in commits[1:]:
+        shutil.rmtree(dump_packaging_dir)
+        packaging_tree = '%s:%s' % (commit, options.packaging_dir)
+        dump_tree(repo, dump_packaging_dir, packaging_tree,
+                  with_submodules=False, recursive=False)
+        try:
+            spec = SpecFile(os.path.join(dump_packaging_dir, spec_fn))
+            update_patch_series(repo, spec, upstream, commit, options)
+        except (NoSpecError, GbpError):
+            gbp.log.warn("Failed to generate patches from '%s'" % commit)
+
+        new_tree = repo.create_tree(packaging_tmp)
+        if new_tree == repo.rev_parse(tip_commit + ':'):
+            gbp.log.info("Skipping commit '%s' which generated no change" %
+                         commit)
+        else:
+            info = repo.get_commit_info(commit)
+            msg = "%s\n\n%sAuto-imported by gbp from '%s'" % (info['subject'],
+                        info['body'], commit)
+            tip_commit = repo.commit_tree(new_tree, msg, [tip_commit])
+
+    repo.create_branch(new_branch, tip_commit)
+    repo.set_branch(new_branch)
+
+
+def opt_split_cb(option, opt_str, value, parser):
+    """Split option string into a list"""
+    setattr(parser.values, option.dest, value.split(','))
+
+
+def main(argv):
+    """Main function for the gbp pq-rpm command"""
+    retval = 0
+
+    try:
+        parser = GbpOptionParserRpm(command=os.path.basename(argv[0]),
+                                    prefix='', usage=USAGE_STRING)
+    except ConfigParser.ParsingError as err:
+        gbp.log.err('Invalid config file: %s' % err)
+        return 1
+
+    parser.add_boolean_config_file_option(option_name="patch-numbers",
+            dest="patch_numbers")
+    parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+            default=False, help="Verbose command execution")
+    parser.add_option("--force", dest="force", action="store_true",
+            default=False,
+            help="In case of import even import if the branch already exists")
+    parser.add_config_file_option(option_name="vendor", action="store",
+            dest="vendor")
+    parser.add_config_file_option(option_name="color", dest="color",
+            type='tristate')
+    parser.add_config_file_option(option_name="color-scheme",
+            dest="color_scheme")
+    parser.add_config_file_option(option_name="tmp-dir", dest="tmp_dir")
+    parser.add_config_file_option(option_name="upstream-tag",
+            dest="upstream_tag")
+    parser.add_config_file_option(option_name="spec-file", dest="spec_file")
+    parser.add_config_file_option(option_name="packaging-dir",
+            dest="packaging_dir")
+    parser.add_option("--new-packaging-dir",
+            help="Packaging directory in the new packaging branch. Only "
+                 "relevant for the 'convert' action. If not defined, defaults "
+                 "to '--packaging-dir'")
+    parser.add_config_file_option(option_name="packaging-branch",
+            dest="packaging_branch",
+            help="Branch the packaging is being maintained on. Only relevant "
+                 "if a invariable/single pq-branch is defined, in which case "
+                 "this is used as the 'base' branch. Default is "
+                 "'%(packaging-branch)s'")
+    parser.add_config_file_option(option_name="pq-branch", dest="pq_branch")
+    parser.add_config_file_option(option_name="import-files",
+            dest="import_files", type="string", action="callback",
+            callback=opt_split_cb)
+    parser.add_option("--retain-history", action="store_true",
+            help="When doing convert, preserve as much of the git history as "
+                 "possible, i.e. create one commit per commit. Only "
+                 "relevant for the 'convert' action.")
+    parser.add_option("--export-rev", action="store", dest="export_rev",
+            default="",
+            help="Export patches from treeish object TREEISH instead of head "
+                 "of patch-queue branch", metavar="TREEISH")
+    parser.add_config_file_option("patch-export-compress",
+            dest="patch_export_compress")
+    parser.add_config_file_option("patch-export-squash-until",
+            dest="patch_export_squash_until")
+    parser.add_config_file_option("patch-export-ignore-path",
+            dest="patch_export_ignore_path")
+
+    (options, args) = parser.parse_args(argv)
+    gbp.log.setup(options.color, options.verbose, options.color_scheme)
+    options.patch_export_compress = string_to_int(options.patch_export_compress)
+    if options.new_packaging_dir is None:
+        options.new_packaging_dir = options.packaging_dir
+
+    if len(args) < 2:
+        gbp.log.err("No action given.")
+        return 1
+    else:
+        action = args[1]
+
+    if args[1] in ["export", "import", "rebase", "drop", "switch", "convert"]:
+        pass
+    elif args[1] in ["apply"]:
+        if len(args) != 3:
+            gbp.log.err("No patch name given.")
+            return 1
+        else:
+            patchfile = args[2]
+    else:
+        gbp.log.err("Unknown action '%s'." % args[1])
+        return 1
+
+    try:
+        repo = RpmGitRepository(os.path.curdir)
+    except GitRepositoryError:
+        gbp.log.err("%s is not a git repository" % (os.path.abspath('.')))
+        return 1
+
+    if os.path.abspath('.') != repo.path:
+        gbp.log.warn("Switching to topdir before running commands")
+        os.chdir(repo.path)
+
+    try:
+        # Create base temporary directory for this run
+        options.tmp_dir = tempfile.mkdtemp(dir=options.tmp_dir,
+                                           prefix='gbp-pq-rpm_')
+        if action == "export":
+            export_patches(repo, options)
+        elif action == "import":
+            import_spec_patches(repo, options)
+        elif action == "drop":
+            drop_pq_rpm(repo, options)
+        elif action == "rebase":
+            rebase_pq(repo, options)
+        elif action == "apply":
+            apply_single_patch(repo, patchfile, options)
+        elif action == "switch":
+            switch_pq(repo, options)
+        elif action == "convert":
+            convert_package(repo, options)
+    except CommandExecFailed:
+        retval = 1
+    except GitRepositoryError as err:
+        gbp.log.err("Git command failed: %s" % err)
+        retval = 1
+    except GbpError, err:
+        if len(err.__str__()):
+            gbp.log.err(err)
+        retval = 1
+    finally:
+        shutil.rmtree(options.tmp_dir, ignore_errors=True)
+
+    return retval
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
+
-- 
2.1.3


--- End Message ---
--- Begin Message ---
Source: git-buildpackage
Source-Version: 0.6.23

We believe that the bug you reported is fixed in the latest version of
git-buildpackage, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to 771...@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Guido Günther <a...@sigxcpu.org> (supplier of updated git-buildpackage package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmas...@ftp-master.debian.org)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Format: 1.8
Date: Sun, 18 Jan 2015 15:29:57 +0100
Source: git-buildpackage
Binary: git-buildpackage git-buildpackage-rpm
Architecture: source all
Version: 0.6.23
Distribution: experimental
Urgency: medium
Maintainer: Guido Günther <a...@sigxcpu.org>
Changed-By: Guido Günther <a...@sigxcpu.org>
Description:
 git-buildpackage - Suite to help with Debian packages in Git repositories
 git-buildpackage-rpm - Suite to help with RPM packages in Git repositories
Closes: 747101 771215
Changes:
 git-buildpackage (0.6.23) experimental; urgency=medium
 .
   [ Markus Lehtonen ]
   * [7a503e9] pq: move switch_pq() to common.
   * [cb9271f] GitRepository: add diff_status method.
     This is a method of getting the filename and status information of a
     diff. That is, a list of files that changed and their status, "added",
     "modified" etc.
   * [410e613] GitRepository.create_branch: add 'force' option
   * [a84f6c1] ComponentTestBase: add a per-class toplevel temp dir
   * [0e7cb0d] ComponentTestBase: add check_files() method
   * [194b6b8] ComponentTestBase: add dirs argument to _check_repo_state()
     Make difference between regular files and directories, eliminating the
     requirement of listing directories in the file list.
   * [01470e1] gbp-dch: fix handling of the '--meta' option.
     Make it effective again - previously it was totally ignored. Also,
     change it's default value to True to match the current behavior.
   * [f48f0ff] notify: catch RuntimeError when importing pynotify.
     Work around a problem in some distros (e.g. Fedora) where "import
     pynotify" crashes in RuntimeError in some cases, e.g. when DISPLAY env
     variable is not set.
   * [7df4d8c] log: fix auto colorizing for custom streams.
     Check for existence of isatty() method in the stream object. Some custom
     streams (e.g. in nose) do not necessarily have this.
   * [4cd6627] buildpackage/dump_tree: add 'recursive' option.
     For selecting whether to dump all the files recursively or just the top
     level directory of the tree.
   * [ff4cc8b] config: read the right config if run from subdir.
     A step towards being able to run GBP tools from subdirectories.
     Now expands '%(top_dir)s' and '%(git_dir)s' in config file path to root
     of the working directory and git metadata directory, respectively.
     Also, adds a new method _read_config_file() in preparation for
     supporting per-tree config files.
     Fixes tests.test_Config: currently the only correct way to define the
     config file(s) to be parsed is by using the GBP_CONF_FILES environment
     variable.
   * [60479af] Introduce gbp-pq-rpm.
     Initial version of gbp-pq-rpm - a tool for managing patch queues for rpm
     packages. The functionality more or less corresponds to that of the
     (Debian) gbp-pq. The only major difference probably being (in addition
     to the obvious of working with .spec files instead of debian/) is that
     patches are always imported on top of the upstream version, not on top
     of the packaging branch (which might not even contain any source code).
     (Closes: #771215)
 .
   [ Ed Bartosh ]
   * [76739f8] GitRepository: Implement status method.  Simple wrapper to the
     git-status command.
 .
   [ Guido Günther ]
   * [578e394] pq: print which patch got just applied
   * [e098857] test data: Add .git for bare repository
   * [813d01d] Fix argument type
   * [15663e7] import-orig: Add --download option to download tarballs via HTTP
     (Closes: #747101)
Checksums-Sha1:
 13cc2c622fed8531e6ca7dc5d275334b41de694f 2018 git-buildpackage_0.6.23.dsc
 355bb51dcb9da356f01f281d73ed02db74e7691b 1636096 git-buildpackage_0.6.23.tar.xz
 bf99b809b347dc7107c93ed959e44f765a2e50d0 307510 git-buildpackage_0.6.23_all.deb
 9aa67bd8adf9e2ee2425c18af85275eff9c2088e 66064 
git-buildpackage-rpm_0.6.23_all.deb
Checksums-Sha256:
 19083dbc6f5be2f95a0c5b21a0dd7e35f904af6817c7e24a24bd8895d7f04d87 2018 
git-buildpackage_0.6.23.dsc
 148eff9ef63d89f0f631e2cd44375baa9b7aa882908bbeaa05bb5ab15ea798ff 1636096 
git-buildpackage_0.6.23.tar.xz
 9c92d367c793e1a8b9c7d61da10a8b699de1a903bf7280af6f8f93854770c031 307510 
git-buildpackage_0.6.23_all.deb
 07023ddbaa23d0ed413e911b995a89a886d2648f85a2a6fa26f5e5f660bb6836 66064 
git-buildpackage-rpm_0.6.23_all.deb
Files:
 2edf452c758ba4c0e19ec18e4c3df90d 2018 vcs optional git-buildpackage_0.6.23.dsc
 b709dff0f479c7b256a19efba8a18a74 1636096 vcs optional 
git-buildpackage_0.6.23.tar.xz
 6f6cce38da53ea3a69d843e8e9c49d7a 307510 vcs optional 
git-buildpackage_0.6.23_all.deb
 a039bdcfa8a2a432f193454891901b1d 66064 vcs optional 
git-buildpackage-rpm_0.6.23_all.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIVAwUBVLvRige4t7DqmBILAQgQhBAAvTZyK3+7gzhlFifFzRUeuao7sLbWyepi
BdAid02JdlQo1Ee0ivARvKVLsfGa+5eIRDMe/VKtfx6yixajHeblUHSHIWRyy7yH
IdzYa88+LGy9IZrkQF/JB91AGhqLSEHJz6YYoB5goLJDAPns5qfHdlxVPzMrea4T
2XZSqb3ZbXUhIgohrbNpOaTFQKWxCGbaFbr+Wbbz33I5NBd53tvVpO1GnjZ+ZYEA
VcKJiuk8dKnJ9dHMUdOR8nrgCr8l1rFP1f9FNvbJfgKVW4dIcJ81+fgTqCIiqK8g
t3NVN4BclxItfzvYQvIjfLpIl3isEfMzyuxxQyh3sYYc55iG//+FA0pLK7Z9lHj2
ffzKIz54gZf2Do+WuvNdcX/5pwK8tMBYULZrQtt237Gta5zqjoWJQ7dYYYKEJTYA
8ExK3uLJlVi5LXlVfXRf/FLS7LhbVi6kdHhycek1G51vJwppsPe5nxOE7evW3LXb
RpPRCXo969zBgSXtSbwU4woe3MD+jCIbjsll7+3araIwL+Yy9CrsioWz6eyvQ3SL
3DpYDSiU7vf1EY3X6p920viol/jclSrlE5ZpRQ4QGDU1Voflduq2DeC2xASMXqnz
7FR2DItRCbjMD5vT6Qd4kmeZLEZ7DAgtuyu1QtNKoBai+JlTapz1OKzPAADmo0Ml
RNzDeciJzdQ=
=sPEE
-----END PGP SIGNATURE-----

--- End Message ---

Reply via email to