The Branch-Based Regeneration Pattern
How Fractal Forge handles the fundamental tension between generated code and custom modifications through Git branching.
Code generators face a fundamental tension: the code needs to be regenerated when the model changes, but developers need to customize that code. How do you regenerate without destroying customizations?
Most generators solve this poorly. Either they forbid modifications (“don’t touch the generated code”), or they use fragile markers to identify safe zones, or they require complex merge tooling. All of these approaches create friction and often fail at the worst possible moments.
Fractal Forge takes a different approach: branch-based regeneration. Every regeneration creates a new Git branch. Your customizations on main are never touched. Standard Git merge resolves conflicts.
The Problem in Detail
Let’s say you’ve generated an application and made these customizations:
- Added validation logic to a command handler
- Extended a frontend component with custom styling
- Created a new service that integrates with an external API
- Modified how a query filters results
Now your model changes. You’ve added a new entity, modified an existing one, and added new commands. You need to regenerate.
With traditional approaches, you have several bad options:
Option A: Regenerate and manually reapply changes
You lose your customizations and have to manually redo them. This is error-prone and time-consuming. It gets worse as the codebase grows.
Option B: Mark “safe zones” in the code
Some generators use comment markers to identify sections that won’t be overwritten. This is fragile: markers get accidentally deleted, and the safe zones impose artificial constraints on where you can make changes.
Option C: Generate into separate files and manually integrate
You maintain two parallel codebases and manually copy relevant parts. This is unsustainable at scale.
The Branch-Based Solution
Fractal Forge sidesteps these problems entirely by leveraging something developers already know: Git branching.
Here’s how it works:
Initial Generation
When you first generate, the code goes to a branch (let’s call it fractal/initial). You review it, merge to main, and start customizing.
# Generated code appears on fractal/initial
git checkout main
git merge fractal/initial
# Now customize on main Custom Code Organization
Your customizations go in specific places:
- Custom handlers live in
custom/directories - Overrides follow a predictable pattern
- New code can go anywhere since it’s your codebase
The generated code is designed to look for custom implementations first. If you’ve created custom/commands/create_order_handler.py, the framework uses that instead of the default.
Regeneration
When the model changes, you regenerate. The new code goes to a new branch (fractal/regenerate-v2):
# Regeneration creates a new branch
git checkout fractal/regenerate-v2
# Compare with main to see what changed
git diff main
# When ready, merge to main
git checkout main
git merge fractal/regenerate-v2 Conflict Resolution
Sometimes the merge will have conflicts. This happens when:
- Generated code changed in the same place you customized
- File structure changed significantly
- New generated code interacts with custom code
These are standard Git conflicts. You resolve them the same way you resolve any merge conflict. Your IDE’s merge tools work. Your team’s code review process works. Nothing special required.
Why This Works
Familiarity
Every developer knows Git. Every team has merge workflows. By using standard Git branching, we eliminate the need for specialized tooling or training.
Visibility
You can see exactly what changed between regenerations. git diff shows every modification. Code review catches issues before they reach production.
Reversibility
Don’t like a regeneration? Don’t merge it. The branch exists independently. You can cherry-pick specific changes, modify the generated code before merging, or abandon the branch entirely.
Flexibility
Because the generated code is standard Python and Svelte, you can modify anything. There are no protected files, no magic markers, no forbidden zones. The pattern encourages customization rather than preventing it.
The Custom Directory Convention
While you can customize any file, the custom/ directory convention keeps things organized:
backend/
app/
commands/
create_order.py # Generated
custom/
commands/
create_order.py # Your override Files in custom/ are never touched by regeneration. The framework automatically prefers custom implementations over generated ones.
This means:
- Simple changes override generated code with minimal risk
- Complex customizations are clearly separated
- Regeneration is safe because custom code is architecturally protected
Practical Example
Let’s walk through a real scenario:
Day 1: Generate initial application with Order and Customer entities.
Day 5: Add custom validation to CreateOrder command.
# custom/commands/create_order_handler.py
class CreateOrderHandler:
def handle(self, command):
self.validate_stock_available(command)
self.validate_customer_credit(command)
# ... rest of implementation Day 20: Model changes: add new fields to Order, new ShippingAddress entity.
Day 21: Regenerate to branch fractal/v2.
git diff main fractal/v2
# Shows: new entity files, modified Order model, updated tests
# Your custom/commands/create_order_handler.py is untouched Day 22: Merge after review.
git checkout main
git merge fractal/v2
# Resolves cleanly, custom directory preserved Day 25: Another model change conflicts with your customization.
git merge fractal/v3
# CONFLICT in app/commands/create_order.py
# The generated file changed where your custom code references it Day 26: Resolve conflict.
# Standard merge resolution
# Update your custom code to work with new generated interfaces
git add .
git commit -m "Merge fractal/v3 with updated custom handlers" Key Takeaways
Branch-based regeneration isn’t revolutionary technology. It’s the application of a familiar tool (Git branching) to a specific problem (generated code evolution).
The pattern succeeds because it:
- Uses tools developers already know
- Preserves all the flexibility of manual coding
- Makes changes visible and reviewable
- Keeps custom code architecturally protected
- Fails gracefully when conflicts occur
When your code generator works with Git rather than around it, you get the best of both worlds: the speed of generation and the flexibility of handwritten code.