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 test_topic(self): """Test if setting a topic works""" patch = gbp.patch_series.Patch(_patch_path('foo.patch')) pq.apply_and_commit_patch(self.repo, patch, None, topic='foobar') info = self.repo.get_commit_info('HEAD') self.assertIn('Gbp-Pq-Topic: foobar', info['body'])
def test_debian_missing_author(self): """ Check if we parse the author from debian control if it's missing in the patch. """ def _check_log(msg): self.assertEqual(msg, "Patch 'foo.patch' has no authorship " "information, using 'Guido Günther <*****@*****.**>'") patch = gbp.patch_series.Patch(_patch_path('foo.patch')) # Overwrite data parsed from patch: patch.author patch.info['author'] = None patch.info['email'] = None # Fake a control file self.add_file("debian/control", "Maintainer: Guido Günther <*****@*****.**>") maintainer = pq.get_maintainer_from_control(self.repo) orig_warn = gbp.log.warn gbp.log.warn = _check_log pq.apply_and_commit_patch(self.repo, patch, maintainer) gbp.log.warn = orig_warn info = self.repo.get_commit_info('HEAD') self.assertEqual(info['author'].email, '*****@*****.**') self.assertIn('foo', self.repo.list_files())
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'])
def import_spec_patches(repo, spec, dirs): """ Import patches from a spec file to the current branch """ queue = spec.patchseries() if len(queue) == 0: return gbp.log.info("Importing patches to '%s' branch" % repo.get_branch()) tmpdir = tempfile.mkdtemp(dir=dirs['tmp_base'], prefix='import_') orig_head = repo.rev_parse("HEAD") packager = get_packager(spec) # Put patches in a safe place queue = safe_patches(queue, tmpdir) for patch in queue: gbp.log.debug("Applying %s" % patch.path) try: apply_and_commit_patch(repo, patch, packager) except (GbpError, GitRepositoryError): repo.force_head(orig_head, hard=True) raise PatchImportError("Patch(es) didn't apply, you need apply " "and commit manually") # Remove patches from spec and packaging directory gbp.log.info("Removing imported patch files from spec and packaging dir") rm_patch_files(spec) try: spec.update_patches([], {}) spec.write_spec_file() except GbpError: repo.force_head('HEAD', hard=True) raise PatchImportError("Unable to update spec file, you need to edit" "and commit it manually") repo.commit_all(msg=PATCH_AUTODELETE_COMMIT_MSG % spec.specfile)
def test_apply_and_commit_patch(self): """Test applying a single patch""" patch = gbp.patch_series.Patch( os.path.join(os.path.abspath(os.path.curdir), 'tests/data/foo.patch')) pq.apply_and_commit_patch(self.repo, patch, None) self.assertIn('foo', self.repo.list_files())
def test_apply_and_commit_patch_preserve_subject(self): """Test applying a patch preserves the subject""" patch = gbp.patch_series.Patch(_patch_path('brackets-in-subject.patch')) pq.apply_and_commit_patch(self.repo, patch, None) self.assertIn(b'foo', self.repo.list_files()) info = self.repo.get_commit_info('HEAD') self.assertEquals('[text] foobar', info['subject'])
def test_apply_and_commit_patch_preserve_subject(self): """Test applying a patch preserves the subject""" patch = gbp.patch_series.Patch( _patch_path('brackets-in-subject.patch')) pq.apply_and_commit_patch(self.repo, patch, None) self.assertIn(b'foo', self.repo.list_files()) info = self.repo.get_commit_info('HEAD') self.assertEquals('[text] foobar', info['subject'])
def import_bb_patches(cfg, repo, options): """Apply a series of patches in a recipe to branch onto a pq branch""" current = repo.get_branch() if is_pq_branch(current, options): base = pq_branch_base(current, options) raise GbpError("Already on a patch-queue branch '%s' - doing " "nothing." % current) else: bbfile = parse_bb(cfg, options, repo) base = current upstream_commit = find_upstream_commit(repo, bbfile, options.upstream_tag) pq_branch = pq_branch_name(base, options, pkg_version(bbfile)) # Create pq-branch if repo.has_branch(pq_branch) and not options.force: raise GbpError("Patch-queue branch '%s' already exists. " "Try 'rebase' 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 in_queue = bb_to_patch_series(bbfile) 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, fallback_author=None) except (GbpError, GitRepositoryError) as err: gbp.log.err('Import failed: %s' % err) repo.force_head('HEAD', hard=True) repo.set_branch(base) repo.delete_branch(pq_branch) raise recipe_fn = os.path.basename(bbfile.getVar('FILE', True)) gbp.log.info("Patches listed in '%s' imported on '%s'" % (recipe_fn, pq_branch))
def test_debian_missing_author(self): """ Check if we parse the author from debian control if it's missing. """ patch = gbp.patch_series.Patch( os.path.join(os.path.abspath(os.path.curdir), 'tests/data/foo.patch')) # Overwrite data parsed from patch: patch.author patch.info['author'] = None patch.info['email'] = None # Fake a control file self.add_file("debian/control", "Maintainer: Guido Günther <*****@*****.**>") c = pq.get_maintainer_from_control pq.apply_and_commit_patch(self.repo, patch, c) info = self.repo.get_commit_info('HEAD') self.assertEqual(info['author'].email, '*****@*****.**') self.assertIn('foo', self.repo.list_files())
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): base = pq_branch_base(current) 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) # 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_') 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) # Do import try: gbp.log.info("Switching to branch '%s'" % pq_branch) repo.set_branch(pq_branch) 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("%d patches listed in '%s' imported on '%s'" % (len(queue), spec.specfile, pq_branch))
def import_quilt_patches(repo, branch, series, tries, force): """ apply a series of quilt patches in the series file 'series' to branch the patch-queue branch for 'branch' @param repo: git repository to work on @param branch: branch to base pqtch queue on @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 """ tmpdir = None if is_pq_branch(branch): if force: branch = pq_branch_base(branch) pq_branch = pq_branch_name(branch) 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) if repo.has_branch(pq_branch): if force: drop_pq(repo, branch) else: raise GbpError("Patch queue branch '%s'. already exists. Try 'rebase' instead." % pq_branch) maintainer = get_maintainer_from_control(repo) commits = repo.get_commits(num=tries, first_parent=True) # If we go back in history we have to safe our pq so we always try to apply # the latest one if len(commits) > 1: tmpdir, series = safe_patches(series) queue = PatchSeries.read_series_file(series) i = len(commits) for commit in commits: if len(commits) > 1: gbp.log.info("%d %s left" % (i, 'tries' if i > 1 else 'try')) try: gbp.log.info("Trying to apply patches at '%s'" % commit) repo.create_branch(pq_branch, commit) except GitRepositoryError: raise GbpError("Cannot create patch-queue branch '%s'." % pq_branch) repo.set_branch(pq_branch) for patch in queue: gbp.log.debug("Applying %s" % patch.path) try: apply_and_commit_patch(repo, patch, maintainer, patch.topic) except (GbpError, GitRepositoryError): gbp.log.err("Failed to apply '%s'" % patch.path) repo.set_branch(branch) repo.delete_branch(pq_branch) break else: # All patches applied successfully break i-=1 else: raise GbpError("Couldn't apply patches") if tmpdir: gbp.log.debug("Remove temporary patch safe '%s'" % tmpdir) shutil.rmtree(tmpdir)
def import_quilt_patches(repo, branch, series, tries, force, pq_from, upstream_tag): """ apply a series of quilt patches in the series file 'series' to branch the patch-queue branch for 'branch' @param repo: git repository to work on @param branch: branch to base patch queue on @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 pq_from: what to use as the starting point for the pq branch. DEBIAN indicates the current branch, TAG indicates that the corresponding upstream tag should be used. @param upstream_tag: upstream tag template to use """ tmpdir = None series = os.path.join(repo.path, series) if is_pq_branch(branch): if force: branch = pq_branch_base(branch) pq_branch = pq_branch_name(branch) repo.checkout(branch) else: raise GbpError( "Already on a patch-queue branch '%s' - doing nothing." % branch) else: pq_branch = pq_branch_name(branch) if repo.has_branch(pq_branch): if force: drop_pq(repo, branch) else: raise GbpError( "Patch queue branch '%s'. already exists. Try 'rebase' or 'switch' instead." % pq_branch) maintainer = get_maintainer_from_control(repo) if pq_on_upstream_tag(pq_from): commits = [find_upstream_commit(repo, branch, upstream_tag)] else: # pq_from == 'DEBIAN' commits = repo.get_commits(num=tries, first_parent=True) # If we go back in history we have to safe our pq so we always try to apply # the latest one # If we are using the upstream_tag, we always need a copy of the patches if len(commits) > 1 or pq_on_upstream_tag(pq_from): if os.path.exists(series): tmpdir, series = safe_patches(series, repo) queue = PatchSeries.read_series_file(series) i = len(commits) for commit in commits: if len(commits) > 1: gbp.log.info("%d %s left" % (i, 'tries' if i > 1 else 'try')) try: gbp.log.info("Trying to apply patches at '%s'" % commit) repo.create_branch(pq_branch, commit) except GitRepositoryError: raise GbpError("Cannot create patch-queue branch '%s'." % pq_branch) repo.set_branch(pq_branch) for patch in queue: gbp.log.debug("Applying %s" % patch.path) try: 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) repo.set_branch(branch) repo.delete_branch(pq_branch) break else: # All patches applied successfully break i -= 1 else: raise GbpError("Couldn't apply patches") if tmpdir: gbp.log.debug("Remove temporary patch safe '%s'" % tmpdir) shutil.rmtree(tmpdir) return len(queue)
def test_apply_and_commit_patch(self): """Test applying a single patch""" patch = gbp.patch_series.Patch(_patch_path('foo.patch')) pq.apply_and_commit_patch(self.repo, patch, None) self.assertIn('foo', self.repo.list_files())
def import_quilt_patches(repo, branch, series, tries, force, pq_from, upstream_tag): """ apply a series of quilt patches in the series file 'series' to branch the patch-queue branch for 'branch' @param repo: git repository to work on @param branch: branch to base patch queue on @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 pq_from: what to use as the starting point for the pq branch. DEBIAN indicates the current branch, TAG indicates that the corresponding upstream tag should be used. @param upstream_tag: upstream tag template to use """ tmpdir = None series = os.path.join(repo.path, series) if is_pq_branch(branch): if force: branch = pq_branch_base(branch) pq_branch = pq_branch_name(branch) repo.checkout(branch) else: raise GbpError("Already on a patch-queue branch '%s' - doing nothing." % branch) else: pq_branch = pq_branch_name(branch) if repo.has_branch(pq_branch): if force: drop_pq(repo, branch) else: raise GbpError("Patch queue branch '%s'. already exists. Try 'rebase' or 'switch' instead." % pq_branch) maintainer = get_maintainer_from_control(repo) if pq_on_upstream_tag(pq_from): commits = [find_upstream_commit(repo, branch, upstream_tag)] else: # pq_from == 'DEBIAN' commits = repo.get_commits(num=tries, first_parent=True) # If we go back in history we have to safe our pq so we always try to apply # the latest one # If we are using the upstream_tag, we always need a copy of the patches if len(commits) > 1 or pq_on_upstream_tag(pq_from): if os.path.exists(series): tmpdir, series = safe_patches(series, repo) queue = PatchSeries.read_series_file(series) i = len(commits) for commit in commits: if len(commits) > 1: gbp.log.info("%d %s left" % (i, 'tries' if i > 1 else 'try')) try: gbp.log.info("Trying to apply patches at '%s'" % commit) repo.create_branch(pq_branch, commit) except GitRepositoryError: raise GbpError("Cannot create patch-queue branch '%s'." % pq_branch) repo.set_branch(pq_branch) for patch in queue: gbp.log.debug("Applying %s" % patch.path) try: 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) repo.set_branch(branch) repo.delete_branch(pq_branch) break else: # All patches applied successfully break i -= 1 else: raise GbpError("Couldn't apply patches") if tmpdir: gbp.log.debug("Remove temporary patch safe '%s'" % tmpdir) shutil.rmtree(tmpdir) return len(queue)
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): base = pq_branch_base(current) 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) # 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) 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))