---
title: "How to land agent changes in one step: rebase, test and push · Cork"
description: "Land AI agent commits in one step: fetch, rebase onto teammates' work, rerun tests and push, using a script, a pre-push hook or a merge queue."
canonical: "https://corkcli.com/blog/land-agent-changes-rebase-test-push"
last_updated: "2026-10-03"
published: "2026-10-03"
author: "Kevin Vera"
---

# How to land agent changes in one step: rebase, test and push

Land AI agent commits in one step: fetch, rebase onto teammates' work, rerun tests and push, using a script, a pre-push hook or a merge queue.

By Kevin Vera · October 3, 2026 · [Guides](https://corkcli.com/blog/c/guides) · 6 min read

To land an agent's changes in one step, wrap three things into a single command: rebase the agent's commits onto the latest shared branch, rerun the tests on the rebased result, and push only if they pass. When several agents push to the same branch, the push often fails as non-fast-forward because someone landed first; the fix is to loop (fetch, rebase, test, push) until the push succeeds or a real conflict or failing test needs attention. Doing this in a script, not in the agent's conversation, saves turns and makes every landing identical.

## Why landing is the bottleneck with many agents

With one developer, `git pull --rebase && git push` is a habit. With five agents pushing to one origin, it becomes a race. Git only allows fast-forward updates to a branch by default, so every agent that finished second gets a rejected push, has to fetch, rebase, rerun tests, and try again, often while a third agent lands in the meantime. An agent doing this by hand spends several model turns per retry, re-reading output and deciding what to do, and it may skip the test rerun because its own tests passed a minute ago. Those skipped reruns are how code that compiled on each branch breaks on main: one agent renamed a function, another added a new caller of the old name, and both branches were green.

## The manual sequence

The underlying steps are plain git:

```bash
git fetch origin
git rebase origin/main          # replay your commits on top of everyone else's
npm test                        # rerun the tests on the combined code
git push origin HEAD:main       # push only if the tests passed
```

Useful options:

- `git pull --rebase` (or `git config pull.rebase true`) fetches and rebases in one command instead of merging.
- `git rebase --autostash` stashes uncommitted changes before the rebase and reapplies them after. Use it with care: the git docs warn the final stash application can produce non-trivial conflicts.
- `git rebase --exec "npm test" origin/main` runs a command after each replayed commit and stops the rebase at the first failure, which pinpoints the commit that broke.
- `git config rerere.enabled true` records how you resolved a conflict and reapplies that resolution when the same conflict comes back, which happens often when agents retry landings.
- If you are updating a branch you already pushed and rewrote, use `git push --force-with-lease`, never `--force`. It only overwrites the remote ref if it is still where you expect, so you cannot silently erase a commit a teammate pushed while you were rebasing.

## A one-step landing script

Put the loop in a script that agents call instead of `git push`:

```bash
#!/usr/bin/env bash
# land.sh: rebase onto origin/main, test, push; retry on races
set -euo pipefail
BRANCH=main
for attempt in 1 2 3 4 5; do
  git fetch origin "$BRANCH"
  if ! git rebase "origin/$BRANCH"; then
    echo "Rebase conflict: resolve, then rerun land.sh" >&2
    exit 1
  fi
  if ! npm test; then
    echo "Tests fail on top of origin/$BRANCH: fix before landing" >&2
    exit 1
  fi
  if git push origin "HEAD:$BRANCH"; then
    echo "Landed on attempt $attempt"
    exit 0
  fi
  echo "Push rejected (someone landed first), retrying" >&2
done
echo "Gave up after 5 attempts" >&2
exit 1
```

Then tell agents to use it. In `AGENTS.md` (read by Codex, and by Claude Code when there is no `CLAUDE.md`) or `CLAUDE.md`:

```markdown
To publish work, run ./land.sh. Never run git push directly.
If land.sh reports a conflict or failing test, fix it and run land.sh again.
```

The script's output is short and deterministic, so the agent spends one turn per landing instead of several.

## Enforce it with a pre-push hook

Instructions can be ignored. A git `pre-push` hook runs on every `git push` and aborts the push if it exits non-zero:

```bash
#!/usr/bin/env bash
# .git/hooks/pre-push
git fetch origin main --quiet
if ! git merge-base --is-ancestor origin/main HEAD; then
  echo "Not rebased onto origin/main. Run ./land.sh" >&2
  exit 1
fi
npm test
```

This catches pushes that skip the rebase or the tests, whoever runs them. You can also block direct `git push` in your agent's tool permissions or with a pre-tool hook (Claude Code, Codex and Cursor all support blocking a shell command from a hook by exiting with code 2).

## When to use a merge queue instead

If agents open pull requests instead of pushing to a shared branch, the server can do the landing. GitHub's merge queue merges pull requests into a busy branch one at a time, in order, after checking that each passes required checks on top of the changes ahead of it, so the branch is never broken by incompatible changes. GitHub Actions workflows must trigger on the `merge_group` event for this to work. A merge queue is the right choice when every change needs human review anyway; a landing script fits when agents push small, tested commits directly and you want them on main within seconds.

## How Cork helps

Cork turns `git push` into this one step. With Cork's hooks installed, a push rebases onto teammates' commits, reruns the tests, and pushes, so the retry loop happens outside the model and the agent does not spend turns on it. Cork also reduces how often landing fails in the first place: a write gate holds an edit against code another agent is changing right now until your agent has their version, and a teammate's rename or signature change becomes a [semantic lint](https://corkcli.com/blog/semantic-lint) rule your agents are checked against, so stale callers are caught before the push. In Cork's published benchmark (12 Claude Code agents at once on one repository, hard tasks), agents with Cork used 53% fewer tokens than the same agents without it.

Cork is the [coordination layer](https://corkcli.com/blog/coordination-layer-ai-coding-agents) for multiplayer coding agents: it keeps Claude Code, Codex and Cursor agents, on one machine or across a team's machines, from overwriting each other on one codebase, and hands each agent what the others already learned.

```bash
curl -fsSL https://corkcli.com/install.sh | sh
```

## Frequently asked questions

### Why does git push fail when several agents work on one branch?

Git only fast-forwards a branch by default. If another agent pushed first, your branch is behind, and the push is rejected until you fetch and rebase or merge.

### Should agents use git push --force?

No. If an agent must overwrite a branch it rewrote, use `--force-with-lease`, which refuses when the remote moved since you last fetched.

### Do I need to rerun tests after a clean rebase?

Yes. A rebase with no textual conflicts can still break the build, for example when another agent renamed a function your new code calls.

### Merge queue or landing script?

Use a merge queue when changes go through pull request review. Use a landing script when agents push small commits directly to a shared branch.

## Sources

- <https://git-scm.com/docs/git-push>
- <https://git-scm.com/docs/git-pull>
- <https://git-scm.com/docs/git-rebase>
- <https://git-scm.com/docs/git-rerere>
- <https://git-scm.com/docs/githooks>
- <https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue>
- <https://learn.chatgpt.com/docs/agent-configuration/agents-md>
- <https://code.claude.com/docs/en/memory>

## Related reading

- [Landing: rebase, test and push in one step for AI coding agents](https://corkcli.com/blog/landing-rebase-test-push): Landing means getting finished work onto the shared branch in one step: rebase onto everyone else's commits, rerun the tests, then push only if they pass.
- [Trunk-based development with AI coding agents](https://corkcli.com/blog/trunk-based-development-ai-coding-agents): Trunk-based development when AI coding agents write much of the code: short-lived agent branches, daily merges, feature flags, rebase-test-push, merge queues.
- [Blast radius: how to know what a code change breaks before you make it](https://corkcli.com/blog/blast-radius-code-change): Find a code change's blast radius before you make it: callers via LSP and git grep, dependents with Nx or Turborepo, history, tests, and teammates' work.
- [Pre-commit checks for code written by AI agents](https://corkcli.com/blog/pre-commit-checks-ai-generated-code): Pre-commit checks for AI-written code: git hooks, the pre-commit framework, secret scanning, and agent hooks in Claude Code, Codex and Cursor.

[All articles](https://corkcli.com/blog.md) · [Cork in Markdown](https://corkcli.com/index.md) · [llms.txt](https://corkcli.com/llms.txt)

This page in HTML: https://corkcli.com/blog/land-agent-changes-rebase-test-push
