Example #1
0
def func(parser, options, args):
    """Import a commit object as a new patch
    """
    if not args:
        parser.error('incorrect number of arguments')

    if options.file and not options.fold:
        parser.error('--file can only be specified with --fold')

    if not options.unapplied:
        check_local_changes()
        check_conflicts()
        check_head_top_equal(crt_series)

    if options.ref_branch:
        remote_series = Series(options.ref_branch)
    else:
        remote_series = crt_series

    applied = remote_series.get_applied()
    unapplied = remote_series.get_unapplied()
    try:
        patches = parse_patches(args, applied + unapplied, len(applied))
        commit_id = None
    except CmdException:
        if len(args) > 1:
            raise
        # no patches found, try a commit id
        commit_id = git_id(remote_series, args[0])

    if not commit_id and len(patches) > 1:
        if options.name:
            raise CmdException, '--name can only be specified with one patch'
        if options.parent:
            raise CmdException, '--parent can only be specified with one patch'

    if options.update and not crt_series.get_current():
        raise CmdException, 'No patches applied'

    if commit_id:
        # Try to guess a patch name if the argument was <branch>:<patch>
        try:
            patchname = args[0].split(':')[1]
        except IndexError:
            patchname = None
        __pick_commit(commit_id, patchname, options)
    else:
        if options.unapplied:
            patches.reverse()
        for patch in patches:
            __pick_commit(git_id(remote_series, patch), patch, options)

    print_crt_patch(crt_series)
Example #2
0
def func(parser, options, args):
    """Import a commit object as a new patch
    """
    if not args:
        parser.error('incorrect number of arguments')

    if options.file and not options.fold:
        parser.error('--file can only be specified with --fold')

    if not options.unapplied:
        check_local_changes()
        check_conflicts()
        check_head_top_equal(crt_series)

    if options.ref_branch:
        remote_series = Series(options.ref_branch)
    else:
        remote_series = crt_series

    applied = remote_series.get_applied()
    unapplied = remote_series.get_unapplied()
    try:
        patches = parse_patches(args, applied + unapplied, len(applied))
        commit_id = None
    except CmdException:
        if len(args) > 1:
            raise
        # no patches found, try a commit id
        commit_id = git_id(remote_series, args[0])

    if not commit_id and len(patches) > 1:
        if options.name:
            raise CmdException('--name can only be specified with one patch')
        if options.parent:
            raise CmdException('--parent can only be specified with one patch')

    if options.update and not crt_series.get_current():
        raise CmdException('No patches applied')

    if commit_id:
        # Try to guess a patch name if the argument was <branch>:<patch>
        try:
            patchname = args[0].split(':')[1]
        except IndexError:
            patchname = None
        __pick_commit(commit_id, patchname, options)
    else:
        if options.unapplied:
            patches.reverse()
        for patch in patches:
            __pick_commit(git_id(remote_series, patch), patch, options)

    print_crt_patch(crt_series)
