def generate_patches(repo, start, end, outdir, options): """ Generate patch files from git """ gbp.log.info("Generating patches from git (%s..%s)" % (start, end)) patches = [] for treeish in [start, end]: if not repo.has_treeish(treeish): raise GbpError('%s not a valid tree-ish' % treeish) # Generate patches rev_list = reversed(repo.get_commits(start, end)) topic_regex = 'gbp-pq-topic:\s*(?P<topic>\S.*)' for commit in rev_list: info = repo.get_commit_info(commit) cmds = parse_gbp_commands(info, 'gbp', ('ignore'), ('topic')) cmds.update(parse_gbp_commands(info, 'gbp-pq', ('ignore'), ('topic'))) if not 'ignore' in cmds: topic = cmds['topic'] if 'topic' in cmds else '' format_patch(outdir, repo, info, patches, options.patch_numbers, topic_regex=topic_regex, topic=topic) else: gbp.log.info('Ignoring commit %s' % info['id']) return patches
def test_filter_cmd(self): orig_body = '\n'.join(["Foo", "tag: cmd1"]) info = {'body': orig_body} (cmds, body) = pq.parse_gbp_commands(info, 'tag', ['cmd'], ['argcmd'], ['cmd']) self.assertEquals(cmds, {'cmd': None}) self.assertEquals(body, 'Foo')
def generate_patches(repo, start, 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 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)) # Check for merge commits, 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) 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 # Generate patches for commit in reversed(repo.get_commits(start, end_commit)): info = repo.get_commit_info(commit) (cmds, info['body']) = parse_gbp_commands(info, 'gbp-rpm', ('ignore'), ('if', 'ifarch')) if 'ignore' not in cmds: patch_fn = format_patch(outdir, repo, info, patches, options.patch_numbers) 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) return [os.path.relpath(p) for p in patches], commands
def generate_patches(repo, start, end, outdir, options): """ Generate patch files from git """ gbp.log.info("Generating patches from git (%s..%s)" % (start, end)) patches = [] for treeish in [start, end]: if not repo.has_treeish(treeish): raise GbpError('%s not a valid tree-ish' % treeish) # Generate patches rev_list = reversed(repo.get_commits(start, end)) 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 {} # Parse 'Gbp: ' style commands (cmds_gbp, info['body']) = parse_gbp_commands(info, 'gbp', ('ignore'), ('topic', 'name'), ('topic', 'name')) cmds.update(cmds) # Parse 'Gbp-Pq: ' style commands (cmds_gbp_pq, info['body']) = parse_gbp_commands(info, 'gbp-pq', ('ignore'), ('topic', 'name'), ('topic', 'name')) cmds.update(cmds_gbp_pq) if 'ignore' not in cmds: if 'topic' in cmds: topic = cmds['topic'] name = cmds.get('name', None) format_patch(outdir, repo, info, patches, options.abbrev, numbered=options.patch_numbers, topic=topic, name=name, renumber=options.renumber, patch_num_prefix_format=options.patch_num_format) else: gbp.log.info('Ignoring commit %s' % info['id']) return patches
def compose(cls, commit_info, **kwargs): """ Generate a changelog entry from a git commit. @param commit_info: info about the commit @type commit_info: C{commit_info} object from L{gbp.git.repository.GitRepository.get_commit_info()}. @param kwargs: additional arguments to the compose() method, currently we recognize 'full', 'id_len' and 'ignore_re' @type kwargs: C{dict} @return: formatted changelog entry @rtype: C{list} of C{str} """ # Parse and filter out gbp command meta-tags cmds, body = parse_gbp_commands(commit_info, 'gbp-rpm-ch', ('ignore', 'short', 'full'), ()) body = body.splitlines() if 'ignore' in cmds: return None # Parse and filter out bts-related meta-tags bts_tags, body = cls._parse_bts_tags(body, cls.bts_meta_tags) # Additional filtering body = cls._extra_filter(body, kwargs['ignore_re']) # Generate changelog entry subject = commit_info['subject'] commitid = commit_info['id'] if kwargs['id_len']: text = ["- [%s] %s" % (commitid[0:kwargs['id_len']], subject)] else: text = ["- %s" % subject] # Add all non-filtered-out lines from commit message, unless 'short' if (kwargs['full'] or 'full' in cmds) and 'short' not in cmds: # Add all non-blank body lines. text.extend([" " + line for line in body if line.strip()]) # Add bts tags and ids in the end for tag, ids in bts_tags.items(): bts_msg = " (%s: %s)" % (tag, ', '.join(ids)) if len(text[-1]) + len(bts_msg) >= cls.max_entry_line_length: text.append(" ") text[-1] += bts_msg return text
def compose(cls, commit_info, **kwargs): """ Generate a changelog entry from a git commit. @param commit_info: info about the commit @type commit_info: C{commit_info} object from L{gbp.git.repository.GitRepository.get_commit_info()}. @param kwargs: additional arguments to the compose() method, currently we recognize 'full', 'id_len' and 'ignore_re' @type kwargs: C{dict} @return: formatted changelog entry @rtype: C{list} of C{str} """ # Parse and filter out gbp command meta-tags cmds, body = parse_gbp_commands(commit_info, 'gbp-rpm-ch', ('ignore', 'short', 'full'), ()) body = body.splitlines() if 'ignore' in cmds: return None # Parse and filter out bts-related meta-tags bts_tags, body = cls._parse_bts_tags(body, cls.bts_meta_tags) # Additional filtering body = cls._extra_filter(body, kwargs['ignore_re']) # Generate changelog entry subject = commit_info['subject'] commitid = commit_info['id'] if kwargs['id_len']: text = ["- [%s] %s" % (commitid[0:kwargs['id_len']], subject)] else: text = ["- %s" % subject] # Add all non-filtered-out lines from commit message, unless 'short' if (kwargs['full'] or 'full' in cmds) and 'short' not in cmds: # Add all non-blank body lines. text.extend([" " + line for line in body if line.strip()]) # Add bts tags and ids in the end for tag, ids in bts_tags.iteritems(): bts_msg = " (%s: %s)" % (tag, ', '.join(ids)) if len(text[-1]) + len(bts_msg) >= cls.max_entry_line_length: text.append(" ") text[-1] += bts_msg return text
def test_empty_body(self): """Test command filtering with an empty body""" info = {'body': ''} (cmds, body) = pq.parse_gbp_commands(info, ['tag'], ['cmd1'], ['cmd2']) self.assertEquals(cmds, {}) self.assertEquals(body, '')
def generate_patches(repo, start, 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 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)) # Check for merge commits, 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) 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 # Generate patches for commit in reversed(repo.get_commits(start, end_commit)): info = repo.get_commit_info(commit) (cmds, info['body']) = parse_gbp_commands(info, 'gbp-rpm', ('ignore'), ('if', 'ifarch')) if not 'ignore' in cmds: patch_fn = format_patch(outdir, repo, info, patches, options.patch_numbers) 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) return patches, commands