# How to Push Commits Back to a Repository After Using actions/checkout

> Learn how to push commits back to a repository after using actions/checkout. Set up Git identity and use git commands with the embedded GITHUB_TOKEN.

- Repository: [GitHub Actions/checkout](https://github.com/actions/checkout)
- Tags: how-to-guide
- Published: 2026-07-16

---

**To push commits back after using `actions/checkout`, configure a Git identity and use standard `git` commands, leveraging the automatically persisted `GITHUB_TOKEN` that the action embeds in the remote URL.**

The `actions/checkout` action creates a fully functional Git repository in your workflow runner, enabling subsequent steps to modify source files and push changes back to GitHub. When you use the action with default settings, it automatically persists the `GITHUB_TOKEN` in the remote configuration via [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts), eliminating the need for manual authentication setup. This allows you to treat the checked-out repository exactly like a local clone where you can commit and push changes programmatically.

## How actions/checkout Handles Authentication

By default, `actions/checkout@v4` runs with `persist-credentials: true` as defined in [`action.yml`](https://github.com/actions/checkout/blob/main/action.yml). This setting instructs the action to store the authentication token in the Git remote URL, formatted as `https://x-access-token:<TOKEN>@github.com/...`. The [`src/main.ts`](https://github.com/actions/checkout/blob/main/src/main.ts) file orchestrates this process by calling [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts) to construct the authenticated remote URL, while [`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) parses the input parameters including the `token` and `persist-credentials` options.

When credential persistence is enabled, the repository is ready for authenticated operations immediately after checkout. You do not need to manually provide credentials when pushing, as the token is already embedded in the remote configuration.

## Step-by-Step: Push Commits Back to the Repository

Pushing commits requires three specific steps after the checkout action completes.

### Configure Git Identity

Git requires a `user.name` and `user.email` to create commits, which `actions/checkout` does **not** set automatically. You must configure these using `git config` before committing:

```yaml
- name: Configure Git
  run: |
    git config user.name "${{ github.actor }}"
    git config user.email "${{ github.actor }}@users.noreply.github.com"

```

### Execute Git Commands

Once the identity is configured, use standard Git commands to stage, commit, and push changes. Because the token is persisted in the remote URL, the push succeeds without additional authentication:

```yaml
- name: Commit and push
  run: |
    git add .
    git commit -m "Automated update"
    git push

```

## Complete Workflow Examples

### Example 1: Push Directly to the Same Branch

This workflow appends a timestamp to [`README.md`](https://github.com/actions/checkout/blob/main/README.md) and pushes directly to the branch that triggered the workflow:

```yaml
name: Update README

on:
  workflow_dispatch:

jobs:
  update-readme:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Configure Git
        run: |
          git config user.name "${{ github.actor }}"
          git config user.email "${{ github.actor }}@users.noreply.github.com"

      - name: Append timestamp
        run: |
          echo "\nUpdated on $(date)" >> README.md

      - name: Commit and push
        run: |
          git add README.md
          git commit -m "Update README with timestamp"
          git push

```

### Example 2: Create a Pull Request with Changes

This workflow creates a new branch, pushes formatting changes, and opens a pull request:

```yaml
name: Auto-format code

on:
  push:
    branches:
      - main

jobs:
  format:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Git identity
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

      - name: Run prettier
        run: npx prettier --write .

      - name: Commit and push
        env:
          BRANCH: format-${{ github.run_id }}
        run: |
          git checkout -b $BRANCH
          git add .
          git commit -m "Apply prettier formatting"
          git push --set-upstream origin $BRANCH

      - name: Create PR
        uses: peter-evans/create-pull-request@v5
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          branch: ${{ env.BRANCH }}
          title: "Auto-format with Prettier"
          body: "This PR was created by a workflow."

```

### Example 3: Push to a Different Repository Using a PAT

To push to a repository other than the one checked out, use a Personal Access Token (PAT) and disable the default credential persistence:

```yaml
- uses: actions/checkout@v4
  with:
    token: ${{ secrets.PAT_REPO_WRITE }}
    persist-credentials: false

- name: Set remote with PAT
  run: |
    git remote set-url origin https://x-access-token:${{ secrets.PAT_REPO_WRITE }}@github.com/owner/target-repo.git

- name: Configure Git and push
  run: |
    git config user.name "github-actions[bot]"
    git config user.email "github-actions[bot]@users.noreply.github.com"
    # ... make changes, commit, and push ...

```

## Key Implementation Files in actions/checkout

Understanding the source code helps explain why this workflow behaves as it does:

- **[`action.yml`](https://github.com/actions/checkout/blob/main/action.yml)**: Declares the `token` and `persist-credentials` inputs, with the default value of `persist-credentials` set to `true`.
- **[`src/main.ts`](https://github.com/actions/checkout/blob/main/src/main.ts)**: Contains the core execution logic that initializes the repository and invokes the authentication helper.
- **[`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts)**: Implements the logic that constructs the authenticated remote URL using the provided token.
- **[`src/input-helper.ts`](https://github.com/actions/checkout/blob/main/src/input-helper.ts)**: Parses workflow inputs including `token` and `persist-credentials`, passing them to the main execution context.

## Summary

- **`actions/checkout`** persists the `GITHUB_TOKEN` in the remote URL by default, enabling authenticated pushes without manual credential configuration.
- You must manually configure **Git identity** (`user.name` and `user.email`) before committing, as the action does not set these values.
- Use standard **`git add`**, **`git commit`**, and **`git push`** commands to push changes back to the repository.
- To push to a different repository, provide a **Personal Access Token (PAT)** via the `token` input and set `persist-credentials: false`, then manually configure the remote URL.

## Frequently Asked Questions

### Does actions/checkout automatically configure Git user.name and user.email?

No. While `actions/checkout` handles repository authentication, it does not set Git identity configurations. You must explicitly run `git config user.name` and `git config user.email` before creating commits, otherwise Git will error with "Author identity unknown".

### Why does pushing fail when I set persist-credentials: false?

When you disable credential persistence, the action does not embed the token in the remote URL. According to the implementation in [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts), the authenticated remote URL is only configured when `persist-credentials` is `true`. Without this, you must manually set the remote URL with a token or use SSH keys to authenticate the push.

### Can I push to a repository different from the one checked out?

Yes. Provide a Personal Access Token with write access to the target repository via the `token` input, and optionally set `persist-credentials: false`. Then use `git remote set-url` to point to the target repository URL, including the token in the format `https://x-access-token:<TOKEN>@github.com/owner/repo.git`.

### What permissions does the GITHUB_TOKEN need to push commits?

The default `GITHUB_TOKEN` provided to workflows has sufficient permissions to push to the same repository, provided the workflow job has `contents: write` permissions. If pushing to a different repository, you must use a Personal Access Token with appropriate repository scopes, as the built-in `GITHUB_TOKEN` is scoped only to the current repository.