Example #3
0
def _main():
    """The main function
    """
    global prog

    sys.argv = list(map(fsdecode_utf8, sys.argv))

    prog = os.path.basename(sys.argv[0])

    if len(sys.argv) < 2:
        print('usage: %s <command>' % prog, file=sys.stderr)
        print('  Try "%s --help" for a list of supported commands' % prog,
              file=sys.stderr)
        sys.exit(utils.STGIT_GENERAL_ERROR)

    cmd = sys.argv[1]

    if cmd in ['-h', '--help']:
        if len(sys.argv) >= 3:
            cmd = commands.canonical_cmd(sys.argv[2])
            sys.argv[2] = '--help'
        else:
            print_help()
            sys.exit(utils.STGIT_SUCCESS)
    if cmd == 'help':
        if len(sys.argv) == 3 and not sys.argv[2] in ['-h', '--help']:
            cmd = commands.canonical_cmd(sys.argv[2])
            sys.argv[0] += ' %s' % cmd
            command = commands[cmd]
            parser = argparse.make_option_parser(command)
            if is_cmd_alias(command):
                parser.remove_option('-h')
            pager(parser.format_help().encode())
        else:
            print_help()
        sys.exit(utils.STGIT_SUCCESS)
    if cmd in ['-v', '--version', 'version']:
        from stgit.version import get_version

        print('Stacked GIT %s' % get_version())
        os.system('git --version')
        print('Python version %s' % sys.version)
        sys.exit(utils.STGIT_SUCCESS)
    if cmd in ['copyright']:
        print(__copyright__)
        sys.exit(utils.STGIT_SUCCESS)

    # re-build the command line arguments
    cmd = commands.canonical_cmd(cmd)
    sys.argv[0] += ' %s' % cmd
    del sys.argv[1]

    command = commands[cmd]
    if is_cmd_alias(command):
        sys.exit(command.func(sys.argv[1:]))

    parser = argparse.make_option_parser(command)
    directory = command.directory

    # These modules are only used from this point onwards and do not
    # need to be imported earlier
    try:
        from configparser import ParsingError, NoSectionError
    except ImportError:
        from ConfigParser import ParsingError, NoSectionError
    from stgit.exception import StgException
    from stgit.config import config_setup
    from stgit.stack import Series

    try:
        debug_level = int(environ_get('STGIT_DEBUG_LEVEL', 0))
    except ValueError:
        out.error('Invalid STGIT_DEBUG_LEVEL environment variable')
        sys.exit(utils.STGIT_GENERAL_ERROR)

    try:
        (options, args) = parser.parse_args()
        directory.setup()
        config_setup()

        # Some commands don't (always) need an initialized series.
        if directory.needs_current_series:
            if hasattr(options, 'branch') and options.branch:
                command.crt_series = Series(options.branch)
            else:
                command.crt_series = Series()

        ret = command.func(parser, options, args)
    except (StgException, IOError, ParsingError, NoSectionError) as err:
        directory.write_log(cmd)
        if debug_level > 0:
            traceback.print_exc(file=sys.stderr)
        out.error(str(err), title='%s %s' % (prog, cmd))
        sys.exit(utils.STGIT_COMMAND_ERROR)
    except SystemExit:
        # Triggered by the option parser when it finds bad commandline
        # parameters.
        sys.exit(utils.STGIT_COMMAND_ERROR)
    except KeyboardInterrupt:
        sys.exit(utils.STGIT_GENERAL_ERROR)
    except BaseException:
        out.error('Unhandled exception:')
        traceback.print_exc(file=sys.stderr)
        sys.exit(utils.STGIT_BUG_ERROR)

    directory.write_log(cmd)
    sys.exit(ret or utils.STGIT_SUCCESS)
Example #4
0
def __pick_commit(commit_id, patchname, options):
    """Pick a commit id.
    """
    commit = git.Commit(commit_id)

    if options.name:
        patchname = options.name
    elif patchname and options.revert:
        patchname = 'revert-' + patchname
    if patchname:
        patchname = find_patch_name(patchname, crt_series.patch_exists)

    if options.parent:
        parent = git_id(crt_series, options.parent)
    else:
        parent = commit.get_parent()

    if not options.revert:
        bottom = parent
        top = commit_id
    else:
        bottom = commit_id
        top = parent

    if options.fold:
        out.start('Folding commit %s' % commit_id)

        # try a direct git apply first
        if not git.apply_diff(bottom, top, files = options.file):
            if options.file:
                raise CmdException('Patch folding failed')
            else:
                git.merge_recursive(bottom, git.get_head(), top)

        out.done()
    elif options.update:
        rev1 = git_id(crt_series, 'HEAD^')
        rev2 = git_id(crt_series, 'HEAD')
        files = git.barefiles(rev1, rev2).split('\n')

        out.start('Updating with commit %s' % commit_id)

        if not git.apply_diff(bottom, top, files = files):
            raise CmdException, 'Patch updating failed'

        out.done()
    else:
        message = commit.get_log()
        if options.revert:
            if message:
                lines = message.splitlines()
                subject = lines[0]
                body = '\n'.join(lines[2:])
            else:
                subject = commit.get_id_hash()
                body = ''
            message = 'Revert "%s"\n\nThis reverts commit %s.\n\n%s\n' \
                    % (subject, commit.get_id_hash(), body)
        elif options.expose:
            message += '(imported from commit %s)\n' % commit.get_id_hash()
        author_name, author_email, author_date = \
                     name_email_date(commit.get_author())
        if options.revert:
            author_name = author_email = None

        out.start('Importing commit %s' % commit_id)

        newpatch = crt_series.new_patch(patchname, message = message, can_edit = False,
                                        unapplied = True, bottom = bottom, top = top,
                                        author_name = author_name,
                                        author_email = author_email,
                                        author_date = author_date)
        # in case the patch name was automatically generated
        patchname = newpatch.get_name()

        # find a patchlog to fork from
        refbranchname, refpatchname = parse_rev(patchname)
        if refpatchname:
            if refbranchname:
                # assume the refseries is OK, since we already resolved
                # commit_str to a git_id
                refseries = Series(refbranchname)
            else:
                refseries = crt_series
            patch = refseries.get_patch(refpatchname)
            if patch.get_log():
                out.info("Log was %s" % newpatch.get_log())
                out.info("Setting log to %s\n" %  patch.get_log())
                newpatch.set_log(patch.get_log())
                out.info("Log is now %s" % newpatch.get_log())
            else:
                out.info("No log for %s\n" % patchname)

        if not options.unapplied:
            modified = crt_series.push_patch(patchname)
        else:
            modified = False

        if crt_series.empty_patch(patchname):
            out.done('empty patch')
        elif modified:
            out.done('modified')
        else:
            out.done()
