DEV Community

Cover image for Run Claude Code, Codex and Antigravity CLI on One Repo Without Merge Hell
Gabriel Anhaia
Gabriel Anhaia

Posted on

Run Claude Code, Codex and Antigravity CLI on One Repo Without Merge Hell


The suite went red, and both agents had reported back as done.
Claude Code had the flaky login test. Codex, in a second terminal on
the same checkout, had the auth cleanup.

Codex tidied src/login.js while Claude was halfway through fixing
it. One agent read a file the other had already changed, and neither
knew. Now you are reading one diff that two agents wrote at the same
time, with no record of which line came from whom.

That is the merge hell here: agents overwriting each other in one
folder, and finding out late. There is a second kind, real conflicts
between two branches, and no tool makes those go away. Worktrees
don't fix that one. Step 4 is how you see it coming.

Step 1 is plain git, and steps 4 and 6 show the plain-git side too.
From step 2 on I use Hermes IDE, which I
build.

Step 1: one worktree per task

A worktree is an extra working folder attached to the same
repository. Each folder has its own branch checked out and its own
files on disk. They all share one .git history, so nothing is
cloned twice and a commit made in one folder is visible from the
others straight away.

On a throwaway repo called acme-api, with git 2.52, one worktree
for each of three tasks:

$ git worktree add -b hermes/fix-login ../fix-login
Preparing worktree (new branch 'hermes/fix-login')
HEAD is now at e00b40e Initial commit
$ git worktree add -b hermes/tidy-auth ../tidy-auth
Preparing worktree (new branch 'hermes/tidy-auth')
HEAD is now at e00b40e Initial commit
$ git worktree add -b hermes/rename-session ../rename-session
Preparing worktree (new branch 'hermes/rename-session')
HEAD is now at e00b40e Initial commit
$ git worktree list
/home/dev/acme-api        e00b40e [main]
/home/dev/fix-login       e00b40e [hermes/fix-login]
/home/dev/rename-session  e00b40e [hermes/rename-session]
/home/dev/tidy-auth       e00b40e [hermes/tidy-auth]
$ git branch --list 'hermes/*'
+ hermes/fix-login
+ hermes/rename-session
+ hermes/tidy-auth
Enter fullscreen mode Exit fullscreen mode

The + marks a branch that is checked out in another worktree. Git
refuses to check out the same branch in two folders at once, which
is the rule you want: each agent gets a branch nobody else can check
out.

Three agents on three branches of one repository, each working on its own leaf

Start Claude Code in ../fix-login, Codex in ../tidy-auth and
Antigravity CLI in ../rename-session, and they can no longer touch
each other's files. When the login fix is committed, compare it with
main using three dots. That shows only what the branch changed
since it split off, not what main did in the meantime:

$ git diff main...hermes/fix-login
diff --git a/src/login.js b/src/login.js
index 2b4c4e7..d2aa2a1 100644
--- a/src/login.js
+++ b/src/login.js
@@ -1,4 +1,4 @@
 export function login(user, pass) {
-  if (!user) return { ok: false };
-  return { ok: pass.length > 0 };
+  if (!user || !pass) return { ok: false };
+  return { ok: true };
 }
Enter fullscreen mode Exit fullscreen mode

Claude Code and Codex already do this for their own agents. Claude
Code's agent view (a
research preview) moves background sessions into a worktree under
.claude/worktrees/. Codex, in the ChatGPT desktop app, keeps its
worktrees in $CODEX_HOME/worktrees by default
(docs).
Both isolate their own agent well. Mix vendors and you get two
folders of worktrees, two status views, two review screens, and a
third agent, Antigravity CLI, started by hand in its own terminal.

Then there is the thing every first-time worktree user hits:

$ ls -a ../fix-login
.
..
.git
.gitignore
package.json
src
Enter fullscreen mode Exit fullscreen mode

No .env. No node_modules. A new worktree holds the tracked files
and nothing else, so anything git ignores stays behind in the main
folder. The agent starts, runs the tests and fails on a missing
database URL. Start a dev server in two worktrees and both reach for
port 3000.

Step 2: a recipe that prepares each worktree

Hermes reads a file called .hermes/worktree.toml from your repo and
runs it in every new task's worktree before the agent starts. This is
the example from the
recipe docs:

# .hermes/worktree.toml
setup = ["npm ci", "npm run build:types"]
copy = [".env", "apps/*/.env.local"]
done_when = ["npm test"]

[ports]
web = 3000
Enter fullscreen mode Exit fullscreen mode
  • setup runs in order inside the new worktree (sh on macOS and Linux, cmd on Windows). The first command that fails stops the rest, and the failure lands in the inbox.
  • copy brings files over from your project folder into the same place in the worktree. It only takes files git ignores. A pattern that matches a tracked file is refused as a whole, and setup doesn't run. Copying is for local secrets and caches, not for files that belong in a commit.
  • done_when is the default check for the task. More on that in step 6.
  • Each name under [ports] gets the first free port at or above its number that no other worktree was given. Setup commands see it as HERMES_PORT_WEB.

