How to manage Migrations in a project with multiple branches?

There is a much better solution for handling entity framework migration merge conflicts on a similar question.

All you need to do after a merge is to re-scaffold the meta data of the migration in the target branch. That is you do not rescaffold the up/down code, just the state in the resx-file.

add-migration [the_migration_to_rescaffold_metadata_for]

This almost always works. The procedure will fail if a different migration in the merge have changed the database in such a way that the migration is no longer runnable or gives an unexpected result. That being said - I believe that to be a very rare case as most migrations should be auto-generated, or at least not be dependent on other tables that are not changed in the migration itself as well.

One such case where rescaffold state would fail could be:

  • Column foo is an int and rows contain [0, 1, 2]

  • Migration A from branch A change foo to boolean (0 will become false automatically and > 0 will become true)

  • Migration B from branch B change foo to string. It expects it to be an int but it is a boolean, the migration will succeed though. Data will be lost since when migration B was created the rows would contain ["0", "1", "2"]. When migration A altered column to boolean (and did so successfully and with expected result) the rows will now contain ["0", "1", "1"] instead and Migration B will have a different end result than what was observed in Branch B.

There are probably more edge cases where things could go wrong with the solution. But if migrations up/down code is not dependent on things changed by another migration in the merge it should work well to just update the metadata in the migrations.


Edit: a colleague of mine discovered an easier with to do this, I left my original answer at the bottom for completeness.

(VERY IMPORTANT) migrations in live environment must not conflict with ones in your current branch, otherwise you need to redo all your migrations and resolve data model change conflicts by hand.

  1. restore your development database with live environment data
  2. run update-database, it should run migrations from your branch, and complain about 'unable to update database to match the current model blah blah..'
  3. run add-migration MergeBranchBToMaster -ignoreChanges, this will create an empty migration.
  4. run update-database again
  5. push your changes

The magic in step 3 basically tells EF to shutup about mismatched models, hence be very sure that your migrations do not conflict with ones in live environment. If they do, you can always create SQL scripts for pushing the missing migrations (which is actually the preferred method).

Original Answer

I have found a fairly straight-forward solution based on @Ladislav Mrnka's answer. This will work with live environment[1], you just have to be careful not to change any deployed migrations.

  1. Before Merge, take note of the migration you added (MyMigration), and its previous migration (BaseMigration)

  2. Merge branches in git

  3. Open Package Manager Console, and run: UPDATE-DATABASE -TargetMigration:BaseMigration. This will revert your database to the state before any of the conflicted migrations are applied

  4. Delete your local migration (MyMigration)

  5. Run: UPDATE-DATABASE. This will apply all newer migrations done in other branches.

  6. Run: ADD-MIGRATION MyMigration. This will re-generate your local migration based on current state of database, like git -rebase.

  7. Run: UPDATE-DATABASE. Update database with you local migration.

This also works if you have multiple local migrations, but it will merge them all into a single one.

[1] by working with live environment, I mean that the generated migration can be applied to live environment which may already have some/all of the other branches' migrations applied. The steps themselves are purely for development purpose.