My migration from Laravel 4.2 to Laravel 5.0 with git history

First of all I want to have my git history in place for each file.
This leads me to the slightly different approach during migration than official upgrade guide suggest.

Official upgrade guide is safest way to migrate your project, but you can try to adjust it and preserve history.
This will be pretty complicated if your project is big, not structured correctly (eg. you haven't namespaces your domain logic, helpers...), not documented or not tested.


I did this on my blog as a proof of concept.
I thought it will be quick task, but it took more time than expected.

Before we dive, this was status at beginning:

  • + Project is relatively small
  • + A lot of project has been namespaced
  • + I'm the only one who worked on this, so even undocumented parts are known to me
  • - Pretty small percentage is covered with tests

Prepare for migration

It is good idea to have dump of your project extracted for reference, before you start migration. And one fresh copy of Laravel 5 as a reference where to move files, what to add/remove/update.

Desktop is great place for WiP files, or you can put it somewhere else.

mkdir ~/Desktop/laravel-migration && cd $_

Prepare fresh copy of Laravel 5:

composer create-project laravel/laravel laravel5 "~5.0.0"

Chose your prefered technique to export copy of your project. Just aim to have it in ~/Desktop/laravel-migration/my_project.

Create new git branch where you'll commit everything related to migration, eg. feature/laravel-5.0.

You should use IDE/editor with git support and move files that way, or use git mv via terminal. This ensures git knows how to track history for your files.

At this point I have my project open in IDE and ~/Desktop/laravel-migration/laravel5 open in editor for references. At any point I can open ~/Desktop/laravel-migration/my_project and check old version withoud switching git HEAD from my upgrade branch.

Open official upgrade guide, you will need it for for additional details (eg. changed API of some classes, changed namespaces).

The easiest thing to migrate is namespaced code from old project if you had it, eg. app/Acme. You can just continue to use it, and internally fix dependencies namespaces, eg. Eloquent models.

Move files and dirs to new location

  • app/config/ -> config/
  • app/database/ -> database/
  • app/tests/ -> tests/
  • app/models/ -> app/ (you should namespace your models, and update namespaces in relations or load classmap, consult official update guide)
  • app/controllers/ -> app/Http/Controllers/ (and update namespaces or load classmap)
  • app/assets/ -> resources/assets/ (if you stored your assets within app dir)
  • app/lang/ -> resources/lang/
  • app/views/ -> resources/views/
  • app/commands/ -> app/Console/Commands (don't worry about namespaces yet, fix them latter)
  • app/routes.php -> app/Http/routes.php
  • app/start/*.php to new places (explained in Laravel's documentation) and remove dir

Copy from fresh Laravel 5 project

  • .env
  • .env.example
  • artisan
  • phpunit.xml
  • phpspec.yml
  • server.php
  • app/Console
  • app/Commands
  • app/Events
  • app/Handlers
  • app/Http
  • app/Providers
  • app/Services
  • bootstrap/app.php
  • bootstrap/autoload.php
  • config/compile.php
  • config/filesystems.php
  • config/session.php
  • config/view.php
  • database/seeds/DatabaseSeeder.php (and import your seeder calls if you used it)
  • public/index.php
  • resources/lang/en/passwords.php
  • resources/lang/en/validation.php (merge your messages if you edited this file in your project)
  • storage/

Remove files and dirs

  • app/storage/
  • vendor/
  • composer.lock
  • config/remote.php
  • config/workbench.php
  • config/*/ - Environment specific configurations are not supported anymore (you should extract those to ENV variables)
  • database/production.sqlite - If you don't use SQLite in production
  • bootstrap/paths.php
  • bootstrap/start.php

Update .gitignore

  • Remove composer.lock

  • Remove .env.*.php

  • Remove .env.php

  • Add .env

  • Copy database/.gitignore from Laravel 5

Update composer.json

  • Remove unnecessary dev dependencies from composer.json to avoid migration problems, and bring them back latter if required!

  • Upgrade your composer.json based on one generated in new Laravel 5 project, most important parts:

    "require": {
      "laravel/framework": "5.0.*"
    },
    "autoload": {
      "classmap": [
        "database"
      ],
      "psr-4": {
        "App\\": "app/"
      }
    },
    "autoload-dev": {
      "classmap": [
        "tests/TestCase.php"
      ]
    }
    

Check if you need to update those files

  • config/app.php - use old "key" value as fallback option, eg. env('APP_KEY', 'oldKeyValue')
  • config/auth.php
  • config/cache.php
  • config/database.php - keep in mind you might need 'port' configuration for MySQL DBs
  • config/mail.php
  • config/queue.php
  • If you used laracasts/validation package replace it with Laravel's form request
  • If you have anything important in BaseController class move it to App\Http\Controllers\Controller class
  • If you used Illuminate\Pagination\Paginator class you should probably migrate it to Illuminate\Pagination\LengthAwarePaginator class (follow the official guide for migrating method calls)
Show Comments