The first time Hermes sees the recipe, and again whenever it changes,
it shows you the commands and waits. Nothing runs until you choose
Run setup. Secret values in copied .env-style files (KEY=value
lines) are masked in the setup log, and that log is kept in memory
only. Commit .hermes/worktree.toml so every branch has it.

Two more things happen without a recipe. When a new worktree's
dependencies match the main checkout, they are ready in seconds
instead of a fresh install. And terminals in a new worktree get their
own block of ports as PORT, HERMES_PORT_BASE and
HERMES_PORT_COUNT, so a dev server that reads PORT stops fighting
over 3000.

Step 3: launch three agents and watch one inbox

Press ⌘N (Ctrl+Shift+N on Windows and Linux), type the task and press
Enter. The agent starts in a real terminal, on a new hermes/ branch,
in its own worktree, with the task as its first prompt. "Fix the
flaky login test" becomes hermes/fix-the-flaky-login-test, cut
from the branch you are on.

The ⌘N task launcher with the agent, project, branch, approval, model and effort chips, and the options panel open
Real Hermes window, test build with stand-in agents. The ⌘N launcher: agent, project, branch, approval, model and effort chips, with the options panel open.

The chips pick the agent and account, the project, the branch, the
approval mode, the model and the effort. Launch & next (⌘↵)
starts the task and keeps the sheet open, so you can switch the agent
chip and go again. Task A to Claude Code, task B to Codex, task C to
Antigravity CLI. Hermes remembers your usual combination per project,
and presets (⌘1, ⌘2 in the launcher) save the ones you reach for
often. You can also start the same task in two agents and keep the
better result.

The branches and worktrees are plain git. Stop using Hermes and
git worktree list still shows them, ready to merge by hand.

Why Antigravity CLI and not Gemini CLI? Hermes still lists Gemini
CLI, marked legacy: Google retired it for personal accounts, and
Antigravity CLI is its current agent. Each agent runs its own
interface, so the slash commands are the vendor's own, and so is the
sign-in. Your tokens stay with the vendor.

Hermes sidebar with Claude Code, Codex, Antigravity CLI and OpenCode sessions, each with its own status and hermes/ branch
From hermes-ide.com: a recreation of the 2.0 app with demo data. Claude Code, Codex, Antigravity CLI and OpenCode sessions, each with a status and its own hermes/ branch.

Three agents in three terminals means three places to check. Hermes
gives every session one status with no setup: working, needs
approval, asked you, done, error or idle. A status Hermes had to
guess is shown dimmed. Antigravity CLI has no launch flag that
accepts edits only, so unless you skip permissions entirely it asks
before every change. That agent will visit the inbox a lot.

The title bar counts the agents blocked on you. ⌘I (Ctrl+Shift+I on
Windows and Linux) jumps to the one that has waited longest, and you
answer in that agent's own terminal. Hermes never answers a
permission prompt for you and never types into a terminal on its
own. Notifications fire when an agent is blocked or done, and skip
the session you are looking at.

The attention inbox listing three agents waiting on approval, with a peek at the selected one
Real Hermes window, test build with stand-in agents. The attention inbox: three agents waiting on approval, oldest first, with a peek at the selected one.

Step 4: catch overlap before it is a conflict

Worktrees stop agents from overwriting each other's files on disk.
They do not stop two branches from editing the same lines. Same
throwaway repo: Codex's tidy-up also changed the first check in
login(). The login fix lands first, then the tidy-up:

$ git diff main...hermes/tidy-auth
diff --git a/src/login.js b/src/login.js
index 2b4c4e7..00e40bc 100644
--- a/src/login.js
+++ b/src/login.js
@@ -1,4 +1,4 @@
 export function login(user, pass) {
-  if (!user) return { ok: false };
+  if (!user?.trim()) return { ok: false };
   return { ok: pass.length > 0 };
 }
$ git merge --no-edit hermes/fix-login
Updating e00b40e..831fc5c
Fast-forward
 src/login.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
$ git merge --no-edit hermes/tidy-auth
Auto-merging src/login.js
CONFLICT (content): Merge conflict in src/login.js
Automatic merge failed; fix conflicts and then commit the result.
$ git merge --abort
$ git status --short
Enter fullscreen mode Exit fullscreen mode

git merge --abort puts main back at the login fix, and the
tidy-up waits on its own branch. With plain git you learn about the
clash at merge time, after both agents have finished.

Hermes watches each session's latest turns. When two sessions in the
same repository touched the same file, both get an overlap badge.
Hover it and it names the other session and the files, in the form
"Also changed in Session 2: src/login.js".

Two branches growing toward the same leaf, with a warning lantern where they would meet

That warning comes while the work is still cheap to sequence. Hold
one agent back, land the other, then ask the second to rebase onto
it. If you try to land and the merge would conflict, the Land sheet
says so and offers Ask agent to rebase instead of forcing it. The
conflict, if there is one, shows up in a rebase you started, before
both agents are done.

