Git And Collaboration Workflows
Worktrees, Bisect, And Rerere
Worktrees support parallel checkouts, bisect searches commit history for a regression, and rerere reuses recorded conflict resolutions.
Why This Matters
These tools shorten interruption-heavy debugging and repeated integration work without requiring multiple full clones or manual binary search.
Working Model
A linked worktree shares the repository object database but has its own working tree and index. Bisect repeatedly chooses a midpoint between known good and bad commits. Rerere records conflict shapes and resolutions for later reuse.
Practical Rules
- Use worktrees for an urgent fix while preserving an in-progress branch.
- Keep generated files and environment ports isolated between worktrees.
- Automate bisect with a deterministic test command.
- Mark untestable commits with
git bisect skipsparingly. - Inspect rerere's reused resolution before committing.
Failure Modes
- Running two worktrees against the same mutable local database.
- Using a flaky or environment-dependent bisect test.
- Forgetting
git bisect resetafter diagnosis. - Trusting an old rerere resolution after surrounding behavior changed.
Verification
- List and prune worktrees deliberately.
- Repeat the failing test outside bisect at the identified commit.
- Inspect reused conflict resolutions and run the full relevant suite.
- Document the first bad commit and the causal change.
What You Should Be Able To Do
After this lesson, you should be able to explain parallel Git workspaces, history-based regression search, and reusable conflict resolution, choose a suitable approach for a real PHP project, and verify the result instead of relying on assumptions.
Worktrees Give One Repository Multiple Working Directories
git worktree lets one repository have more than one checked-out working directory. This is useful when you need to keep a feature branch open while testing a hotfix, reviewing another branch, or running a long build. Each worktree has its own working tree and branch checkout, while sharing the underlying object database.
Worktrees reduce the temptation to stash half-finished work or constantly switch branches with dirty files. A PHP developer can keep one worktree on main, another on a feature branch, and another on a release branch. Dependencies and generated files may still be separate per directory, so disk use and setup time matter.
Do not check out the same branch in two worktrees at once. Git normally prevents this because two directories trying to move the same branch name would be confusing. Use separate branch names for separate work.
Practical Worktree Workflow
Create a sibling directory for a hotfix, install dependencies if needed, run the fix, and remove the worktree after merge. Keep path-specific local configuration in mind: .env, caches, uploaded test files, and build output may need setup in each worktree. If your project uses containers, the compose project name or port mapping may also need adjustment.
Use git worktree list to see active worktrees. Remove finished ones with git worktree remove and prune stale administrative data when necessary. A worktree is not a backup; important work still needs commits or branches.
Bisect Finds The Commit That Introduced A Regression
git bisect performs a binary search through history. You mark one commit as good and another as bad, then Git checks out candidates. After each test, you mark the candidate good or bad until Git identifies the first bad commit.
Bisect works best when the test is reliable and commits are buildable. If many commits cannot run because they depend on later fixes, bisect becomes slower and less precise. That is one reason coherent commits matter.
For PHP projects, a bisect test might run one PHPUnit test, a CLI reproduction script, or a small HTTP-level check. Automating the test with git bisect run is powerful, but the script must return correct exit codes: zero for good, non-zero for bad, and a special skip code when the commit cannot be tested.
Choosing Good And Bad Points
The bad point is usually current main or a release commit where the regression is visible. The good point should be a commit where the behavior definitely worked. Guessing wastes time. Use tags, deployment records, release notes, or monitoring data to choose points.
If the regression depends on data or environment, make the reproduction deterministic first. A flaky test gives bisect misleading answers. Pin dependencies, prepare fixtures, and run the same command each step.
Rerere Remembers Conflict Resolutions
rerere means reuse recorded resolution. When enabled, Git records how you resolved a conflict and can apply the same resolution when the same conflict appears again. This helps during repeated rebases, long-running branches, or stack updates.
Rerere is a memory aid, not a correctness guarantee. Inspect reused resolutions before continuing. Surrounding code may have changed even when the conflict looks similar. If rerere applies a bad resolution, you can forget it for that conflict and resolve manually.
Combining The Tools
Worktrees and bisect pair well. You can run a bisect in a separate worktree while keeping your normal branch untouched. Worktrees also help compare two versions of a file side by side without constantly switching. Rerere helps when updating a long-running branch in one worktree repeatedly encounters the same conflict.
The tools solve different problems: worktrees manage parallel working directories, bisect locates regressions, and rerere reduces repeated conflict labor. Do not use one as a substitute for another. A worktree will not identify the bad commit; bisect will not preserve your half-finished feature branch; rerere will not decide whether the resolution is semantically correct.
Cleanup And Safety
Because worktrees create extra directories, they can leave running servers, containers, cache files, or databases behind. Document naming conventions and cleanup commands. Do not put secrets in a temporary worktree and forget it on a shared machine.
Bisect changes the checked-out commit repeatedly. Do not run it in a dirty worktree. Commit or stash work first, or use a separate worktree. After bisect, run git bisect reset to return to the original branch.
Practice Exercise
Create a small repository with a script that passes, add several commits, introduce a failure, and then add more commits. Use bisect manually, then with bisect run. Next, create two worktrees and inspect the good and bad versions side by side. Finally, create a repeated conflict with rerere enabled and observe how Git proposes the previous resolution.
After this lesson, you should be able to use worktrees for parallel tasks, run bisect to identify regressions, write a reliable bisect command, use rerere to reduce repeated conflict work, and clean up safely after these advanced Git workflows.
Debugging A PHP Regression With Bisect
A useful bisect script should prepare the environment consistently. It may need to run Composer install when dependencies changed, clear caches, apply a test database fixture, or skip commits where the application cannot boot. Keep the script focused on the regression. Running the entire suite at every step can make bisect painfully slow and less reliable.
When the first bad commit is found, read it in context. The commit may expose the problem without being the complete cause. For example, a route change may reveal a missing test fixture, or a dependency update may expose undefined behavior that already existed. Use bisect as a pointer to investigation, not a substitute for understanding.
Worktrees help preserve evidence. Keep one worktree at the good commit and one at the bad commit, then compare configuration, generated files, and behavior side by side. This is especially helpful when the regression involves assets, migrations, or runtime configuration.
Operational Tips
Name worktree directories clearly, especially when several point at similar branches. A path like ../project-release-1.4-hotfix is safer than ../tmp2. Keep local environment files separate and avoid starting two worktrees on the same ports or container project names.
For bisect, save the final report: good commit, bad commit, first bad commit, command used, and any skipped commits. That note lets another developer reproduce the investigation or challenge a flaky result.
For rerere, enable it deliberately and learn how to inspect what it did. If a repeated resolution looks suspicious, redo it manually rather than accepting the cached answer.
Maintenance Habits
Prune worktrees after use. Old directories can hold stale dependencies, local databases, ignored files, or secrets. Include worktree cleanup in the same habit as deleting merged branches.
For bisect scripts, keep dependencies minimal. If the script needs a database, create and load a small fixture rather than relying on a developer's current local state. If a commit cannot run because dependencies are unavailable, skip it deliberately and record that skip.
For rerere, remember that it stores conflict-resolution data locally. Another developer will not automatically get your recorded resolution. If a conflict is common across the team, improve the branch structure or documentation instead of relying on everyone's local rerere cache. These tools are most valuable when they reduce context switching without hiding state. Keep branch names, directories, scripts, and recorded resolutions understandable to someone who did not create them. Prefer boring names and repeatable commands over clever one-off debugging setups. Document cleanup too. Remove stale debugging state promptly.
Practice
Practice: Create A Hotfix Worktree
An unfinished feature occupies the main working tree when an urgent production fix arrives.
Your answer must:
- state the intended outcome;
- show the commands, data flow, or implementation shape;
- identify at least one unsafe alternative;
- explain how the result will be verified.
Show solution
Fetch, create a linked worktree on a new hotfix branch from the production base, use separate local ports and state, implement and test the fix, then remove the worktree after merge.
The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.
Practice: Automate A Bisect
A deterministic test fails on the current branch but passed in a known release tag.
Your answer must:
- state the intended outcome;
- show the commands, data flow, or implementation shape;
- identify at least one unsafe alternative;
- explain how the result will be verified.
Show solution
Start bisect, mark the current commit bad and the tag good, run git bisect run with the focused test command, verify the reported first bad commit manually, then reset bisect state.
The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.
Practice: Review Rerere Reuse
A long-running branch repeatedly conflicts in the same dependency file.
Your answer must:
- state the intended outcome;
- show the commands, data flow, or implementation shape;
- identify at least one unsafe alternative;
- explain how the result will be verified.
Show solution
Enable rerere, resolve the conflict correctly once, commit, then inspect future automatic reuse with git diff before accepting it. Regenerate and validate the dependency state rather than trusting textual resolution alone.
The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.