Help us shape the future of Go! Take the 2026 Go Developer Survey

migrationgit

package
v1.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package migrationgit answers, from git, the one question both the version lint and `forge db migration rebase` have to agree on: which migrations were already on the default branch when this branch was cut.

Both callers act on that answer, in opposite directions. The lint flags a migration as NEW — and therefore still fixable — when its version is above the merge-base high-water mark. Rebase REFUSES to re-version a migration that is at or below it and present on the default branch, because renaming one that has already merged breaks every database that recorded it.

Two implementations of that boundary would eventually disagree, and the disagreement would be silent: the lint would tell someone to rebase a file the rebase command would happily rename, or refuse one the lint had just flagged. One definition, in one place.

EVERY FAILURE HERE IS "UNKNOWN", NOT AN ERROR. This code runs in checkouts it does not control: a shallow CI clone, an exported tarball, a repository with no default branch, a migrations directory that is not tracked at all. A missing git binary is deliberately indistinguishable from a failed command, because both mean the same thing to a caller.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultBranchFiles added in v1.0.0

func DefaultBranchFiles(repoRoot, migrationsDir string) (files map[string]bool, ref string, ok bool)

DefaultBranchFiles lists the file names in migrationsDir on the default branch's tip, and names the ref it read. False when there is no default branch to read (a tarball, a repository with no remote and no main).

Names, not versions: whether a migration "is on main" is a question about one file — two branches can claim one version (see the package doc of internal/database's rebase).

func DefaultBranchVersions

func DefaultBranchVersions(repoRoot, migrationsDir string) (map[uint64]string, bool)

DefaultBranchVersions returns the migration versions present in migrationsDir on the default branch's tip, mapped to the filename that claims each one.

The TIP, not the merge-base, because this answers "has this version already merged". A migration that landed on main after this branch was cut is just as merged as one that predates it, and renaming it is just as wrong.

func FilesAt added in v1.0.0

func FilesAt(repoRoot, migrationsDir, rev string) ([]string, bool)

FilesAt lists the file names in migrationsDir at revision rev (a commit, a ref). A directory absent at rev is an empty list, which is a real answer; false means the revision itself could not be read — not in this clone, or no git.

func IsTracked

func IsTracked(repoRoot, path string) bool

IsTracked reports whether path is tracked by git, which decides whether a rename goes through `git mv` or a plain filesystem rename.

func MergeBaseMax

func MergeBaseMax(repoRoot, migrationsDir string) (uint64, bool)

MergeBaseMax returns the highest migration version present in migrationsDir as of the merge-base between HEAD and the default branch — the state this branch started from — and whether that could be determined at all.

func Move

func Move(repoRoot, from, to string) error

Move renames from to to, using `git mv` when the source is tracked so the rename is staged as a rename rather than appearing as a delete plus an untracked add.

func Next added in v1.0.0

func Next(dir string) (string, error)

Next is NextN for one version.

func NextN added in v1.0.0

func NextN(dir string, n int) ([]string, error)

NextN allocates n migration versions for dir that sort above everything the directory holds AND everything the default branch's tip holds.

migrationver.NextN sees only the directory on disk. A branch cut before main's newest migration landed does not contain that file, so a clock that is behind it (a skewed machine, a future-dated main head) or a directory max that is lower allocates BELOW it, and golang-migrate then never applies the new file on any database that has run the newer one. The default branch's tip and the merge-base mark are seeded into the allocator so the version is above the head the lint will compare it against.

Without git (no repository, no default branch) the default-branch sets are unknown and the directory alone decides, as migrationver.NextN does.

func RepoRelative added in v1.0.0

func RepoRelative(repoRoot, migrationsDir string) (string, bool)

RepoRelative is migrationsDir relative to repoRoot in slash form — the path git names it by — or false when it is not inside the repository.

func RepoRoot

func RepoRoot(dir string) string

RepoRoot returns the git repository root containing dir, or dir itself when there is none. Every git call is scoped to it, so a lookup never reads a parent repository that happens to sit above an untracked project.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL