jackc / tern

The SQL Fan's Migrator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Merging a branch with duplicate migration numbers

jackc opened this issue · comments

It is inconvenient to merge a branch when there are migrations with duplicate numbers. Rails resolved this by moving to timestamp migrations. I dislike this approach because it makes the order migrations are applied non-deterministic. However, it would be nice to have a simpler way to resolve this than manually renaming the offending files.

Broadly speaking there are two directions to go with this.

  1. Integrate with version control to determine which files come from which branch. On the plus side it could probably resolve a whole set of migrations with minimal human involvement. On the down side this seems complicated, may add dependencies, and needs to be built for each VCS. It also wouldn't help if duplicate numbers were introduced somewhere other than in a merge.
  2. An interactive renumber mode. Something like git add --patch where it shows each conflict and asks which one comes first.

To me it feels like it should be outside of the scope of tern as a simple direct tool, to fix bad development.

Perhaps all that tern should do is detect if there are multiple migrations with the same version, and abort ahead of time with a meaningful message, without even attempting to run anything?

To me it feels like it should be outside of the scope of tern as a simple direct tool, to fix bad development.

I don't see how it is bad development to have to renumber migrations when working on a branch. If two concurrent branches each have migrations then one of them will need to renumber.

Perhaps all that tern should do is detect if there are multiple migrations with the same version, and abort ahead of time with a meaningful message, without even attempting to run anything?

This is what it does now. What I want is to make it easier to fix.

Here's another example from a current project of mine of what I am trying to simplify. I have a feature branch with 5 migrations on it. I keep it up to date with master by rebasing on top of master (it'd be the same with merge but I prefer rebase). Every time there is a new migration on master I have to manually renumber those 5 migration files. It's not a big deal but it is an annoying 30 second task that happens fairly frequently.

Fair enough! I suppose to an interactive shell that allows you to renumber each conflicting migration file is a little more friendly then renumbering by hand.

Here's a 3rd potential approach.

Given I have just rebased branch wip-feature on top of master and I notice conflicting migrations then I:

  1. Checkout master.
  2. Run tern something. That saves the list of migration files to a temp file (probably in the migration folder).
  3. Checkout wip-feature.
  4. Run term something-else. That compares the current list of migration files to the saved list and renumbers the new ones.

This avoids the user having to make any decisions, avoids coding an interactive UI, and avoids VCS integration. The whole thing could be scripted.

I actually really like this.

So say that master as migrations 1, 2, 3, 4 5, and you rebase onto it with a feature branch that has conflicting migrations 4 and 5, if you had run tern commit history on master and now run tern rebase the conflicting files would automatically be renumbered to 6 and 7?

What if only version 4 was in conflict? do you still push it completely to the back?

What if only version 4 was in conflict? do you still push it completely to the back?

Yes. It would become 6.

Added tern renumber start and tern renumber finish commands.

@jackc it would be great if the core logic of these commands was somehow in migrate, and made available to people (like me) who build tools around the features provided by tern/migrate.

I agree. Though there are a few complications. The migrate package works in terms of MigratorFS. And if and when there is a tern v2 at some point, I want replace that with fs.FS. Neither of these support writing or deleting files. Also, if #50 and/or #52 are implemented they may have impact on this feature and what its interface would be.