Exemplo n.º 1
0
Arquivo: stack.py Projeto: snits/stgit
    def log_patch(self, patch, message, notes = None):
        """Generate a log commit for a patch
        """
        top = git.get_commit(patch.get_top())
        old_log = patch.get_log()

        if message is None:
            # replace the current log entry
            if not old_log:
                raise StackException('No log entry to annotate for patch "%s"'
                                     % patch.get_name())
            replace = True
            log_commit = git.get_commit(old_log)
            msg = log_commit.get_log().split('\n')[0]
            log_parent = log_commit.get_parent()
            if log_parent:
                parents = [log_parent]
            else:
                parents = []
        else:
            # generate a new log entry
            replace = False
            msg = '%s\t%s' % (message, top.get_id_hash())
            if old_log:
                parents = [old_log]
            else:
                parents = []

        if notes:
            msg += '\n\n' + notes

        log = git.commit(message = msg, parents = parents,
                         cache_update = False, tree_id = top.get_tree(),
                         allowempty = True)
        patch.set_log(log)
Exemplo n.º 2
0
    def log_patch(self, patch, message):
        """Generate a log commit for a patch
        """
        top = git.get_commit(patch.get_top())
        old_log = patch.get_log()

        # generate a new log entry
        msg = '%s\t%s' % (message, top.get_id_hash())
        if old_log:
            parents = [old_log]
        else:
            parents = []

        log = git.commit(
            message=msg,
            parents=parents,
            cache_update=False,
            tree_id=top.get_tree(),
            allowempty=True,
        )
        patch.set_log(log)
Exemplo n.º 3
0
    def log_patch(self, patch, message, notes=None):
        """Generate a log commit for a patch
        """
        top = git.get_commit(patch.get_top())
        old_log = patch.get_log()

        if message is None:
            # replace the current log entry
            if not old_log:
                raise StackException, \
                      'No log entry to annotate for patch "%s"' \
                      % patch.get_name()
            replace = True
            log_commit = git.get_commit(old_log)
            msg = log_commit.get_log().split('\n')[0]
            log_parent = log_commit.get_parent()
            if log_parent:
                parents = [log_parent]
            else:
                parents = []
        else:
            # generate a new log entry
            replace = False
            msg = '%s\t%s' % (message, top.get_id_hash())
            if old_log:
                parents = [old_log]
            else:
                parents = []

        if notes:
            msg += '\n\n' + notes

        log = git.commit(message=msg,
                         parents=parents,
                         cache_update=False,
                         tree_id=top.get_tree(),
                         allowempty=True)
        patch.set_log(log)
Exemplo n.º 4
0
Arquivo: stack.py Projeto: snits/stgit
    def forward_patches(self, names):
        """Try to fast-forward an array of patches.

        On return, patches in names[0:returned_value] have been pushed on the
        stack. Apply the rest with push_patch
        """
        unapplied = self.get_unapplied()

        forwarded = 0
        top = git.get_head()

        for name in names:
            assert(name in unapplied)

            patch = self.get_patch(name)

            head = top
            bottom = patch.get_bottom()
            top = patch.get_top()

            # top != bottom always since we have a commit for each patch
            if head == bottom:
                # reset the backup information. No logging since the
                # patch hasn't changed
                patch.set_top(top, backup = True)

            else:
                head_tree = git.get_commit(head).get_tree()
                bottom_tree = git.get_commit(bottom).get_tree()
                if head_tree == bottom_tree:
                    # We must just reparent this patch and create a new commit
                    # for it
                    descr = patch.get_description()
                    author_name = patch.get_authname()
                    author_email = patch.get_authemail()
                    author_date = patch.get_authdate()
                    committer_name = patch.get_commname()
                    committer_email = patch.get_commemail()

                    top_tree = git.get_commit(top).get_tree()

                    top = git.commit(message = descr, parents = [head],
                                     cache_update = False,
                                     tree_id = top_tree,
                                     allowempty = True,
                                     author_name = author_name,
                                     author_email = author_email,
                                     author_date = author_date,
                                     committer_name = committer_name,
                                     committer_email = committer_email)

                    patch.set_top(top, backup = True)

                    self.log_patch(patch, 'push(f)')
                else:
                    top = head
                    # stop the fast-forwarding, must do a real merge
                    break

            forwarded+=1
            unapplied.remove(name)

        if forwarded == 0:
            return 0

        git.switch(top)

        append_strings(self.__applied_file, names[0:forwarded])
        write_strings(self.__unapplied_file, unapplied)

        return forwarded
Exemplo n.º 5
0
Arquivo: stack.py Projeto: snits/stgit
    def new_patch(self, name, message = None, can_edit = True,
                  unapplied = False, show_patch = False,
                  top = None, bottom = None, commit = True,
                  author_name = None, author_email = None, author_date = None,
                  committer_name = None, committer_email = None,
                  before_existing = False, sign_str = None):
        """Creates a new patch, either pointing to an existing commit object,
        or by creating a new commit object.
        """

        assert commit or (top and bottom)
        assert not before_existing or (top and bottom)
        assert not (commit and before_existing)
        assert (top and bottom) or (not top and not bottom)
        assert commit or (not top or (bottom == git.get_commit(top).get_parent()))

        if name is not None:
            self.__patch_name_valid(name)
            if self.patch_exists(name):
                raise StackException('Patch "%s" already exists' % name)

        # TODO: move this out of the stgit.stack module, it is really
        # for higher level commands to handle the user interaction
        def sign(msg):
            return add_sign_line(msg, sign_str,
                                 committer_name or git.committer().name,
                                 committer_email or git.committer().email)
        if not message and can_edit:
            descr = edit_file(
                self, sign(''),
                'Please enter the description for the patch above.',
                show_patch)
        else:
            descr = sign(message)

        head = git.get_head()

        if name is None:
            name = make_patch_name(descr, self.patch_exists)

        patch = self.get_patch(name)
        patch.create()

        patch.set_description(descr)
        patch.set_authname(author_name)
        patch.set_authemail(author_email)
        patch.set_authdate(author_date)
        patch.set_commname(committer_name)
        patch.set_commemail(committer_email)

        if before_existing:
            insert_string(self.__applied_file, patch.get_name())
        elif unapplied:
            patches = [patch.get_name()] + self.get_unapplied()
            write_strings(self.__unapplied_file, patches)
            set_head = False
        else:
            append_string(self.__applied_file, patch.get_name())
            set_head = True

        if commit:
            if top:
                top_commit = git.get_commit(top)
            else:
                bottom = head
                top_commit = git.get_commit(head)

            # create a commit for the patch (may be empty if top == bottom);
            # only commit on top of the current branch
            assert(unapplied or bottom == head)
            commit_id = git.commit(message = descr, parents = [bottom],
                                   cache_update = False,
                                   tree_id = top_commit.get_tree(),
                                   allowempty = True, set_head = set_head,
                                   author_name = author_name,
                                   author_email = author_email,
                                   author_date = author_date,
                                   committer_name = committer_name,
                                   committer_email = committer_email)
            # set the patch top to the new commit
            patch.set_top(commit_id)
        else:
            patch.set_top(top)

        self.log_patch(patch, 'new')

        return patch