Example #5
0
def main():
    """The main function
    """
    global prog

    prog = os.path.basename(sys.argv[0])

    if len(sys.argv) < 2:
        print >> sys.stderr, 'usage: %s <command>' % prog
        print >> sys.stderr, \
              '  Try "%s --help" for a list of supported commands' % prog
        sys.exit(1)

    cmd = sys.argv[1]

    if cmd in ['-h', '--help']:
        if len(sys.argv) >= 3:
            cmd = commands.canonical_cmd(sys.argv[2])
            sys.argv[2] = '--help'
        else:
            print_help()
            sys.exit(0)
    if cmd == 'help':
        if len(sys.argv) == 3 and not sys.argv[2] in ['-h', '--help']:
            cmd = commands.canonical_cmd(sys.argv[2])
            if not cmd in commands:
                out.error('%s help: "%s" command unknown' % (prog, cmd))
                sys.exit(1)

            sys.argv[0] += ' %s' % cmd
            command = commands[cmd]
            parser = OptionParser(usage = command.usage,
                                  option_list = command.options)
            from pydoc import pager
            pager(parser.format_help())
        else:
            print_help()
        sys.exit(0)
    if cmd in ['-v', '--version', 'version']:
        from stgit.version import version
        print 'Stacked GIT %s' % version
        os.system('git --version')
        print 'Python version %s' % sys.version
        sys.exit(0)
    if cmd in ['copyright']:
        print __copyright__
        sys.exit(0)

    # re-build the command line arguments
    cmd = commands.canonical_cmd(cmd)
    sys.argv[0] += ' %s' % cmd
    del(sys.argv[1])

    command = commands[cmd]
    usage = command.usage.split('\n')[0].strip()
    parser = OptionParser(usage = usage, option_list = command.options)
    options, args = parser.parse_args()

    # These modules are only used from this point onwards and do not
    # need to be imported earlier
    from stgit.config import config_setup
    from ConfigParser import ParsingError, NoSectionError
    from stgit.stack import Series, StackException
    from stgit.git import GitException
    from stgit.commands.common import CmdException
    from stgit.gitmergeonefile import GitMergeException
    from stgit.utils import EditorException

    try:
        debug_level = int(os.environ['STGIT_DEBUG_LEVEL'])
    except KeyError:
        debug_level = 0
    except ValueError:
        out.error('Invalid STGIT_DEBUG_LEVEL environment variable')
        sys.exit(1)

    try:
        config_setup()

        # 'clone' doesn't expect an already initialised GIT tree. A Series
        # object will be created after the GIT tree is cloned
        if cmd != 'clone':
            if hasattr(options, 'branch') and options.branch:
                command.crt_series = Series(options.branch)
            else:
                command.crt_series = Series()
            stgit.commands.common.crt_series = command.crt_series

        command.func(parser, options, args)
    except (IOError, ParsingError, NoSectionError, CmdException,
            StackException, GitException, GitMergeException,
            EditorException), err:
        print >> sys.stderr, '%s %s: %s' % (prog, cmd, err)
        if debug_level:
            raise
        else:
            sys.exit(2)
