def edit_fun(cd): 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 return cd
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 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): """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()
def __do_rebase_interactive(repository, previously_applied_patches, check_merged): """Opens an interactive editor, generates instruction list, and executes instructions.""" stack = repository.get_stack() if len(stack.patchorder.all) == 0: return utils.STGIT_SUCCESS name_len = max((len(s) for s in stack.patchorder.all)) line = 'keep {{:<{name_len}}} # {{}}'.format(name_len=name_len) # create a list of all patches to send to the editor raw_editor_instructions = [] for pn in previously_applied_patches: patch = (pn, __get_description(stack, pn)) raw_editor_instructions.append(line.format(*patch)) raw_editor_instructions.append(INTERACTIVE_APPLY_LINE) for pn in stack.patchorder.all: if pn in previously_applied_patches: continue patch = (pn, __get_description(stack, pn)) raw_editor_instructions.append(line.format(*patch)) raw_editor_instructions.append(INTERACTIVE_HELP_INSTRUCTIONS) # open an editor to let the user generate the 'todo' instructions todo = edit_string( '\n'.join(raw_editor_instructions), '.stgit-rebase-interactive.txt', ) # parse the instructions we've been given seen_apply_line = False instructions = [] for line in todo.splitlines(): line = line.strip() # record when we find the APPLY_LINE so we know which patches to apply if INTERACTIVE_APPLY_LINE in line: if INTERACTIVE_APPLY_LINE == line: seen_apply_line = True else: raise CmdException("Bad APPLY_LINE: '%s'" % line) # ignore comment lines if not line or line.startswith('#'): continue # parse a single instruction match = re.match(r'(\S+) (\S+).*', line) if not match: raise CmdException("Bad todo line: '%s'" % line) instruction_str, patch_name = match.groups() if patch_name not in stack.patchorder.all: raise CmdException("Bad patch name '%s'" % patch_name) if instruction_str in ('k', 'keep'): instruction_type = Action.KEEP elif instruction_str in ('e', 'edit'): instruction_type = Action.EDIT elif instruction_str in ('s', 'squash'): instruction_type = Action.SQUASH elif instruction_str in ('f', 'fix', 'fixup'): instruction_type = Action.FIXUP elif instruction_str in ('h', 'hide'): instruction_type = Action.HIDE elif instruction_str in ('d', 'delete'): instruction_type = Action.DELETE else: raise CmdException("Unknown instruction '%s'" % instruction_str) # save the instruction to execute later instructions.append( Instruction(patch_name, instruction_type, not seen_apply_line)) index = 0 while index < len(instructions): patch_name = instructions[index].patch_name if instructions[index].action == Action.HIDE: hide_patches(stack, stack.repository.default_iw, {patch_name}) instructions.pop(index) index = max(0, index - 1) # re-run this index another time continue if instructions[index].action == Action.DELETE: delete_patches(stack, stack.repository.default_iw, {patch_name}) instructions.pop(index) index = max(0, index - 1) # re-run this index another time continue if instructions[index].action == Action.FIXUP and index > 0: base_patch = instructions[index - 1].patch_name __fixup_patches(stack, [base_patch, patch_name]) instructions.pop(index) # remove 'fixed' (ie deleted) patch index -= 1 # re-run this index another time continue if instructions[index].action == Action.EDIT: cd = stack.patches[patch_name].data cd, new_patch_name, failed_diff = edit.interactive_edit_patch( stack.repository, cd, patch_name, edit_diff=True, diff_flags="") if failed_diff is not None: return utils.STGIT_COMMAND_ERROR _, new_patch_name = edit.perform_edit( stack, cd, patch_name, new_patch_name, edit_diff=True, diff_flags="", ) if new_patch_name and patch_name != new_patch_name: instructions[index] = Instruction( new_patch_name, instructions[index].action, instructions[index].apply, ) patch_name = new_patch_name instructions = __perform_squashes(instructions, index, stack) index += 1 post_rebase( stack, [ instruction.patch_name for instruction in instructions if instruction.apply ], 'rebase', check_merged, ) return utils.STGIT_SUCCESS