Step 5: review by turn, and comment to the right agent

Hermes saves every agent turn in git, including changes made by shell
commands, without touching your branch, your staging area or your
stash. A bar under the terminal gives you Diff and Restore for any
turn, with Undo.

⌘G (Ctrl+Shift+G on Windows and Linux) opens the Review Desk, where
you read changes by turn or by file. Risk flags mark lockfiles, CI
workflows, secrets, new binaries and edits to the agent's own config.
If Codex's tidy-up turn had also bumped package-lock.json, that
turn would carry a lockfile flag, and you could revert just that one
turn while keeping the rest of its work.

The Review Desk by turn, with a line comment addressed to Claude Code on turn T1 and a drafted commit message
From hermes-ide.com: a recreation of the 2.0 app with demo data. The Review Desk by turn, with a line comment for Claude Code and a drafted commit message.

A line comment goes back to the agent that wrote that line. The
comment on Codex's turn goes to Codex, so you don't paste it into
the wrong terminal.

Step 6: land, then clean up

Land does the last step in one sheet: commit, open a pull request, or
merge locally. It drafts the message from the turns and lands into the
branch the task started from.

The done_when commands from your recipe run at the end of each turn
and again before landing. In a Claude Code session, a failing check
sends Claude back to fix it, up to three times, through Claude Code's
own Stop hook rather than by typing into the terminal. For Codex,
Antigravity CLI and the other agents, the failing check shows as a
chip on the session with a Send failures back button. The
failures go to the agent when you click it. If checks are still
failing when you land, the sheet warns you and offers Land
anyway
. After landing, the sheet says "Landed." and offers Undo
that
.

By hand, cleanup is two commands per task. Same repo, after the login
fix landed:

$ git worktree remove ../fix-login
$ git branch -d hermes/fix-login
Deleted branch hermes/fix-login (was 831fc5c).
$ git worktree list
/home/dev/acme-api        831fc5c [main]
/home/dev/rename-session  e00b40e [hermes/rename-session]
/home/dev/tidy-auth       285b797 [hermes/tidy-auth]
Enter fullscreen mode Exit fullscreen mode

git worktree remove refuses to delete a folder with modified or
untracked files unless you add --force. Leave that flag off. The
tidy-up is still on its branch, waiting for its rebase.

In Hermes, closing a session with changes commits them to its branch
or archives them, instead of stashing. Since 2.1 it also cleans up
disk: rebuildable dependencies and build output go from task folders
unused for a week, and merged task folders with nothing uncommitted
are removed. By design it leaves any task with uncommitted or
unpushed work alone. Settings → Storage shows what it holds, and it
warns you when disk runs low.

By hand vs with Hermes

Job Plain git Hermes
Folder and branch per task git worktree add -b ⌘N, hermes/<task>
.env and local files Copy each time copy, ignored files only
Dependencies Install per worktree Ready in seconds if they match
Ports Pick one by hand PORT block, [ports]
Who is waiting Check every terminal Status, inbox, ⌘I
Same files touched Find out at merge overlap badge
Review git diff main...branch By turn, comments to the author
Merge and tidy git merge, worktree remove Land (checks run first), undo

What this setup doesn't do

Everything here runs on your machine, in worktrees. Hermes has no
cloud agents and no Docker isolation. If you want containers,
JetBrains Air
offers a Docker environment. If you want agents running on someone
else's hardware, Cursor, the Copilot cloud agent, Claude Code on the
web and Codex Cloud all do that.

If you only ever use one vendor, its own app's worktrees may be all
you need. Hermes isn't the only tool with a worktree recipe either.
Conductor
has "Files to copy" and setup scripts for its workspaces, for Claude
Code, Codex, Cursor and OpenCode on the Mac. And
Warp
and Zed run several CLI
agents too. I put them side by side, with where each one wins, in
Hermes IDE vs Cursor vs Warp vs Zed.


Try it on your repo

I build Hermes IDE. It is free, source-available under BSL 1.1, and
runs on macOS, Windows and Linux. Hermes 2.0 shipped on October 2,
2026, and 14 more releases followed by October 11.

Adapt the recipe above before you commit it. Its build:types step
is only an example, so put in your own install command, the ignored
files your app needs and your test command. Save it as
.hermes/worktree.toml, commit it, then press ⌘N (Ctrl+Shift+N)
twice: the same task, once to Claude Code and once to Codex (or any
two agents you use). Two agents on one task tend to touch the same
files, so the overlap badge is likely to show up within a few
turns.

Download Hermes IDE and, if it
saves you a merge, star the repo.
It's built in the open, and a star helps other developers find it.
If a step above doesn't behave the way I described, open an issue on
GitHub and tell me. If you're wondering whether you need another
subscription on top of the agents you pay for, I wrote
that one up too.

For the agent patterns underneath all this, my AI Agents Pocket
Guide
is the short read.

AI Agents Pocket Guide: Patterns for Building Autonomous Systems with LLMs

Top comments (0)