Example #6
0
def __pick_commit(commit_id, patchname, options):
    """Pick a commit id.
    """
    commit = git.Commit(commit_id)

    if options.name:
        patchname = options.name
    elif patchname and options.revert:
        patchname = 'revert-' + patchname
    if patchname:
        patchname = find_patch_name(patchname, crt_series.patch_exists)

    if options.parent:
        parent = git_id(crt_series, options.parent)
    else:
        parent = commit.get_parent()

    if not options.revert:
        bottom = parent
        top = commit_id
    else:
        bottom = commit_id
        top = parent

    if options.fold:
        out.start('Folding commit %s' % commit_id)

        # try a direct git apply first
        if not git.apply_diff(bottom, top, files=options.file):
            if options.file:
                raise CmdException('Patch folding failed')
            else:
                git.merge_recursive(bottom, git.get_head(), top)

        out.done()
    elif options.update:
        rev1 = git_id(crt_series, 'HEAD^')
        rev2 = git_id(crt_series, 'HEAD')
        files = git.barefiles(rev1, rev2).split('\n')

        out.start('Updating with commit %s' % commit_id)

        if not git.apply_diff(bottom, top, files=files):
            raise CmdException('Patch updating failed')

        out.done()
    else:
        message = commit.get_log()
        if options.revert:
            if message:
                lines = message.splitlines()
                subject = lines[0]
                body = '\n'.join(lines[2:])
            else:
                subject = commit.get_id_hash()
                body = ''
            message = 'Revert "%s"\n\nThis reverts commit %s.\n\n%s\n' % (
                subject, commit.get_id_hash(), body)
        elif options.expose:
            if not message.endswith('\n'):
                message += '\n'
            message += '(imported from commit %s)\n' % commit.get_id_hash()
        (author_name, author_email,
         author_date) = name_email_date(commit.get_author())
        if options.revert:
            author_name = author_email = None

        out.start('Importing commit %s' % commit_id)

        newpatch = crt_series.new_patch(
            patchname,
            message=message,
            can_edit=False,
            unapplied=True,
            bottom=bottom,
            top=top,
            author_name=author_name,
            author_email=author_email,
            author_date=author_date,
        )
        # in case the patch name was automatically generated
        patchname = newpatch.get_name()

        # find a patchlog to fork from
        refbranchname, refpatchname = parse_rev(patchname)
        if refpatchname:
            if refbranchname:
                # assume the refseries is OK, since we already resolved
                # commit_str to a git_id
                refseries = Series(refbranchname)
            else:
                refseries = crt_series
            patch = refseries.get_patch(refpatchname)
            if patch.get_log():
                out.info("Log was %s" % newpatch.get_log())
                out.info("Setting log to %s\n" % patch.get_log())
                newpatch.set_log(patch.get_log())
                out.info("Log is now %s" % newpatch.get_log())
            else:
                out.info("No log for %s\n" % patchname)

        if not options.unapplied:
            modified = crt_series.push_patch(patchname)
        else:
            modified = False

        if crt_series.empty_patch(patchname):
            out.done('empty patch')
        elif modified:
            out.done('modified')
        else:
            out.done()
Example #7
0
def func(parser, options, args):
    """Import a commit object as a new patch
    """
    if len(args) != 1:
        parser.error('incorrect number of arguments')

    if not options.unapplied:
        check_local_changes()
        check_conflicts()
        check_head_top_equal()

    commit_str = args[0]
    commit_id = git_id(commit_str)
    commit = git.Commit(commit_id)

    if options.fold or options.update:
        if not crt_series.get_current():
            raise CmdException, 'No patches applied'
    else:
        patch_branch = commit_str.split('@')
        if options.name:
            patchname = options.name
        elif len(patch_branch) == 2:
            patchname = patch_branch[0]
        else:
            patchname = None

    if options.parent:
        parent = git_id(options.parent)
    else:
        parent = commit.get_parent()

    if not options.reverse:
        bottom = parent
        top = commit_id
    else:
        bottom = commit_id
        top = parent

    if options.fold:
        out.start('Folding commit %s' % commit_id)

        # try a direct git-apply first
        if not git.apply_diff(bottom, top):
            git.merge(bottom, git.get_head(), top, recursive = True)

        out.done()
    elif options.update:
        rev1 = git_id('//bottom')
        rev2 = git_id('//top')
        files = git.barefiles(rev1, rev2).split('\n')

        out.start('Updating with commit %s' % commit_id)

        if not git.apply_diff(bottom, top, files = files):
            raise CmdException, 'Patch updating failed'

        out.done()
    else:
        message = commit.get_log()
        if options.expose:
            message += '(imported from commit %s)\n' % commit.get_id_hash()
        author_name, author_email, author_date = \
                     name_email_date(commit.get_author())

        out.start('Importing commit %s' % commit_id)

        newpatch = crt_series.new_patch(patchname, message = message, can_edit = False,
                                        unapplied = True, bottom = bottom, top = top,
                                        author_name = author_name,
                                        author_email = author_email,
                                        author_date = author_date)
        # in case the patch name was automatically generated
        patchname = newpatch.get_name()

        # find a patchlog to fork from
        (refpatchname, refbranchname, refpatchid) = parse_rev(commit_str)
        if refpatchname and not refpatchid and \
               (not refpatchid or refpatchid == 'top'):
            # FIXME: should also support picking //top.old
            if refbranchname:
                # assume the refseries is OK, since we already resolved
                # commit_str to a git_id
                refseries = Series(refbranchname)
            else:
                refseries = crt_series
            patch = refseries.get_patch(refpatchname)
            if patch.get_log():
                out.info("Log was %s" % newpatch.get_log())
                out.info("Setting log to %s\n" %  patch.get_log())
                newpatch.set_log(patch.get_log())
                out.info("Log is now %s" % newpatch.get_log())
            else:
                out.info("No log for %s\n" % patchname)

        if not options.unapplied:
            modified = crt_series.push_patch(patchname)
        else:
            modified = False

        if crt_series.empty_patch(patchname):
            out.done('empty patch')
        elif modified:
            out.done('modified')
        else:
            out.done()

    print_crt_patch()
