{"slug": "two-terminals-one-pot-of-tea-parallel-claude-code-with-git-worktrees", "title": "Two Terminals, One Pot of Tea: Parallel Claude Code with Git Worktrees", "summary": "A developer combined Git worktrees with parallel Claude Code sessions to work on multiple features simultaneously without merge conflicts. By creating separate worktrees for each feature branch, they enabled independent AI-assisted development in isolated directories, avoiding the need for stashing or sequential workflows. The approach was tested on the peektea TUI file browser project, where two unrelated features were developed in parallel.", "body_md": "I had a lot of work to get through, and for once I didn't want to crawl through it one ticket at a time.\n\nI knew Claude Code could run a few sessions in parallel, so my first thought was just to turn a couple of agents loose on different things at once.\n\nBut then I hit my actual hangup: I don't merge code I haven't read.\n\nI like going through diffs properly, lately with [git-lrc](https://github.com/HexmosTech/git-lrc).\n\nSo the question became, how do I let a bunch of sessions work at the same time without all their changes piling up into one unreviewable mess on a single branch?\n\nBecause in a single checkout, everything is sequential by definition: work → review → commit → push → cut a new branch → start the whole thing over.\n\nOne task can't start until the last one is done.\n\nAnd if something interrupts you halfway through, you're back to the old muscle memory: stash, checkout main, branch, fix, switch back, pop the stash, and hope nothing re-ran a build while you weren't looking.\n\nThen I remembered git worktrees. And it turned out Claude had a genuinely good doc on them.\n\nThe idea clicked right away.\n\nOne folder per task, each on its own branch, each with its own Claude session.\n\nMy one rule was dead simple: branch name = session name = whatever it's for.\n\nThat way I could jump to any of them, or come back hours later, and not have to squint to remember which was which.\n\nSo I sat down and actually learned it on my little TUI file browser, [peektea](https://github.com/lovestaco/peektea).\n\nHere's the small write-up. Let me pour you a cup xD\n\nA normal clone gives you **one** working directory tied to **one** branch.\n\nA [ worktree](https://git-scm.com/docs/git-worktree) is a\n\nBoth folders share one `.git`\n\n(file) same history, same remote, but their files are completely independent.\n\nEdit, build, or run in one, and the other never even notices.\n\nThat isolation is the entire point.\n\nClaude can be wiring up one feature in Terminal A while you fix something unrelated in Terminal B, and neither session can clobber the other's files. No stashing. No tea spilled.\n\nThe one rule that decides everything\n\nA worktree belongs toexactly one repository, and a branch can live inexactly one worktreeat a time. So the math is simple:one worktree per parallel feature.Two features in peektea → two worktrees → two terminals → two sessions.\n\nI created two issues in peektea that may not touch each other, ideal for steeping in parallel:\n\n| Feature | Issue | What it is |\n|---|---|---|\nA |\n|\n\n`y`\n\ncopies the highlighted path, `Y`\n\ncopies the file's contents`x`\n\ncuts the entry, `v`\n\ndrops it into the current directoryBoth branch off `master`\n\n.\n\nBoth add keybindings, but they live in different code paths, exactly the kind of \"could be one PR each, done at the same time\" work worktrees were made for.\n\nMy main checkout lives at `~/pers/peektea`\n\n.\n\nThe worktrees will sit right next to it.\n\nYou run `git worktree add`\n\nfrom **any** existing checkout of the repo, you don't have to be \"inside\" a worktree to make one.\n\nThe command creates the folder **and** the branch in a single shot and wires them together.\n\n**Terminal A · the copy-shortcuts feature**\n\n```\ncd ~/pers/peektea\ngit fetch origin master            # refresh the base\n\n# new folder + new branch, off master\ngit worktree add \\\n  -b copy-path-and-contents \\\n  ~/pers/peektea-copy \\\n  master\n\ncd ~/pers/peektea-copy\n\nclaude                             # fresh session, right here\n```\n\n**Terminal B · the move-file feature**\n\n```\ncd ~/pers/peektea\n\ngit worktree add \\\n  -b move-to-dir \\\n  ~/pers/peektea-move \\\n  master\n\ncd ~/pers/peektea-move\n\nclaude                             # second session, fully independent\n```\n\nThat's it. Two checkouts, two branches, two Claude sessions and your original `~/pers/peektea`\n\nis sitting there untouched, exactly how you left it.\n\nInside each session, run `/rename`\n\nto match the branch.\n\nCosts a second now, saves you squinting at an unlabelled session list later:\n\n```\n/rename copy-path-and-contents\n```\n\nBecause `claude --resume`\n\nonly lists sessions for the folder you launch it from, the branch-named one is the obvious cup waiting in each worktree:\n\n```\ncd ~/pers/peektea-move\nclaude --resume      # pick the named session\n# or, fastest:\nclaude --continue    # reopen the most recent one here\n```\n\nSwitching is just… switching terminals.\n\nThe sessions don't share state, so there's nothing to reconcile.\n\n`status`\n\nand `diff`\n\nwork exactly how you already know them, and you can peek at *either* tree from *anywhere* with `git -C`\n\ninstead of `cd`\n\n-ing around:\n\n```\n# inside a worktree\ngit status\ngit diff            # unstaged\ngit diff --staged   # staged\n\n# or peek without leaving your current folder\ngit -C ~/pers/peektea-move status\n```\n\nHere's the part I genuinely didn't appreciate until I tried it.\n\nBecause **each worktree is its branch**, a commit can only ever land on that branch.\n\nThe classic \"ugh, I committed the bugfix onto the feature branch\" mistake isn't something you have to be careful about, it's *structurally impossible*.\n\nVisually, the two features steep in their own cups and only meet when you merge:\n\nCommitting and pushing is the usual ceremony, the first push just sets the upstream:\n\n```\ncd ~/pers/peektea-copy\ngit add -A\ngit commit -m \"feat: y/Y to copy path and file contents (#2)\"\ngit push -u origin copy-path-and-contents   # first push sets upstream\n```\n\nThis is where a Go TUI is a *delight* compared to a web stack.\n\npeektea is a single binary, no frontend, no backend, no ports to fight over.\n\nYou build inside the worktree and run the local binary, because you're testing *your* edited code, not the main tree's:\n\n```\ncd ~/pers/peektea-move\nmake build      # builds ./peektea right here in the worktree\n./peektea       # run the version with YOUR changes\n```\n\nWant live reload while you iterate with Claude? `make start`\n\nrebuilds on every `.go`\n\nsave:\n\n```\nmake start      # air watches and rebuilds ./peektea\n```\n\nAnd because there's no server, you can happily run `make start`\n\nin **both** worktrees at once, no port collision, no proxy juggling, nothing to stop and restart.\n\nThe TUI just reads the terminal it's launched in.\n\nAnyways.\n\nWhen a feature's merged, remove its worktree from a **different** checkout, not from inside the folder you're deleting:\n\n```\ncd ~/pers/peektea\ngit worktree list                       # see them all\ngit worktree remove ~/pers/peektea-move\n# refuses if the worktree is dirty; add --force to discard changes\n\ngit branch -d move-to-dir               # -D to force-delete if unmerged\ngit worktree prune                      # tidy up stale metadata\n```\n\nNote that `git worktree remove`\n\n**leaves the branch behind on purpose**, so you can't accidentally throw away unmerged work by deleting a folder.\n\nBranches get deleted separately, deliberately. Polite to the last drop.\n\n`--worktree`\n\n…\"\nIt does! `claude --worktree feature-x`\n\nspins up a worktree and drops you straight into a session, perfect for a quick spike.\n\nFor real tickets I still reach for the manual `git worktree add`\n\n, for two reasons:\n\n`worktree-feature-x`\n\n, not the exact name I want (`copy-path-and-contents`\n\n).`origin/HEAD`\n\n, which here is `master`\n\nanyway, but on repos where your trunk is `dev`\n\nor `develop`\n\n, that's the wrong base.When the branch name and base both need to be *exactly* right, plain `git worktree add`\n\nwins.\n\nFor a throwaway experiment, `--worktree`\n\nis the faster pour.\n\n| Command | What it does |\n|---|---|\n`git worktree add -b <branch> <dir> <base>` |\nnew worktree on a brand-new branch |\n`git worktree add <dir> <existing-branch>` |\nworktree from an existing branch |\n`git worktree list` |\nshow every worktree + its branch |\n`git -C <dir> status` |\ninspect a worktree without `cd` -ing |\n`git worktree remove <dir>` |\ndelete it (`--force` if dirty) |\n`git worktree prune` |\nclear stale worktree metadata |\n`/rename <name>` |\nname the Claude session (= the branch) |\n`claude --resume` / `--continue`\n|\nreopen a session in this folder |\n\nWorktrees turn \"I can only hold one branch in my hands at a time\" into \"I have as many hands as I have terminals.\"\n\nPair that with a named Claude Code session per checkout, and parallel work stops feeling like juggling and starts feeling like… letting two cups steep at once.\n\nNo stash dance. No wrong-branch commits. No tea spilled.\n\nDisclaimer: This article was written by me; AI was used to fix grammar and improve readability.\n\nAI agents write code fast. They also silently remove logic, change behavior, and introduce bugs — without telling you. You often find out in production.\n\ngit-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.\n\nAny feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.\n\n⭐ Star it on GitHub:\n\n| [🇩🇰 Dansk](https://github.com/HexmosTech/git-lrc/readme/README.da.md) | [🇪🇸 Español](https://github.com/HexmosTech/git-lrc/readme/README.es.md) | [🇮🇷 Farsi](https://github.com/HexmosTech/git-lrc/readme/README.fa.md) | [🇫🇮 Suomi](https://github.com/HexmosTech/git-lrc/readme/README.fi.md) | [🇯🇵 日本語](https://github.com/HexmosTech/git-lrc/readme/README.ja.md) | [🇳🇴 Norsk](https://github.com/HexmosTech/git-lrc/readme/README.nn.md) | [🇵🇹 Português](https://github.com/HexmosTech/git-lrc/readme/README.pt.md) | [🇷🇺 Русский](https://github.com/HexmosTech/git-lrc/readme/README.ru.md) | [🇦🇱 Shqip](https://github.com/HexmosTech/git-lrc/readme/README.sq.md) | [🇨🇳 中文](https://github.com/HexmosTech/git-lrc/readme/README.zh.md) | [🇮🇳 हिन्दी](https://github.com/HexmosTech/git-lrc/readme/README.hi.md) |\n\nGenAI today is a **race car without brakes**. It accelerates fast -- you describe something, and large blocks of code appear instantly. But AI agents *silently break things*: they remove logic, relax constraints, introduce expensive cloud calls, leak credentials, and change behavior -- without telling you. You often find out in production.\n\n** git-lrc is your braking system.** It hooks into\n\n`git commit`\n\nand runs an AI review on every diff In short, git-lrc helps **Prevent Outages, Breaches, and Technical Debt Before They Happen**\n\n**At a glance:** [10 risk categories](https://github.com/HexmosTech/git-lrc#what-git-lrc-checks-for) · [100+ failure patterns tracked](https://github.com/HexmosTech/git-lrc#what-git-lrc-checks-for) · every commit…", "url": "https://wpnews.pro/news/two-terminals-one-pot-of-tea-parallel-claude-code-with-git-worktrees", "canonical_source": "https://dev.to/lovestaco/two-terminals-one-pot-of-tea-parallel-claude-code-with-git-worktrees-6h", "published_at": "2026-06-30 18:59:14+00:00", "updated_at": "2026-06-30 19:18:47.050076+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "large-language-models"], "entities": ["Claude Code", "Git", "peektea", "HexmosTech", "git-lrc", "lovestaco"], "alternates": {"html": "https://wpnews.pro/news/two-terminals-one-pot-of-tea-parallel-claude-code-with-git-worktrees", "markdown": "https://wpnews.pro/news/two-terminals-one-pot-of-tea-parallel-claude-code-with-git-worktrees.md", "text": "https://wpnews.pro/news/two-terminals-one-pot-of-tea-parallel-claude-code-with-git-worktrees.txt", "jsonld": "https://wpnews.pro/news/two-terminals-one-pot-of-tea-parallel-claude-code-with-git-worktrees.jsonld"}}