Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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)
Beispiel #4
0
 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
Beispiel #5
0
Datei: new.py Projekt: gwd/stgit
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()
Beispiel #6
0
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
Beispiel #7
0
 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)
Beispiel #8
0
 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)
Beispiel #9
0
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()
Beispiel #10
0
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
Beispiel #12
0
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()