How to fix The command git fetch --depth=50 origin +refs/pull/123/merge: exited with 128 in Git

GitINTERMEDIATEMEDIUMUpdated Dec 6, 2025ยท 195 views

The 'git fetch --depth=50 origin +refs/pull/X/merge exited with 128' error occurs in CI/CD pipelines when Git cannot find the pull request merge reference. This typically happens when a PR is merged or closed before the build completes.

Quick fix

Fixes The command git fetch --depth=50 origin +refs/pull/123/merge: exited with 128

# In your .travis.yml, add branch protection awareness
branches:
  only:
    - main
    - master
    - /^v\d+\.\d+(\.\d+)?(-\S*)?$/
  1. Wait for CI builds to complete before merging
  2. Build the base branch instead of restarting failed PR builds
  3. Increase git clone depth for shallow clones
  4. Use the head SHA instead of merge ref for PR builds
git โ€” error
# In your .travis.yml, add branch protection awareness
branches:
only:
- main
- master
- /^v\d+\.\d+(\.\d+)?(-\S*)?$/
The command git fetch --depth=50 origin +refs/pull/123/merge: exited with 128

What this error means

The "git fetch --depth=50 origin +refs/pull/X/merge: exited with 128" error indicates that Git failed with a fatal error (exit code 128) while trying to fetch a pull request merge reference from the remote repository. When CI/CD platforms like Travis CI, GitHub Actions, or Jenkins build pull requests, they fetch a special merge commit reference (refs/pull/X/merge) that represents the result of merging the PR branch into the base branch. This reference is temporary and managed by the Git hosting provider (GitHub, GitLab, Bitbucket). Exit code 128 in Git signifies a fatal error, and in this context, it means "fatal: Couldn't find remote ref refs/pull/X/merge". The merge reference doesn't exist because: - The PR was merged or closed, causing GitHub to delete the merge ref - There was a race condition between merging and the CI build starting - The PR branch was force-pushed, invalidating the previous merge ref - The repository's PR merge refs were not fetched due to shallow clone depth limitations

Typical symptoms

  • CI/CD build fails during the Git fetch or checkout step
  • Error message contains 'exited with 128' and mentions refs/pull/X/merge
  • Build worked previously for the same PR but suddenly fails
  • Error occurs after merging or closing a pull request
  • Restarted builds for merged PRs consistently fail with this error
  • Multiple retry attempts all fail with the same error
  • The error appears specifically for pull request builds, not branch builds

Common causes

  1. Pull request was merged before the CI build completed (most common)
  2. Pull request was closed or abandoned after build was triggered
  3. Force push to the PR branch invalidated the merge reference
  4. Race condition between merge button click and CI job start
  5. Shallow clone depth doesn't include the merge commit
  6. GitHub/GitLab temporarily unavailable when creating merge ref
  7. Repository permissions changed during the build process
  8. Network timeout during ref advertisement from the server

How to fix "The command git fetch --depth=50 origin +refs/pull/123/merge: exited with 128"

1Wait for CI builds to complete before merging

The most reliable prevention is to wait for all CI jobs to finish before clicking the merge button:

yaml
# In your .travis.yml, add branch protection awareness
branches:
  only:
    - main
    - master
    - /^v\d+\.\d+(\.\d+)?(-\S*)?$/

Best practices:
- Enable "Require status checks to pass before merging" in GitHub branch protection
- Wait for the green checkmark before merging
- Don't restart builds for already-merged PRs

2Build the base branch instead of restarting failed PR builds

If a PR was merged and you need to verify the build, trigger a build on the base branch instead:

Travis CI:
1. Go to your Travis CI dashboard
2. Navigate to the repository
3. Click "More options" > "Trigger build"
4. Select your base branch (main/master)
5. Click "Trigger custom build"

GitHub Actions:
If using GitHub Actions, the push event to main will automatically trigger a new build.

yaml
# Example workflow that builds on push to main
on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]
3Increase git clone depth for shallow clones

Sometimes increasing the clone depth helps when merge refs are further back in history:

yaml
# .travis.yml
git:
  depth: 100  # Increase from default 50

# Or disable shallow cloning entirely (slower but more reliable)
git:
  depth: false

For GitHub Actions:

yaml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0  # Fetch all history

For GitLab CI:

yaml
variables:
  GIT_DEPTH: 0  # Full clone
4Use the head SHA instead of merge ref for PR builds

Configure your CI to build the PR head commit instead of the merge commit:

yaml
# .travis.yml - build the PR branch directly
git:
  depth: 50

# Optionally, configure to not build merge commits
# This is controlled by Travis settings, not YAML

GitHub Actions approach:

yaml
- uses: actions/checkout@v4
  with:
    ref: ${{ github.event.pull_request.head.sha }}

This approach builds the PR branch tip rather than the merge result, which is more stable but doesn't test merge compatibility.

5Verify the PR still exists and is open

Before troubleshooting further, confirm the PR state:

bash
# Check if the PR merge ref exists
gh pr view 123 --json state,merged

# Or using git directly
git ls-remote origin refs/pull/123/merge
git ls-remote origin refs/pull/123/head

If the PR is merged:
- The refs/pull/X/merge ref will not exist
- The refs/pull/X/head ref may still exist temporarily

