Expand description
Detect and auto-renumber colliding sqlx migration version numbers across git branches.
sqlx assigns a migration’s version at author time, so two branches that both
add NNNN_*.sql at the same NNNN merge cleanly, then fail at test time
with UNIQUE constraint failed: _sqlx_migrations.version. migrate-guard
catches this before merge and renumbers your topic branch above the global
max. A collision is one version claimed by two different files — the same
file seen on multiple branches is not a collision.
§As a CLI
The cargo migrate-guard subcommand runs at your repo root, configured by a
migrate-guard.toml that lists your migration directories:
cargo install migrate-guard
cargo migrate-guard check # CI gate: non-zero exit on collision
cargo migrate-guard renumber # dry run: show the plan
cargo migrate-guard renumber --apply # renumber this branch + rewrite include_str! refs
cargo migrate-guard max # print the max version per role# migrate-guard.toml
base_ref = "main"
reference_globs = ["src/**/*.rs"]
[[dir]]
role = "platform"
path = "migrations"§As a library
The pure collision + renumber logic is exposed and needs no git or filesystem. Parse a filename:
use migrate_guard::parse_filename;
assert_eq!(parse_filename("0286_add_index.sql"), Some((286, 4, "add_index")));
assert_eq!(parse_filename("not-a-migration.sql"), None);Detect a collision (same version, two different files):
use migrate_guard::MigrationFile;
use migrate_guard::model::{detect_collisions, Observation, Source};
let observations = vec![
Observation { role: "platform".into(), version: 2,
source: Source::Branch("feat-a".into()), file: file(2, "0002_a.sql") },
Observation { role: "platform".into(), version: 2,
source: Source::WorkingTree, file: file(2, "0002_b.sql") },
];
let collisions = detect_collisions(&observations);
assert_eq!(collisions.len(), 1);
assert_eq!(collisions[0].version, 2);Modules§
- apply
- Floor computation, reference rewriting, and renumber application.
- config
migrate-guard.tomlparsing.- error
- git
- Shells to the
gitbinary. No git library. - model
- Pure collision + renumber logic. No I/O.
Structs§
- Migration
Dir - An independent numbering namespace (platform vs tenant, etc.).
- Migration
File - One parsed migration file within a numbering namespace.
Functions§
- parse_
filename - Parse a migration filename: a leading run of ASCII digits, then ‘_’, then a description, then “.sql”. Returns (version, digit_width, desc).
- scan_
dir - Scan a directory for migration files (missing dir → empty), sorted by version.