# git rebase --onto: Transplant a Range of Commits

> git rebase --onto <newbase> <upstream> <branch> moves a slice of commits onto a new base, the precise tool for dropping or relocating commits. Reference and CI errors.

Source: https://latchkey.dev/learn/command-reference/git-rebase-onto  
Updated: 2026-06-30

git rebase --onto <newbase> <upstream> [<branch>] replays only the commits in upstream..branch onto newbase, letting you relocate or excise a precise range.

The three-argument form of rebase is the one people forget. It separates "what to replay" (upstream..branch) from "where to put it" (newbase), which is how you drop the lower commits of a branch or move a feature onto a different base.

## What it does

git rebase --onto A B C takes the commits reachable from C but not from B and replays them on top of A, then moves the branch ref to the new tip. Setting A and B to different commits is what lets you skip the commits between them, effectively removing them from history.

## Common usage

```Terminal
# move feature (based on develop) onto main instead
git rebase --onto main develop feature
# drop the bottom 3 commits of the current branch
git rebase --onto HEAD~3 HEAD~1
# replay just one commit onto a release branch
git rebase --onto release-1.0 abc1234~1 abc1234
```

## Options

| Argument / flag | What it does |
| --- | --- |
| <newbase> | Commit the range is replayed on top of |
| <upstream> | Exclusive lower bound: commits after this are replayed |
| <branch> | Branch (or HEAD) whose commits are replayed |
| --continue | Resume after resolving a conflict |
| --abort | Cancel and restore the original branch |
| --committer-date-is-author-date | Preserve author dates as committer dates |

## In CI

Rebase rewrites SHAs, so a later push needs --force-with-lease, which CI tokens may be blocked from doing on protected branches. Prefer rebase --onto in throwaway worktrees for building, not for pushing to shared branches. A shallow clone may lack <upstream>; fetch enough depth first.

## Common errors in CI

"fatal: invalid upstream 'develop'" means the ref is missing locally (shallow clone or never fetched). "error: could not apply <sha>" is a conflict; resolve and --continue or --abort. "There is no tracking information for the current branch" appears if you omit arguments and rely on upstream that is not set.

## Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

```.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached
```

> `git rev-parse --abbrev-ref HEAD` returns the literal string `HEAD` on a detached checkout rather than a branch name. On GitHub Actions read `github.ref_name` instead; the git command cannot know what it was checked out for.

## FAQ

### git rebase --onto: Transplant a Range of Commits?

The three-argument form of rebase is the one people forget. It separates "what to replay" (upstream..branch) from "where to put it" (newbase), which is how you drop the lower commits of a branch or move a feature onto a different base.

### What it does?

git rebase --onto A B C takes the commits reachable from C but not from B and replays them on top of A, then moves the branch ref to the new tip. Setting A and B to different commits is what lets you skip the commits between them, effectively removing them from history.

### In CI?

Rebase rewrites SHAs, so a later push needs --force-with-lease, which CI tokens may be blocked from doing on protected branches. Prefer rebase --onto in throwaway worktrees for building, not for pushing to shared branches. A shallow clone may lack <upstream>; fetch enough depth first.

### Common errors in CI?

"fatal: invalid upstream 'develop'" means the ref is missing locally (shallow clone or never fetched). "error: could not apply <sha>" is a conflict; resolve and --continue or --abort. "There is no tracking information for the current branch" appears if you omit arguments and rely on upstream that is not set.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
