Commit 8241459f authored by Guido Günther's avatar Guido Günther

pq: Allow to preserve the patch name on import/export

Closes: #761161
parent 58ea0677
......@@ -190,6 +190,17 @@
<term><option>Gbp[-Pq]: Name</option> <replaceable>name</replaceable>
The name to use for the patch when running <screen>&gbp-pq;
export</screen>. If unset it will be formatted
like <command>git am</command> would format it.
<term><option>Gbp[-Pq]: Topic</option> <replaceable>topic</replaceable>
# vim: set fileencoding=utf-8 :
# (C) 2011 Guido Günther <>
# (C) 2011,2015 Guido Günther <>
# (C) 2012 Intel Corporation <>
# 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
......@@ -175,7 +175,7 @@ def write_patch_file(filename, commit_info, diff):
def format_patch(outdir, repo, commit_info, series, numbered=True,
path_exclude_regex=None, topic=''):
path_exclude_regex=None, topic='', name=None):
"""Create patch of a single commit"""
# Determine filename and path
......@@ -186,7 +186,10 @@ def format_patch(outdir, repo, commit_info, series, numbered=True,
suffix = '.patch'
base_maxlen = 63 - len(num_prefix) - len(suffix)
base = commit_info['patchname'][:base_maxlen]
filename = (num_prefix if numbered else '') + base + suffix
if name is not None:
filename = name
filename = (num_prefix if numbered else '') + base + suffix
filepath = os.path.join(outdir, filename)
# Make sure that we don't overwrite existing patches in the series
if filepath in series:
......@@ -275,7 +278,7 @@ def apply_single_patch(repo, branch, patch, fallback_author, topic=None):"Applied %s" % os.path.basename(patch.path))
def apply_and_commit_patch(repo, patch, fallback_author, topic=None):
def apply_and_commit_patch(repo, patch, fallback_author, topic=None, name=None):
"""apply a single patch 'patch', add topic 'topic' and commit it"""
author = {'name':,
......@@ -296,6 +299,8 @@ def apply_and_commit_patch(repo, patch, fallback_author, topic=None):
msg = "%s\n\n%s" % (patch.subject, patch.long_desc)
if topic:
msg += "\nGbp-Pq: Topic %s" % topic
if name:
msg += "\nGbp-Pq: Name %s" % name
commit = repo.commit_tree(tree, msg, [repo.head], author=author)
repo.update_ref('HEAD', commit, msg="gbp-pq import %s" % patch.path)
......@@ -77,26 +77,27 @@ def generate_patches(repo, start, end, outdir, options):
for commit in rev_list:
info = repo.get_commit_info(commit)
# Parse 'gbp-pq-topic:'
topic = parse_old_style_topic(info)
cmds ={'topic': topic } if topic else {}
topic = parse_old_style_topic(info)
cmds = {'topic': topic} if topic else {}
# Parse 'Gbp: ' style commands
(cmds_gbp, info['body']) = parse_gbp_commands(info, 'gbp',
('topic', 'name'),
('topic', 'name'))
# Parse 'Gbp-Pq: ' style commands
(cmds_gbp_pq, info['body']) = parse_gbp_commands(info,
('topic', 'name'),
('topic', 'name'))
if not 'ignore' in cmds:
if 'ignore' not in cmds:
if 'topic' in cmds:
topic = cmds['topic']
name = cmds.get('name', None)
format_patch(outdir, repo, info, patches, options.patch_numbers,
topic=topic, name=name)
else:'Ignoring commit %s' % info['id'])
......@@ -286,7 +287,8 @@ def import_quilt_patches(repo, branch, series, tries, force):
for patch in queue:
gbp.log.debug("Applying %s" % patch.path)
apply_and_commit_patch(repo, patch, maintainer, patch.topic)
name = os.path.basename(patch.path)
apply_and_commit_patch(repo, patch, maintainer, patch.topic, name)
except (GbpError, GitRepositoryError) as e:
gbp.log.err("Failed to apply '%s': %s" % (patch.path, e))
repo.force_head('HEAD', hard=True)
......@@ -19,7 +19,6 @@ from . import context
from . import testutils
import os
import logging
import unittest
from gbp.scripts.pq import generate_patches, export_patches
......@@ -49,6 +48,14 @@ class TestApplyAndCommit(testutils.DebianGitTestRepo):
info = self.repo.get_commit_info('HEAD')
self.assertIn('Gbp-Pq: Topic foobar', info['body'])
def test_name(self):
"""Test if setting a name works"""
patch = gbp.patch_series.Patch(_patch_path('foo.patch'))
pq.apply_and_commit_patch(self.repo, patch, None, name='foobar')
info = self.repo.get_commit_info('HEAD')
self.assertIn('Gbp-Pq: Name foobar', info['body'])
@unittest.skipIf(not os.path.exists('/usr/bin/dpkg'), 'Dpkg not found')
def test_debian_missing_author(self):
......@@ -112,26 +119,30 @@ class TestWritePatch(testutils.DebianGitTestRepo):
class opts:
patch_numbers = False
d = context.new_tmpdir(__name__)
expected_paths = [os.path.join(str(d), 'gbptest', n) for n in
['added-foo.patch', 'patchname.diff']]
# Add test file with topic:
msg = ("added foo\n\n"
"Gbp-Pq: Topic gbptest")
self.add_file('foo', 'foo', msg)
msg = ("added bar\n\n"
"Gbp-Pq: Topic gbptest\n"
"Gbp-Pq: Name patchname.diff")
self.add_file('baz', 'baz', msg)
# Write it out as patch and check it's existence
d = context.new_tmpdir(__name__)
patchfile = generate_patches(self.repo, 'HEAD^', 'HEAD', str(d),
expected = os.path.join(str(d), 'gbptest', 'added-foo.patch')
patchfiles = generate_patches(self.repo, 'HEAD^^', 'HEAD', str(d),
for expected in expected_paths:
self.assertIn(expected, patchfiles)
# Reapply the patch to a new branch
self.repo.create_branch('testapply', 'HEAD^')
self.repo.create_branch('testapply', 'HEAD^^')
for expected in expected_paths:
diff = self.repo.diff('master', 'testapply')
# Branches must be identical afterwards
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment