| name | resolving-rebase-conflicts |
| description | Resolve rebase conflicts in Ent generated code and Atlas migrations using repository scripts. |
Resolving Rebase Conflicts in Ent and Atlas Migrations
Triggers
Activate this skill when any of these conditions are detected:
- User is in a
git rebase or gt restack and atlas.sum has conflict markers
- User mentions atlas migration conflicts, migration ordering issues, or
atlas.sum conflicts
git status shows atlas.sum as "both modified" or migration .sql files with conflicts
- User asks about resolving migration timestamp collisions after rebase
- Generated ent files in
spark/so/ent/ have conflict markers after rebase
go build or go generate fails due to conflict markers in ent-generated code
- User mentions ent conflicts, generated code conflicts, or ent regeneration during rebase
Two Conflict Scenarios
Scenario A: Atlas-only conflicts (unrelated schema changes)
Symptom: atlas.sum has conflict markers, but ent-generated .go files are fine. The base branch added migrations for schemas unrelated to yours - only ordering conflicts.
Fix: mise fix-atlas-conflicts
Scenario B: Ent schema conflicts (base changed schemas you also changed)
Symptom: Generated ent .go files in spark/so/ent/ have conflict markers (<<<<<<</>>>>>>>). Go compilation fails, so go generate can't run. If this commit also added atlas migrations, those migrations are invalid (generated against pre-rebase schema state).
Fix: mise fix-ent-conflicts
Scenario A: Atlas-Only Fix
The repository includes scripts/fix-atlas-conflicts.sh (also available as mise fix-atlas-conflicts) which automates the fix:
- Finds migration
.sql files added by the rebasing commit (via REBASE_HEAD)
- Determines the highest timestamp among all other (upstream) migrations
- Renames our files to timestamps after the upstream max (offset +1000, increment by 1)
- Regenerates
atlas.sum from scratch using atlas migrate hash
- Stages all changes
Steps
-
Preview the fix (always do this first):
mise fix-atlas-conflicts -- --dry-run
This shows which files will be renamed and to what timestamps, without making changes.
-
Apply the fix:
mise fix-atlas-conflicts
-
Continue the rebase. The script will suggest the correct command:
- If using Graphite (
gt on PATH and .graphite/ exists): gt continue
- Otherwise:
git rebase --continue
Edge Cases
- No migrations in commit: Script exits cleanly with "Nothing to do"
- Outside of rebase: Use
mise fix-atlas-conflicts -- --commit <SHA> to specify the commit manually
- Multiple migrations in one commit: All are renamed with sequential timestamps, preserving relative order
- Collision detection: Script checks that renamed files don't collide with existing files before proceeding
Scenario B: Ent + Atlas Fix
The repository includes scripts/fix-ent-conflicts.sh (also available as mise fix-ent-conflicts) which automates the fix:
- Checks all
.go files for conflict markers in hand-written files (any file without the Code generated by ent header)
- Identifies generated
.go files by scanning for the // Code generated by ent, DO NOT EDIT. header
- Resets generated files to their upstream (
--ours) version via git checkout --ours. This removes conflict markers while keeping valid, type-checkable Go - necessary because ent's codegen parses schemas that import from generated packages
- Runs
go generate ./so/ent/... to regenerate from the merged schemas
- If the current rebase commit added migration
.sql files, deletes them (they're stale) and rehashes atlas.sum
- Stages all changes
Steps
-
Resolve conflicts in hand-written files first. The script will abort if it finds conflict markers in any .go file that lacks the Code generated by ent header (schemas, extensions, tests, config files, etc.).
-
Preview the fix:
mise fix-ent-conflicts -- --dry-run
-
Apply the fix:
mise fix-ent-conflicts
-
If the script deleted stale migrations, regenerate them:
./scripts/gen-migration.sh <migration-name>
-
Continue the rebase. The script will suggest the correct command.
Flags
--dry-run - Preview which files would be reset, without making changes
--force - Skip generated-file conflict-marker check (useful outside a rebase, e.g. after manual schema merge)
-h/--help - Usage information
Hand-Written Files (Preserved)
The script detects generated files by their // Code generated by ent, DO NOT EDIT. header. Any .go file without this header is treated as hand-written and left untouched. Examples:
| File | Why |
|---|
ent/schema/** | Schema definitions, mixins, schematype/ |
ent/*_extension.go | Hand-written extension files |
ent/*_ext.go | Hand-written predicate extensions |
ent/*_test.go | Test files |
ent/entc.go | Codegen driver config |
ent/generate.go | //go:generate directive |
ent/interceptor.go | Custom OpenTelemetry interceptors |
ent/telemetry.go | Custom tracer init |
ent/migrate/dump_schema.go | Hand-written schema dump utility |
ent/migrate/migrations/** | Migration SQL files + atlas.sum |
What NOT to Do
- Do not manually edit
atlas.sum conflict markers - the hash file is regenerated from scratch
- Do not manually rename migration files without regenerating
atlas.sum
- Do not use
git checkout --theirs atlas.sum - this loses the entry for our migration files
- Do not run
fix-ent-conflicts for atlas-only conflicts - use fix-atlas-conflicts instead
- Do not try to manually fix conflict markers in generated ent files - delete and regenerate