def merge_up(self, target_branch=None, feature_branch=None, delete=True, create=True):
timer = Timer()<EOL>repository_was_created = self.create()<EOL>revision_to_merge = None<EOL>if not target_branch:<EOL><INDENT>target_branch = self.current_branch<EOL>if not target_branch:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT><DEDENT>feature_branch = coerce_feature_branch(feature_branch) if feature_branch else None<EOL>self.ensure_clean()<EOL>if not repository_was_created:<EOL><INDENT>self.pull()<EOL><DEDENT>logger.debug("<STR_LIT>", target_branch)<EOL>if target_branch in self.branches:<EOL><INDENT>self.checkout(revision=target_branch)<EOL>revision_to_merge = self.find_revision_id(target_branch)<EOL><DEDENT>elif not create:<EOL><INDENT>raise ValueError("<STR_LIT>" % target_branch)<EOL><DEDENT>elif self.compiled_filter.match(target_branch):<EOL><INDENT>self.create_release_branch(target_branch)<EOL><DEDENT>else:<EOL><INDENT>self.create_branch(target_branch)<EOL><DEDENT>if feature_branch:<EOL><INDENT>if feature_branch.location:<EOL><INDENT>self.pull(remote=feature_branch.location,<EOL>revision=feature_branch.revision)<EOL><DEDENT>revision_to_merge = self.find_revision_id(feature_branch.revision)<EOL>self.merge(revision=feature_branch.revision)<EOL>self.commit(message="<STR_LIT>" % feature_branch.expression)<EOL><DEDENT>if target_branch != self.default_revision:<EOL><INDENT>release_branches = [release.revision.branch for release in self.ordered_releases]<EOL>logger.debug("<STR_LIT>",<EOL>pluralize(len(release_branches), "<STR_LIT>", "<STR_LIT>"),<EOL>concatenate(release_branches))<EOL>later_branches = release_branches[release_branches.index(target_branch) + <NUM_LIT:1>:]<EOL>logger.info("<STR_LIT>",<EOL>pluralize(len(later_branches), "<STR_LIT>", "<STR_LIT>"),<EOL>target_branch,<EOL>concatenate(later_branches))<EOL>branches_to_upmerge = later_branches + [self.default_revision]<EOL>logger.info("<STR_LIT>",<EOL>target_branch,<EOL>pluralize(len(branches_to_upmerge), "<STR_LIT>", "<STR_LIT>"),<EOL>concatenate(branches_to_upmerge))<EOL>merge_queue = [target_branch] + branches_to_upmerge<EOL>while len(merge_queue) >= <NUM_LIT:2>:<EOL><INDENT>from_branch = merge_queue[<NUM_LIT:0>]<EOL>to_branch = merge_queue[<NUM_LIT:1>]<EOL>logger.info("<STR_LIT>", from_branch, to_branch)<EOL>self.checkout(revision=to_branch)<EOL>self.merge(revision=from_branch)<EOL>self.commit(message="<STR_LIT>" % from_branch)<EOL>merge_queue.pop(<NUM_LIT:0>)<EOL><DEDENT><DEDENT>if delete and feature_branch and self.is_feature_branch(feature_branch.revision):<EOL><INDENT>self.delete_branch(<EOL>branch_name=feature_branch.revision,<EOL>message="<STR_LIT>" % feature_branch.revision,<EOL>)<EOL>self.checkout()<EOL><DEDENT>logger.info("<STR_LIT>", timer)<EOL>return revision_to_merge<EOL>
Merge a change into one or more release branches and the default branch.

:param target_branch: The name of the release branch where merging of
                      the feature branch starts (a string or
                      :data:`None`, defaults to
                      :attr:`current_branch`).
:param feature_branch: The feature branch to merge in (any value
                       accepted by :func:`coerce_feature_branch()`).
:param delete: :data:`True` (the default) to delete or close the
               feature branch after it is merged, :data:`False`
               otherwise.
:param create: :data:`True` to automatically create the target branch
               when it doesn't exist yet, :data:`False` otherwise.
:returns: If `feature_branch` is given the global revision id of the
          feature branch is returned, otherwise the global revision id
          of the target branch (before any merges performed by
          :func:`merge_up()`) is returned. If the target branch is
          created by :func:`merge_up()` and `feature_branch` isn't
          given then :data:`None` is returned.
:raises: The following exceptions can be raised:

         - :exc:`~exceptions.TypeError` when `target_branch` and
           :attr:`current_branch` are both :data:`None`.
         - :exc:`~exceptions.ValueError` when the given target branch
           doesn't exist (based on :attr:`branches`) and `create` is
           :data:`False`.
         - :exc:`~executor.ExternalCommandFailed` if a command fails.