Example #8
0
def func(parser, options, args):
    """Import a commit object as a new patch
    """
    if len(args) != 1:
        parser.error('incorrect number of arguments')

    if not options.unapplied:
        check_local_changes()
        check_conflicts()
        check_head_top_equal()

    commit_str = args[0]
    commit_id = git_id(commit_str)
    commit = git.Commit(commit_id)

    if options.fold or options.update:
        if not crt_series.get_current():
            raise CmdException, 'No patches applied'
    else:
        patch_branch = commit_str.split('@')
        if options.name:
            patchname = options.name
        elif len(patch_branch) == 2:
            patchname = patch_branch[0]
        else:
            patchname = None

    if options.parent:
        parent = git_id(options.parent)
    else:
        parent = commit.get_parent()

    if not options.reverse:
        bottom = parent
        top = commit_id
    else:
        bottom = commit_id
        top = parent

    if options.fold:
        out.start('Folding commit %s' % commit_id)

        # try a direct git-apply first
        if not git.apply_diff(bottom, top):
            git.merge(bottom, git.get_head(), top, recursive=True)

        out.done()
    elif options.update:
        rev1 = git_id('//bottom')
        rev2 = git_id('//top')
        files = git.barefiles(rev1, rev2).split('\n')

        out.start('Updating with commit %s' % commit_id)

        if not git.apply_diff(bottom, top, files=files):
            raise CmdException, 'Patch updating failed'

        out.done()
    else:
        message = commit.get_log()
        if options.expose:
            message += '(imported from commit %s)\n' % commit.get_id_hash()
        author_name, author_email, author_date = \
                     name_email_date(commit.get_author())

        out.start('Importing commit %s' % commit_id)

        newpatch = crt_series.new_patch(patchname,
                                        message=message,
                                        can_edit=False,
                                        unapplied=True,
                                        bottom=bottom,
                                        top=top,
                                        author_name=author_name,
                                        author_email=author_email,
                                        author_date=author_date)
        # in case the patch name was automatically generated
        patchname = newpatch.get_name()

        # find a patchlog to fork from
        (refpatchname, refbranchname, refpatchid) = parse_rev(commit_str)
        if refpatchname and not refpatchid and \
               (not refpatchid or refpatchid == 'top'):
            # FIXME: should also support picking //top.old
            if refbranchname:
                # assume the refseries is OK, since we already resolved
                # commit_str to a git_id
                refseries = Series(refbranchname)
            else:
                refseries = crt_series
            patch = refseries.get_patch(refpatchname)
            if patch.get_log():
                out.info("Log was %s" % newpatch.get_log())
                out.info("Setting log to %s\n" % patch.get_log())
                newpatch.set_log(patch.get_log())
                out.info("Log is now %s" % newpatch.get_log())
            else:
                out.info("No log for %s\n" % patchname)

        if not options.unapplied:
            modified = crt_series.push_patch(patchname)
        else:
            modified = False

        if crt_series.empty_patch(patchname):
            out.done('empty patch')
        elif modified:
            out.done('modified')
        else:
            out.done()

    print_crt_patch()