---
title: Merge
description: Automate the merging of your pull requests.
---

The `merge` action allows Mergify to automatically merge pull requests when
certain conditions are met. This can significantly streamline your workflow by
reducing the need for manual intervention.

Whatever your conditions are, Mergify might inject extra conditions for the
merge action to take place:

- Mergify always respects the [branch protection settings](#branch-protection-conditions)

- Mergify always respect [pull request dependencies](#pull-request-dependencies)

- Mergify always respect the [merge date](#merge-date)

- Mergify allows merging pull request modifying its configuration file by
  default. But Mergify will always check whether these changes are
  valid or not, to avoid merging broken configurations.

## Branch Protection Conditions

Mergify automatically reads your GitHub branch protections and rulesets and
injects them as merge conditions. For example, if you require at least one
approved review, Mergify injects the `#approved-reviews-by >= 1` condition.

<Image src={branchProtectionConditionsScreenshot} alt="Mergify Branch Protection Condition Injection" />

For details on how injection works, which ruleset rules are compatible,
known incompatibilities, and how to configure bypass actors, see
[GitHub Rulesets Compatibility](/merge-queue/github-rulesets).

## Pull Request Dependencies

You can specify dependencies between pull requests from the same repository,
or from other repositories with Mergify installed within your organization.
Mergify waits for the linked pull requests to be merged before merging any pull
request with a `Depends-On:` header.

To use this feature, add the `Depends-On:` header to the body of your pull
request:

```text
New awesome feature 🎉

To get the full picture, you may need to look at these pull requests:

Depends-On: #42
Depends-On: https://github.com/organization/repository/pull/123
Depends-On: https://github.com/organization/other-repository/pull/456
Depends-On: organization/test-repository#789
```

In this example, the pull request will only be merged when the pull
request #42, #123, #456 from `other-repository` and #789 from
`test-repository` are merged.

:::caution
  If the dependency happens between pull requests targeting different branches,
  the evaluation of the dependent will not be automatic. You might need to use
  the [refresh](/commands/refresh) command to make Mergify realize the
  dependency has been merged.
:::

## Merge Date

You can specify a date after which you want a pull request to be merged with a
`Merge-After:` header. Mergify will wait for the date and time to be passed
before merging your pull request.

To use this feature, add the `Merge-After:` header to the body of your pull
request, followed by the date in the [timestamp
format](/configuration/data-types#timestamp).

For example, if a pull request body contains:

```text
Merge-After: 2023-04-18 18:20
```

The pull request will only be merged after April, 18th 2023 at 18:20 UTC, if
all other merge conditions are satisfied.

## Parameters

| Key name | Value type | Default | Description |
| --- | --- | --- | --- |
| `commit_message_format` | CommitMessageFormatModel or null | `null` | Declarative commit message format configuration. Use this instead of the Jinja2 `commit_message_template` for the common merge-commit shapes. Mutually exclusive with `commit_message_template` on the same rule. |
| `commit_message_template` | template or null | `null` | Template to use as the commit message when using the merge or squash merge method. |
| `merge_bot_account` | template or null | `null` | Mergify can impersonate a GitHub user to merge pull requests. If no `merge_bot_account` is set, Mergify merges the pull request itself. The user account **must** have already been logged in Mergify dashboard once and have **write** or **maintain** permission. |
| `method` | `merge` or `rebase` or `squash` or `fast-forward` or null | `null` | Merge method to use. If no value is set, Mergify uses the first authorized method available in the repository configuration. |

## Examples

### Automatic Merge

In this example, Mergify will automatically merge (using the squash method) any
pull request that has passed its CI checks and has at least 2 approved reviews.

```yaml
pull_request_rules:
  - name: automatic merge when CI checks pass and at least 2 approved reviews
    conditions:
      - check-success = test
      - "#approved-reviews-by >= 2"
    actions:
      merge:
        method: squash
```

### Customizing the Commit Message

When merging with the `merge` or `squash` method, the
`commit_message_format` setting controls the title, body, and trailers
of the resulting commit:

```yaml
commit_message_format:
  title: inherit            # inherit | pr-title              (default: inherit)
  body:  inherit            # inherit | pr-body | empty       (default: inherit)
  trailers: []              # subset of [co-authored-by, approved-by, merged-by]
```

`commit_message_format` is accepted under `queue_rules`,
`actions.merge`, and `defaults`. Omit it to let your repository's GitHub
settings render the entire commit.

#### Title

- `inherit` (default): Mergify does not send a title; your repository
  settings render it.

- `pr-title`: use the pull request title with the PR number appended:
  `{title} (#{number})`.

#### Body

- `inherit` (default): Mergify does not send a body; your repository
  settings render it.

- `pr-body`: use the pull request description.

- `empty`: produce an empty body. Useful when you only want trailers.

#### Trailers

`trailers` is an ordered list. Mergify appends one trailer block to the
commit body, separated by a blank line:

| Value | Source | Format |
| ----- | ------ | ------ |
| `co-authored-by` | PR commit authors, deduplicated by email | `Co-authored-by: <name> <email>` |
| `approved-by` | Approving reviewers | `Approved-by: <login> <id+login@users.noreply.github.com>` |
| `merged-by` | Mergify identity | `Merged-by: Mergify <bot-id+mergify[bot]@users.noreply.github.com>` |

All three follow the canonical kernel-style `Name <email>` shape and
are parseable by `git interpret-trailers`. `Co-authored-by` continues
to render as a co-author badge in the GitHub UI.

#### Validation

- `commit_message_format` and `commit_message_template` cannot be set
  on the same rule.

- `body: inherit` cannot be combined with non-empty `trailers`,
  because Mergify must not override the body to append trailers.

:::caution
  When `body` is set to `pr-body` or `empty`, Mergify always sends a
  body to GitHub's merge API. This overrides your repository's
  `squash_merge_commit_message` and `merge_commit_message` settings
  for the affected merges.
:::

#### Sample Configurations

GitHub-style commit, with the pull request title in the subject and the
pull request description as the body:

```yaml
pull_request_rules:
  - name: automatic merge when CI checks pass and at least 2 approved reviews
    conditions:
      - check-success = test
      - "#approved-reviews-by >= 2"
    actions:
      merge:
        method: squash
        commit_message_format:
          title: pr-title
          body: pr-body
```

Merging a pull request titled "Fix some bug" with the description "This
fixes some bug I found while testing the app." produces:

```text
Fix some bug (#123)

This fixes some bug I found while testing the app.
```

The remaining variants show only the `commit_message_format` block;
nest it under `actions.merge`, `queue_rules[]`, or `defaults`.

Title only, no body content:

```yaml
commit_message_format:
  title: pr-title
  body: empty
```

Pull request description plus an `Approved-by:` trailer block:

```yaml
commit_message_format:
  title: pr-title
  body: pr-body
  trailers:
    - approved-by
```

resulting in:

```text
Fix some bug (#123)

This fixes some bug I found while testing the app.

Approved-by: jdoe <12345+jdoe@users.noreply.github.com>
Approved-by: jsmith <67890+jsmith@users.noreply.github.com>
```

Trailer-only commit, useful when you want every merge to carry a
`Merged-by:` line and nothing else:

```yaml
commit_message_format:
  title: pr-title
  body: empty
  trailers:
    - merged-by
```

### Migrating from `commit_message_template`

The legacy `commit_message_template` setting is a
[template](/configuration/data-types#template) that renders the entire
commit message. `commit_message_format` covers the common patterns
declaratively, with predictable output and no template engine.

Most existing templates map directly:

| `commit_message_template` | `commit_message_format` equivalent |
| ------------------------- | ---------------------------------- |
| `{{ title }} (#{{ number }})\n\n{{ body }}` | `title: pr-title`, `body: pr-body` |
| `{{ title }} (#{{ number }})` | `title: pr-title`, `body: empty` |
| `{{ title }}\n\n{{ body }}` | `title: inherit`, `body: pr-body` |
| `Merge pull request #N from owner/branch` (the GitHub default) | omit `commit_message_format` entirely |

For example, this template that appends an `Approved-by:` line per
reviewer:

```yaml
commit_message_template: |
  {{ title }} (#{{ number }})

  {{ body }}

  {% for user in approved_reviews_by %}
  Approved-by: {{ user }}
  {% endfor %}
```

becomes:

```yaml
commit_message_format:
  title: pr-title
  body: pr-body
  trailers:
    - approved-by
```
