Sometimes, when working with Laravel projects, especially when migrating databases manually or syncing environments, the migrations
table might miss entries — even though the migration files exist and were executed. This causes Laravel to attempt to re-run migrations or show them as pending. And even sometime, you added new migration and try to migrate them, but migration gives error that previous migrations are pending.
This article will guide you through creating an Artisan command that adds missing migration entries to the database without running them, keeping Laravel in sync with the actual DB schema.
Step 1: Create the Command
To create an artisan command, run the following command in your terminal:
php artisan make:command SyncMigrations
It creates a file at app/Console/Commands/SyncMigrations.php
.
Step 2: Add the Logic
Now, open this file and paste the following code inside it:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
class SyncMigrations extends Command
{
protected $signature = 'sync:migrations';
protected $description = 'Add missing migrations to the migrations table without running them';
public function handle()
{
$migrationPath = database_path('migrations');
$files = File::files($migrationPath);
$fileMigrations = collect($files)->map(function ($file) {
return pathinfo($file->getFilename(), PATHINFO_FILENAME);
});
$existingMigrations = DB::table('migrations')->pluck('migration');
$missingMigrations = $fileMigrations->diff($existingMigrations);
if ($missingMigrations->isEmpty()) {
$this->info('✅ All migrations are already recorded.');
return 0;
}
$lastBatch = DB::table('migrations')->max('batch') ?? 0;
$nextBatch = $lastBatch + 1;
foreach ($missingMigrations as $migration) {
DB::table('migrations')->insert([
'migration' => $migration,
'batch' => $nextBatch,
]);
$this->line("✔️ Added migration: <info>$migration</info>");
}
$this->info("🎉 Added " . $missingMigrations->count() . " missing migration(s) to batch $nextBatch.");
return 0;
}
}
Explanation:
- Get all filenames list from the
migrations
folder. - Get all migrations list from the
migrations
table. - Check a difference between two lists and return 0 if no difference found.
- If there is a difference, get a last migration batch and create new batch by adding 1 to this batch number.
- Add all migrations available in the difference with new batch number.
Step 3: Run the Command
If you are running Laravel < 11, register the command file in app/Console/Kernel.php
:
protected $commands = [
\App\Console\Commands\SyncMigrations::class,
];
In Laravel 11+, there’s no need to register commands manually.
Now, run the following command in your terminal:
php artisan sync:migrations
You’ll see output like this:
✔️ Added migration: 2024_12_31_235959_create_users_table
✔️ Added migration: 2025_01_01_000000_create_orders_table
🎉 Added 2 missing migration(s) to batch 4.
Caution
This command does not execute the migrations. It assumes the database schema already reflects them. Use this only when you’re sure the migrations were already applied, e.g. from another environment or a database import.
Conclusion
This approach is a safe and Laravel-friendly way to fix out-of-sync migrations. It’s perfect for developers working across multiple environments or restoring production databases.
Want to take it further? Add a prompt or backup feature to this command. Let me know in the comments!