Exemplo n.º 6
0
Arquivo: stack.py Projeto: snits/stgit
    def refresh_patch(self, files = None, message = None, edit = False,
                      empty = False,
                      show_patch = False,
                      cache_update = True,
                      author_name = None, author_email = None,
                      author_date = None,
                      committer_name = None, committer_email = None,
                      backup = True, sign_str = None, log = 'refresh',
                      notes = None, bottom = None):
        """Generates a new commit for the topmost patch
        """
        patch = self.get_current_patch()
        if not patch:
            raise StackException('No patches applied')

        descr = patch.get_description()
        if not (message or descr):
            edit = True
            descr = ''
        elif message:
            descr = message

        # TODO: move this out of the stgit.stack module, it is really
        # for higher level commands to handle the user interaction
        if not message and edit:
            descr = edit_file(self, descr.rstrip(), \
                              'Please edit the description for patch "%s" ' \
                              'above.' % patch.get_name(), show_patch)

        if not author_name:
            author_name = patch.get_authname()
        if not author_email:
            author_email = patch.get_authemail()
        if not committer_name:
            committer_name = patch.get_commname()
        if not committer_email:
            committer_email = patch.get_commemail()

        descr = add_sign_line(descr, sign_str, committer_name, committer_email)

        if not bottom:
            bottom = patch.get_bottom()

        if empty:
            tree_id = git.get_commit(bottom).get_tree()
        else:
            tree_id = None

        commit_id = git.commit(files = files,
                               message = descr, parents = [bottom],
                               cache_update = cache_update,
                               tree_id = tree_id,
                               set_head = True,
                               allowempty = True,
                               author_name = author_name,
                               author_email = author_email,
                               author_date = author_date,
                               committer_name = committer_name,
                               committer_email = committer_email)

        patch.set_top(commit_id, backup = backup)
        patch.set_description(descr)
        patch.set_authname(author_name)
        patch.set_authemail(author_email)
        patch.set_authdate(author_date)
        patch.set_commname(committer_name)
        patch.set_commemail(committer_email)

        if log:
            self.log_patch(patch, log, notes)

        return commit_id
Exemplo n.º 7
0
    def forward_patches(self, names):
        """Try to fast-forward an array of patches.

        On return, patches in names[0:returned_value] have been pushed on the
        stack. Apply the rest with push_patch
        """
        unapplied = self.get_unapplied()

        forwarded = 0
        top = git.get_head()

        for name in names:
            assert(name in unapplied)

            patch = self.get_patch(name)

            head = top
            bottom = patch.get_bottom()
            top = patch.get_top()

            # top != bottom always since we have a commit for each patch
            if head == bottom:
                # reset the backup information. No logging since the
                # patch hasn't changed
                patch.set_top(top, backup=True)

            else:
                head_tree = git.get_commit(head).get_tree()
                bottom_tree = git.get_commit(bottom).get_tree()
                if head_tree == bottom_tree:
                    # We must just reparent this patch and create a new commit
                    # for it
                    descr = patch.get_description()
                    author_name = patch.get_authname()
                    author_email = patch.get_authemail()
                    author_date = patch.get_authdate()
                    committer_name = patch.get_commname()
                    committer_email = patch.get_commemail()

                    top_tree = git.get_commit(top).get_tree()

                    top = git.commit(
                        message=descr,
                        parents=[head],
                        cache_update=False,
                        tree_id=top_tree,
                        allowempty=True,
                        author_name=author_name,
                        author_email=author_email,
                        author_date=author_date,
                        committer_name=committer_name,
                        committer_email=committer_email,
                    )

                    patch.set_top(top, backup=True)

                    self.log_patch(patch, 'push(f)')
                else:
                    top = head
                    # stop the fast-forwarding, must do a real merge
                    break

            forwarded += 1
            unapplied.remove(name)

        if forwarded == 0:
            return 0

        git.switch(top)

        append_strings(self.__applied_file, names[0:forwarded])
        write_strings(self.__unapplied_file, unapplied)

        return forwarded
