def _squash_patches(trans, patches, msg, save_template, no_verify=False): cd = trans.patches[patches[0]].data for pn in patches[1:]: c = trans.patches[pn] tree = trans.stack.repository.simple_merge( base=c.data.parent.data.tree, ours=cd.tree, theirs=c.data.tree, ) if not tree: return None cd = cd.set_tree(tree) if msg is None: msg = _append_comment( cd.message_str, '\n\n'.join('%s\n\n%s' % (pn.ljust(70, '-'), trans.patches[pn].data.message_str) for pn in patches[1:])) if save_template: save_template(msg.encode(cd.encoding)) raise SaveTemplateDone() else: msg = utils.edit_string(msg, '.stgit-squash.txt') msg = _strip_comment(msg).strip() cd = cd.set_message(msg) if not no_verify: cd = run_commit_msg_hook(trans.stack.repository, cd) return cd
def _squash_patches(trans, patches, msg, save_template, no_verify=False): cd = trans.patches[patches[0]].data cd = git.CommitData(tree = cd.tree, parents = cd.parents) for pn in patches[1:]: c = trans.patches[pn] tree = trans.stack.repository.simple_merge( base = c.data.parent.data.tree, ours = cd.tree, theirs = c.data.tree) if not tree: return None cd = cd.set_tree(tree) if msg is None: msg = utils.append_comment( trans.patches[patches[0]].data.message, '\n\n'.join('%s\n\n%s' % (pn.ljust(70, '-'), trans.patches[pn].data.message) for pn in patches[1:])) if save_template: save_template(msg) raise SaveTemplateDone() else: msg = utils.edit_string(msg, '.stgit-squash.txt') msg = utils.strip_comment(msg).strip() cd = cd.set_message(msg) if not no_verify: cd = common.run_commit_msg_hook(trans.stack.repository, cd) return cd
def func(parser, options, args): """Create a new patch.""" stack = directory.repository.current_stack if stack.repository.default_index.conflicts(): raise CmdException( 'Cannot create a new patch -- resolve conflicts first') # Choose a name for the new patch -- or None, which means make one # up later when we've gotten hold of the commit message. if len(args) == 0: name = None elif len(args) == 1: name = args[0] if not stack.patches.is_name_valid(name): raise CmdException('Invalid patch name: "%s"' % name) elif name in stack.patches: raise CmdException('%s: patch already exists' % name) else: parser.error('incorrect number of arguments') if options.verbose: verbose = options.verbose else: verbose = config.getbool('stgit.new.verbose') or False cd = CommitData( tree=stack.head.data.tree, parents=[stack.head], message='', author=Person.author(), committer=Person.committer(), ) cd = update_commit_data( stack.repository, cd, message=options.message, author=options.author(cd.author), trailers=options.trailers, edit=(not options.save_template and options.message is None), verbose=verbose, ) if options.save_template: options.save_template(cd.message) return utils.STGIT_SUCCESS if not options.no_verify: cd = run_commit_msg_hook(stack.repository, cd) if name is None: name = stack.patches.make_name(cd.message_str) # Write the new patch. check_head_top_equal(stack) trans = StackTransaction(stack) trans.patches[name] = stack.repository.commit(cd) trans.applied.append(name) return trans.execute('new: %s' % name)
def edit_fun(cd): orig_msg = cd.message cd, failed_diff = edit.auto_edit_patch( stack.repository, cd, msg = options.message, contains_diff = False, author = options.author, committer = lambda p: p, sign_str = options.sign_str) assert not failed_diff if options.edit: cd, failed_diff = edit.interactive_edit_patch( stack.repository, cd, edit_diff = False, diff_flags = [], replacement_diff = None) assert not failed_diff if not options.no_verify and (options.edit or cd.message != orig_msg): cd = common.run_commit_msg_hook(stack.repository, cd, options.edit) return cd
def func(parser, options, args): """Create a new patch.""" stack = directory.repository.current_stack if stack.repository.default_index.conflicts(): raise CmdException( 'Cannot create a new patch -- resolve conflicts first') # Choose a name for the new patch -- or None, which means make one # up later when we've gotten hold of the commit message. if len(args) == 0: name = None elif len(args) == 1: name = args[0] if stack.patches.exists(name): raise CmdException('%s: patch already exists' % name) elif not stack.patches.is_name_valid(name): raise CmdException('Invalid patch name: "%s"' % name) else: parser.error('incorrect number of arguments') cd = CommitData( tree=stack.head.data.tree, parents=[stack.head], message='', author=Person.author(), committer=Person.committer(), ) cd = update_commit_data(cd, options) if options.save_template: options.save_template(cd.message.encode('utf-8')) return utils.STGIT_SUCCESS if not options.no_verify: cd = run_commit_msg_hook(stack.repository, cd) if name is None: name = utils.make_patch_name(cd.message, stack.patches.exists) assert stack.patches.is_name_valid(name) # Write the new patch. stack.repository.default_iw trans = StackTransaction(stack, 'new: %s' % name) trans.patches[name] = stack.repository.commit(cd) trans.applied.append(name) return trans.run()
def _squash_patches(trans, patches, name, msg, save_template, no_verify=False): cd = trans.patches[patches[0]].data for pn in patches[1:]: c = trans.patches[pn] tree = trans.stack.repository.simple_merge( base=c.data.parent.data.tree, ours=cd.tree, theirs=c.data.tree, ) if not tree: return None cd = cd.set_tree(tree) if msg is None: if name: msg = "# Squashing %s patches as '%s'.\n" % (len(patches), name) else: msg = "# Squashing %s patches.\n" % len(patches) for num, pn in enumerate(patches, 1): msg += "# This is the commit message for patch #%s (%s):" % ( num, pn, ) msg += "\n%s\n\n" % trans.patches[pn].data.message_str.rstrip() msg += ( "# Please enter the commit message for your patch. Lines starting\n" "# with '#' will be ignored.") if save_template: save_template(msg.encode(cd.encoding)) raise SaveTemplateDone() else: msg = utils.edit_string(msg, '.stgit-squash.txt') msg = '\n'.join(_strip_comments(msg)).strip() if not msg: raise CmdException('Aborting squash due to empty commit message') cd = cd.set_message(msg) if not no_verify: cd = run_commit_msg_hook(trans.stack.repository, cd) return cd
def edit_fun(cd): orig_msg = cd.message cd = auto_edit_patch( stack.repository, cd, msg=(None if options.message is None else options.message.encode( config.get('i18n.commitencoding'))), author=options.author, sign_str=options.sign_str, ) if options.edit: cd, failed_diff = interactive_edit_patch(stack.repository, cd, edit_diff=False, diff_flags=[]) assert not failed_diff if not options.no_verify and (options.edit or cd.message != orig_msg): cd = run_commit_msg_hook(stack.repository, cd, options.edit) # Refresh the committer information return cd.set_committer(None)
def edit_fun(cd): orig_msg = cd.message new_msg = None if message is not None: new_msg = message.encode(config.get('i18n.commitencoding')) cd = auto_edit_patch( stack.repository, cd, msg=new_msg, author=author, sign_str=sign_str, ) if invoke_editor: cd, failed_diff = interactive_edit_patch(stack.repository, cd, edit_diff, diff_flags) assert not failed_diff if not no_verify and (invoke_editor or cd.message != orig_msg): cd = run_commit_msg_hook(stack.repository, cd, invoke_editor) # Refresh the committer information return cd.set_committer(None)
def func(parser, options, args): """Create a new patch.""" stack = directory.repository.current_stack if stack.repository.default_index.conflicts(): raise common.CmdException( 'Cannot create a new patch -- resolve conflicts first') # Choose a name for the new patch -- or None, which means make one # up later when we've gotten hold of the commit message. if len(args) == 0: name = None elif len(args) == 1: name = args[0] if stack.patches.exists(name): raise common.CmdException('%s: patch already exists' % name) else: parser.error('incorrect number of arguments') cd = gitlib.CommitData( tree = stack.head.data.tree, parents = [stack.head], message = '', author = gitlib.Person.author(), committer = gitlib.Person.committer()) cd = common.update_commit_data(cd, options) if options.save_template: options.save_template(cd.message) return utils.STGIT_SUCCESS if not options.no_verify: cd = common.run_commit_msg_hook(stack.repository, cd) if name is None: name = utils.make_patch_name(cd.message, lambda name: stack.patches.exists(name)) # Write the new patch. iw = stack.repository.default_iw trans = transaction.StackTransaction(stack, 'new') trans.patches[name] = stack.repository.commit(cd) trans.applied.append(name) return trans.run()
def func(parser, options, args): """Edit the given patch or the current one. """ stack = directory.repository.current_stack if len(args) == 0: if not stack.patchorder.applied: raise CmdException( 'Cannot edit top patch, because no patches are applied') patchname = stack.patchorder.applied[-1] elif len(args) == 1: [patchname] = args if not stack.patches.exists(patchname): raise CmdException('%s: no such patch' % patchname) else: parser.error('Cannot edit more than one patch') cd = orig_cd = stack.patches.get(patchname).commit.data if options.set_tree: cd = cd.set_tree( stack.repository.rev_parse(options.set_tree, discard_stderr=True, object_type='tree')) cd = edit.auto_edit_patch( stack.repository, cd, msg=(None if options.message is None else options.message.encode( config.get('i18n.commitencoding'))), author=options.author, sign_str=options.sign_str, ) if options.save_template: options.save_template( edit.patch_desc( stack.repository, cd, options.diff, options.diff_flags, replacement_diff=None, )) return utils.STGIT_SUCCESS use_editor = cd == orig_cd or options.edit or options.diff if use_editor: cd, failed_diff = edit.interactive_edit_patch(stack.repository, cd, options.diff, options.diff_flags) else: failed_diff = None def failed(reason='Edited patch did not apply.'): fn = '.stgit-failed.patch' with io.open(fn, 'wb') as f: f.write( edit.patch_desc( stack.repository, cd, options.diff, options.diff_flags, replacement_diff=failed_diff, )) out.error(reason, 'The patch has been saved to "%s".' % fn) return utils.STGIT_COMMAND_ERROR # If we couldn't apply the patch, fail without even trying to # effect any of the changes. if failed_diff: return failed() if not options.no_verify and (use_editor or cd.message != orig_cd.message): try: cd = run_commit_msg_hook(stack.repository, cd, use_editor) except Exception: if options.diff: failed('The commit-msg hook failed.') raise # Refresh the committer information cd = cd.set_committer(None) # The patch applied, so now we have to rewrite the StGit patch # (and any patches on top of it). iw = stack.repository.default_iw trans = transaction.StackTransaction(stack, 'edit', allow_conflicts=True) if patchname in trans.applied: popped = trans.applied[trans.applied.index(patchname) + 1:] popped_extra = trans.pop_patches(lambda pn: pn in popped) assert not popped_extra else: popped = [] trans.patches[patchname] = stack.repository.commit(cd) try: for pn in popped: if options.set_tree: trans.push_tree(pn) else: trans.push_patch(pn, iw, allow_interactive=True) except transaction.TransactionHalted: pass try: # Either a complete success, or a conflict during push. But in # either case, we've successfully effected the edits the user # asked us for. return trans.run(iw) except transaction.TransactionException: # Transaction aborted -- we couldn't check out files due to # dirty index/worktree. The edits were not carried out. return failed()
def func(parser, options, args): """Edit the given patch or the current one.""" stack = directory.repository.current_stack if len(args) == 0: if not stack.patchorder.applied: raise CmdException( 'Cannot edit top patch because no patches are applied') patchname = stack.patchorder.applied[-1] elif len(args) == 1: [patchname] = args if patchname not in stack.patches: raise CmdException('%s: no such patch' % patchname) else: parser.error('Cannot edit more than one patch') cd = orig_cd = stack.patches[patchname].data if options.set_tree: cd = cd.set_tree( stack.repository.rev_parse(options.set_tree, discard_stderr=True, object_type='tree')) cd = edit.auto_edit_patch( stack.repository, cd, msg=(None if options.message is None else options.message.encode( config.get('i18n.commitencoding'))), author=options.author, trailers=options.trailers, ) if options.save_template: options.save_template( edit.get_patch_description(stack.repository, cd, patchname, options.diff, options.diff_flags)) return utils.STGIT_SUCCESS use_editor = cd == orig_cd or options.edit or options.diff if use_editor: cd, new_patchname, failed_diff = edit.interactive_edit_patch( stack.repository, cd, patchname, options.diff, options.diff_flags) # If we couldn't apply the patch, fail without even trying to # affect any of the changes. if failed_diff is not None: return utils.STGIT_COMMAND_ERROR else: new_patchname = None if not options.no_verify and (use_editor or cd.message != orig_cd.message): try: cd = run_commit_msg_hook(stack.repository, cd, use_editor) except Exception: if options.diff: patch_desc = edit.get_patch_description( stack.repository, cd, patchname, options.diff, options.diff_flags) edit.note_patch_application_failure( patch_desc, 'The commit-msg hook failed.') raise retval, _ = edit.perform_edit( stack, cd, patchname, new_patchname, options.diff, options.diff_flags, options.set_tree, ) return retval
def func(parser, options, args): """Edit the given patch or the current one. """ stack = directory.repository.current_stack if len(args) == 0: if not stack.patchorder.applied: raise common.CmdException( 'Cannot edit top patch, because no patches are applied') patchname = stack.patchorder.applied[-1] elif len(args) == 1: [patchname] = args if not stack.patches.exists(patchname): raise common.CmdException('%s: no such patch' % patchname) else: parser.error('Cannot edit more than one patch') cd = orig_cd = stack.patches.get(patchname).commit.data if options.set_tree: cd = cd.set_tree(stack.repository.rev_parse( options.set_tree, discard_stderr = True, object_type = 'tree')) cd, failed_diff = edit.auto_edit_patch( stack.repository, cd, msg = options.message, contains_diff = True, author = options.author, committer = lambda p: p, sign_str = options.sign_str) if options.save_template: options.save_template( edit.patch_desc(stack.repository, cd, options.diff, options.diff_flags, failed_diff)) return utils.STGIT_SUCCESS use_editor = cd == orig_cd or options.edit if use_editor: cd, failed_diff = edit.interactive_edit_patch( stack.repository, cd, options.diff, options.diff_flags, failed_diff) def failed(reason='Edited patch did not apply.'): fn = '.stgit-failed.patch' with open(fn, 'w') as f: f.write(edit.patch_desc(stack.repository, cd, options.diff, options.diff_flags, failed_diff)) out.error(reason, 'The patch has been saved to "%s".' % fn) return utils.STGIT_COMMAND_ERROR # If we couldn't apply the patch, fail without even trying to # effect any of the changes. if failed_diff: return failed() if not options.no_verify and (use_editor or cd.message != orig_cd.message): try: cd = common.run_commit_msg_hook(stack.repository, cd, use_editor) except Exception: if options.diff: failed('The commit-msg hook failed.') raise # The patch applied, so now we have to rewrite the StGit patch # (and any patches on top of it). iw = stack.repository.default_iw trans = transaction.StackTransaction(stack, 'edit', allow_conflicts = True) if patchname in trans.applied: popped = trans.applied[trans.applied.index(patchname)+1:] assert not trans.pop_patches(lambda pn: pn in popped) else: popped = [] trans.patches[patchname] = stack.repository.commit(cd) try: for pn in popped: if options.set_tree: trans.push_tree(pn) else: trans.push_patch(pn, iw, allow_interactive = True) except transaction.TransactionHalted: pass try: # Either a complete success, or a conflict during push. But in # either case, we've successfully effected the edits the user # asked us for. return trans.run(iw) except transaction.TransactionException: # Transaction aborted -- we couldn't check out files due to # dirty index/worktree. The edits were not carried out. return failed()