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, filter_cmds=None):
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)
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)
gbp.log.info("Applied %s" % os.path.basename(patch.path))
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)
gbp.log.info("No patch queue branch found - doing nothing.")
-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 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):
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):
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'
@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)
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])
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:
def export_patches(repo, options):
"""Export patches from the pq branch into a packaging branch"""
current = repo.get_branch()
- 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("On branch '%s', switching to '%s'" % (current, base))
repo.set_branch(base)
pq_branch = current
else:
- pq_branch = pq_branch_name(current)
+ pq_branch = pq_branch_name(current, options)
spec = parse_spec(options, repo)
upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
export_treeish = pq_branch
"""
current = repo.get_branch()
# Get spec and related information
- if is_pq_branch(current):
- base = pq_branch_base(current)
+ if is_pq_branch(current, options):
+ base = pq_branch_base(current, options)
if options.force:
spec = parse_spec(options, repo, base)
spec_treeish = base
base = current
upstream_commit = find_upstream_commit(repo, spec, options.upstream_tag)
packager = get_packager(spec)
- pq_branch = pq_branch_name(base)
+ pq_branch = pq_branch_name(base, options)
# Create pq-branch
if repo.has_branch(pq_branch) and not options.force:
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):
- base = pq_branch_base(current)
+ 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)
+ switch_to_pq_branch(repo, base, options)
GitCommand("rebase")([upstream_commit])
elif action == "import":
import_spec_patches(repo, options)
elif action == "drop":
- drop_pq(repo, current)
+ drop_pq(repo, current, options)
elif action == "rebase":
rebase_pq(repo, options)
elif action == "apply":
patch = Patch(patchfile)
- apply_single_patch(repo, current, patch, fallback_author=None)
+ apply_single_patch(repo, current, patch, None, options)
elif action == "switch":
- switch_pq(repo, current)
+ switch_pq(repo, current, options)
except CommandExecFailed:
retval = 1
except GitRepositoryError as err:
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):
repo = self.repo
start = repo.get_branch()
pq_branch = os.path.join('patch-queue', start)
- pq.switch_pq(repo, start)
+ switch_pq(repo, start, TestExport.Options)
self.assertEqual(repo.get_branch(), pq_branch)
export_patches(repo, pq_branch, TestExport.Options)
self.assertEqual(repo.get_branch(), start)