Пример #1
0
    def push_patch(self, name):
        """Pushes a patch on the stack
        """
        unapplied = self.get_unapplied()
        assert(name in unapplied)

        patch = self.get_patch(name)

        head = git.get_head()
        bottom = patch.get_bottom()
        top = patch.get_top()
        # top != bottom always since we have a commit for each patch

        if head == bottom:
            # A fast-forward push. Just reset the backup
            # information. No need for logging
            patch.set_top(top, backup = True)

            git.switch(top)
            append_string(self.__applied_file, name)

            unapplied.remove(name)
            write_strings(self.__unapplied_file, unapplied)
            return False

        # Need to create a new commit an merge in the old patch
        ex = None
        modified = False

        # Try the fast applying first. If this fails, fall back to the
        # three-way merge
        if not git.apply_diff(bottom, top):
            # if git.apply_diff() fails, the patch requires a diff3
            # merge and can be reported as modified
            modified = True

            # merge can fail but the patch needs to be pushed
            try:
                git.merge_recursive(bottom, head, top)
            except git.GitException, ex:
                out.error('The merge failed during "push".',
                          'Revert the operation with "stg undo".')
Пример #2
0
    def push_patch(self, name):
        """Pushes a patch on the stack
        """
        unapplied = self.get_unapplied()
        assert(name in unapplied)

        patch = self.get_patch(name)

        head = git.get_head()
        bottom = patch.get_bottom()
        top = patch.get_top()
        # top != bottom always since we have a commit for each patch

        if head == bottom:
            # A fast-forward push. Just reset the backup
            # information. No need for logging
            patch.set_top(top, backup = True)

            git.switch(top)
            append_string(self.__applied_file, name)

            unapplied.remove(name)
            write_strings(self.__unapplied_file, unapplied)
            return False

        # Need to create a new commit an merge in the old patch
        ex = None
        modified = False

        # Try the fast applying first. If this fails, fall back to the
        # three-way merge
        if not git.apply_diff(bottom, top):
            # if git.apply_diff() fails, the patch requires a diff3
            # merge and can be reported as modified
            modified = True

            # merge can fail but the patch needs to be pushed
            try:
                git.merge_recursive(bottom, head, top)
            except git.GitException:
                out.error('The merge failed during "push".',
                          'Revert the operation with "stg undo".')

        append_string(self.__applied_file, name)

        unapplied.remove(name)
        write_strings(self.__unapplied_file, unapplied)

        if not ex:
            # if the merge was OK and no conflicts, just refresh the patch
            # The GIT cache was already updated by the merge operation
            if modified:
                log = 'push(m)'
            else:
                log = 'push'
            self.refresh_patch(bottom = head, cache_update = False, log = log)
        else:
            # we make the patch empty, with the merged state in the
            # working tree.
            self.refresh_patch(bottom = head, cache_update = False,
                               empty = True, log = 'push(c)')
            raise StackException(str(ex))

        return modified
Пример #3
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()
Пример #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:
            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()
Пример #5
0
    def push_patch(self, name):
        """Pushes a patch on the stack
        """
        unapplied = self.get_unapplied()
        assert(name in unapplied)

        patch = self.get_patch(name)

        head = git.get_head()
        bottom = patch.get_bottom()
        top = patch.get_top()
        # top != bottom always since we have a commit for each patch

        if head == bottom:
            # A fast-forward push. Just reset the backup
            # information. No need for logging
            patch.set_top(top, backup=True)

            git.switch(top)
            append_string(self.__applied_file, name)

            unapplied.remove(name)
            write_strings(self.__unapplied_file, unapplied)
            return False

        # Need to create a new commit an merge in the old patch
        ex = None
        modified = False

        # Try the fast applying first. If this fails, fall back to the
        # three-way merge
        if not git.apply_diff(bottom, top):
            # if git.apply_diff() fails, the patch requires a diff3
            # merge and can be reported as modified
            modified = True

            # merge can fail but the patch needs to be pushed
            try:
                git.merge_recursive(bottom, head, top)
            except git.GitException:
                out.error('The merge failed during "push".',
                          'Revert the operation with "stg undo".')

        append_string(self.__applied_file, name)

        unapplied.remove(name)
        write_strings(self.__unapplied_file, unapplied)

        if not ex:
            # if the merge was OK and no conflicts, just refresh the patch
            # The GIT cache was already updated by the merge operation
            if modified:
                log = 'push(m)'
            else:
                log = 'push'
            self.refresh_patch(bottom=head, cache_update=False, log=log)
        else:
            # we make the patch empty, with the merged state in the
            # working tree.
            self.refresh_patch(
                bottom=head,
                cache_update=False,
                empty=True,
                log='push(c)',
            )
            raise StackException(str(ex))

        return modified
Пример #6
0
def __branch_merge_patch(remote_series, pname):
    """Merge a patch from a remote branch into the current tree.
    """
    patch = remote_series.get_patch(pname)
    git.merge_recursive(patch.get_bottom(), git.get_head(), patch.get_top())
Пример #7
0
def __branch_merge_patch(remote_series, pname):
    """Merge a patch from a remote branch into the current tree.
    """
    patch = remote_series.get_patch(pname)
    git.merge_recursive(patch.get_bottom(), git.get_head(), patch.get_top())