Exemplo n.º 8
0
    def new_patch(
        self,
        name,
        message=None,
        can_edit=True,
        unapplied=False,
        show_patch=False,
        top=None,
        bottom=None,
        commit=True,
        author_name=None,
        author_email=None,
        author_date=None,
        committer_name=None,
        committer_email=None,
        sign_str=None,
    ):
        """Creates a new patch, either pointing to an existing commit object,
        or by creating a new commit object.
        """

        assert commit or (top and bottom)
        assert (top and bottom) or (not top and not bottom)
        assert commit or (
            not top
            or bottom == git.get_commit(top).get_parent()
        )

        if name is not None:
            self.__patch_name_valid(name)
            if self.patch_exists(name):
                raise StackException('Patch "%s" already exists' % name)

        # TODO: move this out of the stgit.stack module, it is really
        # for higher level commands to handle the user interaction
        def sign(msg):
            return add_sign_line(msg, sign_str,
                                 committer_name or git.committer().name,
                                 committer_email or git.committer().email)
        if not message and can_edit:
            descr = edit_file(
                self, sign(''),
                'Please enter the description for the patch above.',
                show_patch)
        else:
            descr = sign(message)

        head = git.get_head()

        if name is None:
            name = make_patch_name(descr, self.patch_exists)

        patch = self.get_patch(name)
        patch.create()

        patch.set_description(descr)
        patch.set_authname(author_name)
        patch.set_authemail(author_email)
        patch.set_authdate(author_date)
        patch.set_commname(committer_name)
        patch.set_commemail(committer_email)

        if unapplied:
            patches = [patch.get_name()] + self.get_unapplied()
            write_strings(self.__unapplied_file, patches)
            set_head = False
        else:
            append_string(self.__applied_file, patch.get_name())
            set_head = True

        if commit:
            if top:
                top_commit = git.get_commit(top)
            else:
                bottom = head
                top_commit = git.get_commit(head)

            # create a commit for the patch (may be empty if top == bottom);
            # only commit on top of the current branch
            assert(unapplied or bottom == head)
            commit_id = git.commit(
                message=descr,
                parents=[bottom],
                cache_update=False,
                tree_id=top_commit.get_tree(),
                allowempty=True,
                set_head=set_head,
                author_name=author_name,
                author_email=author_email,
                author_date=author_date,
                committer_name=committer_name,
                committer_email=committer_email,
            )
            # set the patch top to the new commit
            patch.set_top(commit_id)
        else:
            patch.set_top(top)

        self.log_patch(patch, 'new')

        return patch
Exemplo n.º 9
0
    def refresh_patch(
        self,
        files=None,
        message=None,
        edit=False,
        empty=False,
        show_patch=False,
        cache_update=True,
        author_name=None,
        author_email=None,
        author_date=None,
        committer_name=None,
        committer_email=None,
        backup=True,
        sign_str=None,
        log='refresh',
        notes=None,
        bottom=None
    ):
        """Generates a new commit for the topmost patch
        """
        patch = self.get_current_patch()
        if not patch:
            raise StackException('No patches applied')

        descr = patch.get_description()
        if not (message or descr):
            edit = True
            descr = ''
        elif message:
            descr = message

        # TODO: move this out of the stgit.stack module, it is really
        # for higher level commands to handle the user interaction
        if not message and edit:
            descr = edit_file(
                self,
                descr.rstrip(),
                'Please edit the description for patch "%s" above.' % (
                    patch.get_name(),
                    show_patch,
                )
            )

        if not author_name:
            author_name = patch.get_authname()
        if not author_email:
            author_email = patch.get_authemail()
        if not committer_name:
            committer_name = patch.get_commname()
        if not committer_email:
            committer_email = patch.get_commemail()

        descr = add_sign_line(descr, sign_str, committer_name, committer_email)

        if not bottom:
            bottom = patch.get_bottom()

        if empty:
            tree_id = git.get_commit(bottom).get_tree()
        else:
            tree_id = None

        commit_id = git.commit(
            files=files,
            message=descr,
            parents=[bottom],
            cache_update=cache_update,
            tree_id=tree_id,
            set_head=True,
            allowempty=True,
            author_name=author_name,
            author_email=author_email,
            author_date=author_date,
            committer_name=committer_name,
            committer_email=committer_email
        )

        patch.set_top(commit_id, backup=backup)
        patch.set_description(descr)
        patch.set_authname(author_name)
        patch.set_authemail(author_email)
        patch.set_authdate(author_date)
        patch.set_commname(committer_name)
        patch.set_commemail(committer_email)

        if log:
            self.log_patch(patch, log, notes)

        return commit_id
Exemplo n.º 10
0
    def new_patch(self,
                  name,
                  message=None,
                  can_edit=True,
                  unapplied=False,
                  show_patch=False,
                  top=None,
                  bottom=None,
                  commit=True,
                  author_name=None,
                  author_email=None,
                  author_date=None,
                  committer_name=None,
                  committer_email=None,
                  before_existing=False):
        """Creates a new patch
        """

        if name != None:
            self.__patch_name_valid(name)
            if self.patch_exists(name):
                raise StackException, 'Patch "%s" already exists' % name

        if not message and can_edit:
            descr = edit_file(
                self, None,
                'Please enter the description for the patch above.',
                show_patch)
        else:
            descr = message

        head = git.get_head()

        if name == None:
            name = make_patch_name(descr, self.patch_exists)

        patch = Patch(name, self.__patch_dir, self.__refs_dir)
        patch.create()

        if not bottom:
            bottom = head
        if not top:
            top = head

        patch.set_bottom(bottom)
        patch.set_top(top)
        patch.set_description(descr)
        patch.set_authname(author_name)
        patch.set_authemail(author_email)
        patch.set_authdate(author_date)
        patch.set_commname(committer_name)
        patch.set_commemail(committer_email)

        if before_existing:
            insert_string(self.__applied_file, patch.get_name())
            # no need to commit anything as the object is already
            # present (mainly used by 'uncommit')
            commit = False
        elif unapplied:
            patches = [patch.get_name()] + self.get_unapplied()
            write_strings(self.__unapplied_file, patches)
            set_head = False
        else:
            append_string(self.__applied_file, patch.get_name())
            set_head = True

        if commit:
            # create a commit for the patch (may be empty if top == bottom);
            # only commit on top of the current branch
            assert (unapplied or bottom == head)
            top_commit = git.get_commit(top)
            commit_id = git.commit(message=descr,
                                   parents=[bottom],
                                   cache_update=False,
                                   tree_id=top_commit.get_tree(),
                                   allowempty=True,
                                   set_head=set_head,
                                   author_name=author_name,
                                   author_email=author_email,
                                   author_date=author_date,
                                   committer_name=committer_name,
                                   committer_email=committer_email)
            # set the patch top to the new commit
            patch.set_top(commit_id)

        self.log_patch(patch, 'new')

        return patch
Exemplo n.º 11
0
    def refresh_patch(self,
                      files=None,
                      message=None,
                      edit=False,
                      show_patch=False,
                      cache_update=True,
                      author_name=None,
                      author_email=None,
                      author_date=None,
                      committer_name=None,
                      committer_email=None,
                      backup=False,
                      sign_str=None,
                      log='refresh',
                      notes=None):
        """Generates a new commit for the given patch
        """
        name = self.get_current()
        if not name:
            raise StackException, 'No patches applied'

        patch = Patch(name, self.__patch_dir, self.__refs_dir)

        descr = patch.get_description()
        if not (message or descr):
            edit = True
            descr = ''
        elif message:
            descr = message

        if not message and edit:
            descr = edit_file(self, descr.rstrip(), \
                              'Please edit the description for patch "%s" ' \
                              'above.' % name, show_patch)

        if not author_name:
            author_name = patch.get_authname()
        if not author_email:
            author_email = patch.get_authemail()
        if not author_date:
            author_date = patch.get_authdate()
        if not committer_name:
            committer_name = patch.get_commname()
        if not committer_email:
            committer_email = patch.get_commemail()

        if sign_str:
            descr = descr.rstrip()
            if descr.find("\nSigned-off-by:") < 0 \
               and descr.find("\nAcked-by:") < 0:
                descr = descr + "\n"

            descr = '%s\n%s: %s <%s>\n' % (descr, sign_str, committer_name,
                                           committer_email)

        bottom = patch.get_bottom()

        commit_id = git.commit(files=files,
                               message=descr,
                               parents=[bottom],
                               cache_update=cache_update,
                               allowempty=True,
                               author_name=author_name,
                               author_email=author_email,
                               author_date=author_date,
                               committer_name=committer_name,
                               committer_email=committer_email)

        patch.set_bottom(bottom, backup=backup)
        patch.set_top(commit_id, backup=backup)
        patch.set_description(descr)
        patch.set_authname(author_name)
        patch.set_authemail(author_email)
        patch.set_authdate(author_date)
        patch.set_commname(committer_name)
        patch.set_commemail(committer_email)

        if log:
            self.log_patch(patch, log, notes)

        return commit_id