---
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:

1. Finds migration `.sql` files added by the rebasing commit (via `REBASE_HEAD`)
2. Determines the highest timestamp among all other (upstream) migrations
3. Renames our files to timestamps after the upstream max (offset +1000, increment by 1)
4. Regenerates `atlas.sum` from scratch using `atlas migrate hash`
5. Stages all changes

### Steps

1. **Preview the fix** (always do this first):
   ```bash
   mise fix-atlas-conflicts -- --dry-run
   ```
   This shows which files will be renamed and to what timestamps, without making changes.

2. **Apply the fix**:
   ```bash
   mise fix-atlas-conflicts
   ```

3. **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:

1. Checks all `.go` files for conflict markers in hand-written files (any file without the `Code generated by ent` header)
2. Identifies generated `.go` files by scanning for the `// Code generated by ent, DO NOT EDIT.` header
3. 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
4. Runs `go generate ./so/ent/...` to regenerate from the merged schemas
5. If the current rebase commit added migration `.sql` files, deletes them (they're stale) and rehashes `atlas.sum`
6. Stages all changes

### Steps

1. **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.).

2. **Preview the fix**:
   ```bash
   mise fix-ent-conflicts -- --dry-run
   ```

3. **Apply the fix**:
   ```bash
   mise fix-ent-conflicts
   ```

4. **If the script deleted stale migrations**, regenerate them:
   ```bash
   ./scripts/gen-migration.sh <migration-name>
   ```

5. **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
