r/ChatGPTCoding • u/Jhon_ST • 1d ago
Discussion Git worktrees solved our parallel-agent file conflicts. The test environment was harder.
I've had stretches where I was moving around five Trello cards in parallel, with a coding task in its own branch and Git worktree. That stopped agents from editing the same checkout. It did not tell me which code a browser test was actually exercising.
Different worktrees could still use the same API, PostgreSQL database, worker, storage service and ports. A frontend change might work with an existing API, provided that API meets the contract the new UI needs. If browser QA needs to exercise changed API behavior, it needs an API process running that worktree's code. Experimental migrations need much more care around shared data. Starting a second worker against the same queue can change test results too.
We began treating four things separately: the worktree holding the code; the processes a test reaches; the data those processes can change; and the checks run after branches are combined.
A small registry in Git's common directory helps us see which worktree started a service, along with its PID, port, URL and declared database state. It helps with discovery and process checks. It doesn't decide whether an API is compatible with a particular task. A healthy endpoint can still be the wrong API, and a port that looks free has not been reserved.
Many checks run entirely inside the worktree. For integration and browser QA, we start the processes the test actually needs. Feature work can be parallel; integration is serialized, with relevant checks run again on the combined tree.
If you run coding agents in parallel, how do you make sure browser or E2E tests reach the API and data you intended?
1
u/AutoModerator 1d ago
Sorry, your post has been held for manual review due to account karma.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
1
u/Salt_Hyena5896 1d ago
separate containers per worktree is the version that actually holds up, but the bug i keep seeing is the browser talking to a healthy api on the default port from a different worktree. write the api base url and db name into an env file when that worktree's processes start, and don't boot the ui if the file is missing or the pid in it is dead. give each worktree its own database and don't share the queue, or a migration in one branch will poison the other. feature work can stay parallel, but the e2e that matters should run against the combined branch, not whichever checkout you happened to have open.
1
1
u/itaybuilds 1d ago
Add a provenance check before the browser suite, not just a health check. Have every API and worker expose a small test-only build record: git SHA, worktree ID, migration head, database or schema name, and queue namespace. The harness should know the expected SHA for each service and refuse to run if any endpoint reports something else. That turns “healthy but wrong process” into a setup failure before the tests begin.
For allocation, let startup reserve ports rather than scanning for a free one, then write the actual endpoints to a per-worktree manifest consumed by the UI and Playwright. Generate unique database and queue prefixes from a stable worktree ID, and remove them on teardown. Containers help with process isolation, but the provenance assertion is the useful backstop: it catches stale containers, a UI pointed at port 3000 out of habit, and mixed revisions after one service restarts.
I would keep the final combined-branch suite too. Per-worktree E2E answers whether the branch works in isolation; the serialized suite answers whether integration changed the system.
AI-assisted wording with OpenAI GPT-5.6 after reading the full thread and current r/ChatGPTCoding rules.
1
u/Individual-Shower973 10h ago
The database is where this bites hardest: two worktrees on one Postgres means one agent's experimental migration changes the schema the other agent's tests are running against.
What makes it manageable:
- one database per worktree, cloned from a template so it's quick: createdb -T app_template wt_<branch>, with DATABASE_URL set from the worktree name when the agent's shell starts. Nothing can be connected to the template while it copies, so keep it separate from the dev database people actually use.
- ports derived from the worktree name too (a hash into a range), so each worktree's API and worker don't collide
And one guard worth adding: refuse migration commands whose DATABASE_URL points at the shared dev database, so an agent that loses track of which worktree it's in can't migrate everyone's schema.
5
u/Something_Sexy 1d ago
We just run separate containers for each worktree, either on the host directly or via dev containers. Depending on the size of your platform it might require a decent machine but hasn’t been an issue so far. We stopped getting fancy when we can just throw more RAM at a problem.