If the PR is open and the ref doesn't exist, there may be a temporary GitHub issue.

6Handle the error gracefully in CI scripts

Add error handling to your CI configuration for this specific scenario:

yaml
# .travis.yml with fallback
before_install:
  - |
    if ! git fetch origin +refs/pull/${TRAVIS_PULL_REQUEST}/merge: 2>/dev/null; then
      echo "Merge ref not found, PR may have been merged"
      if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then
        echo "Building head commit instead"
        git fetch origin +refs/pull/${TRAVIS_PULL_REQUEST}/head:
      fi
    fi

GitHub Actions with conditional:

yaml
- name: Checkout with fallback
  run: |
    git fetch origin +refs/pull/${{ github.event.number }}/merge: || \
    git fetch origin +refs/pull/${{ github.event.number }}/head:
7Check CI platform status and retry

If the PR is still open and the error persists, check for platform issues:

Check status pages:
- GitHub: https://www.githubstatus.com/
- Travis CI: https://www.traviscistatus.com/
- GitLab: https://status.gitlab.com/

Manual retry steps:
1. Wait 5-10 minutes for any temporary issues to resolve
2. Push an empty commit to trigger a new build:

bash
git commit --allow-empty -m "Trigger CI rebuild"
   git push

3. Or restart the build from the CI platform's web interface

8Configure branch protection to prevent race conditions

Set up GitHub branch protection to prevent merging before CI completes:

1. Go to Settings > Branches in your GitHub repository
2. Click Add rule or edit existing rule for your main branch
3. Enable these options:
- Require status checks to pass before merging
- Require branches to be up to date before merging
- Select your CI jobs as required status checks

This prevents the race condition where someone merges while CI is still running.

bash
# You can also use GitHub CLI to configure this
gh api repos/{owner}/{repo}/branches/main/protection -X PUT \
  -F required_status_checks='{"strict":true,"contexts":["continuous-integration/travis-ci/pr"]}'

Advanced notes

### Understanding Pull Request Refs

GitHub maintains several refs for each pull request:
- refs/pull/X/head - Points to the tip of the PR branch
- refs/pull/X/merge - A temporary merge commit combining the PR with the base branch

The merge ref is particularly useful because it tests what the code will look like after merging. However, this ref is deleted when:
- The PR is merged (the ref becomes the actual merge commit on the base branch)
- The PR is closed without merging
- The base branch is updated and the merge ref needs regeneration

### Exit Code 128 Explained

Git exit code 128 indicates a fatal error. In this context:
- The fetch operation started successfully
- Git contacted the remote and requested the ref
- The server responded that the ref doesn't exist
- Git treats a missing requested ref as a fatal error

### Shallow Clone Considerations

CI platforms use --depth=50 (shallow clone) by default for performance:

bash
# What Travis CI actually runs
git clone --depth=50 --branch=main https://github.com/user/repo.git
git fetch origin +refs/pull/123/merge:

The depth parameter affects how much history is available locally but doesn't affect whether the merge ref exists on the remote.

### Alternative: GitLab Merge Request Refs

GitLab uses a different ref scheme:
- refs/merge-requests/X/head - The MR source branch
- refs/merge-requests/X/merge - The merge result (if merge is possible)

GitLab keeps merge refs available longer than GitHub in some cases.

### Debugging Ref Availability

To debug which refs are available:

bash
# List all pull request refs
git ls-remote origin 'refs/pull/*'

# Check a specific PR
git ls-remote origin refs/pull/123/head refs/pull/123/merge

# In CI, log available refs
git fetch --dry-run origin '+refs/pull/*:refs/pull/*' 2>&1

### Race Condition Timeline

Typical race condition scenario:
1. T+0s: Developer clicks merge button
2. T+1s: CI job starts (was queued)
3. T+2s: GitHub processes merge, deletes refs/pull/X/merge
4. T+5s: CI job tries to fetch refs/pull/X/merge
5. T+5s: Error - ref doesn't exist

Frequently asked questions

What does "The command git fetch --depth=50 origin +refs/pull/123/merge: exited w" mean?
The "git fetch --depth=50 origin +refs/pull/X/merge: exited with 128" error indicates that Git failed with a fatal error (exit code 128) while trying to fetch a pull request merge reference from the remote repository. When CI/CD platforms like Travis CI, GitHub Actions, or Jenkins build pull requests, they fetch a special merge commit reference (refs/pull/X/merge) that represents the result of merging the PR branch into the base branch. This reference is temporary and managed by the Git hosting provider (GitHub, GitLab, Bitbucket).
How do I fix "The command git fetch --depth=50 origin +refs/pull/123/merge: exited w"?
The 'git fetch --depth=50 origin +refs/pull/X/merge exited with 128' error occurs in CI/CD pipelines when Git cannot find the pull request merge reference. This typically happens when a PR is merged or closed before the build completes.
What causes "The command git fetch --depth=50 origin +refs/pull/123/merge: exited w"?
Pull request was merged before the CI build completed (most common) Pull request was closed or abandoned after build was triggered Force push to the PR branch invalidated the merge reference
Is the "The command git fetch --depth=50 origin +refs/pull/123/merge: exited w" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading