Posts Tagged ‘Git’

Migrating SVN apps to Git and Composer

23 Jul

Just recently I had to move a few remaining legacy CakePHP2.x apps from SVN to Git+Composer.
This serves as a short how-to.

You can also use this post if you are migrating a git app to a composer based git app.

Note: Installing a new CakePHP 2.x app with Git and Composer right away is dead easy and explained quite well in the cookbook. This post is more about migrating existing ones.

SVN + Composer/Git?

They can actually work side-by-side. For a migration process this can be useful, especially when migrating huge apps.
Then doing it piece by piece helps to avoid chaos.

For this little how-to the main repo will stay a SVN one until the very end for this very same reason.

First steps

We have our SVN repo – up to date thanks to svn update.
Download composer.phar in your APP dir. This file should be added to your excludes. Set up a composer.json file in there, as well, and commit it.

CakePHP Core

You might have hard-coded the core files in ROOT/lib/Cake – or used an svn:externals on ROOT/lib.
Either way, remove that and add CakePHP2.x as Composer dependency.

Update index.php and webroot.php

As per documentation, we now need this in those files:

define('CAKE_CORE_INCLUDE_PATH', ROOT . DS . APP_DIR . DS . 'Vendor' . DS . 'cakephp' . DS . 'cakephp' . DS . 'lib');

Resolve global vendors folder

In case you used a global vendors folder it will now not automatically be included anymore.
To quick-fix this, add this to your bootstrap.php (at the beginning probably):

App::build(array('Vendor' => array(ROOT . DS . 'vendors' . DS)));

This will load your App::import()ed classes again from that folder.
Same goes for the plugins folder, by the way.

In a second step you can then start moving those to the APP/Vendor folder – either as Composer dependency or hard-coded.

When all are transferred, you can remove the global vendors folder and also remove the additional App::build() call.

Resolve svn:externals for plugins

Most plugins will probably be hard-coded or included via svn:externals.
Remove the svn:externals and add them as Composer dependency.
Do the same for any plugins in your ROOT/plugins folder. If they are hard-coded there, move them to the APP/Plugin folder.

Almost done

At this point we already have a fully functional application again that loads all dependencies via composer – even though it is still a SVN repo.
All it needs is

cd .../root && svn update
cd app && composer install

If some global vendor libs are harder to migrate or the "svn to git" conversation is troublesome, you can take your time get it up and running again on this level just fine.
At some point you will have finished the migration though, then proceed to the final step.

Move SVN to Git

When all externals have been resolved, the root vendor and plugin folders have been cleaned and their content moved to the APP pendents, we can now start migrating
the application to Git.
For this we drop the usual /trunk/... folder structure and directly copy the APP folder from your SVN repo into the root of your new Git repo.
The ROOT folder itself serves no purpose anymore, and we can have APP as root folder now.
Therefore in root, you should now have the composer.json file.
For an example, see cakephp-sandbox.

As for "copy": You can either directly copy-and-paste your repo (quick and dirty), or use git-svn tools to preserve your changelogs/history.
The latter is the cleaner approach, of course. See this guide on how to do that. Some services like GitHub might also offer a git-svn push access or link useful tools. Those approaches usually need a folder move of the APP folder content to the root level then on top.

Either way, the more you composer and the less you hard-code your libs, the quicker and easier the svn…git transformation will go.

Now updating app + core + plugins + vendors is just:

cd .../root
git pull
composer install

Since the APP folder is now the root folder, no need to further cd deeper.


You may add

require_once dirname(__DIR__) . '/Vendor/autoload.php';

at the top of your bootstrap.php file to add autoloading via PSR for new namespaced repos (on top of the still working App::import() and App::uses() methods).

That means, that you can now use namespaces and third party packages via composer quite easily.
Let’s say we want to use the MediaEmbed lib in our project.
We then simply add it to our composer.json:

"require": {
	"dereuromark/media-embed": "dev-master"

In our CakePHP classes, e.g. an EmbedHelper, we can now use it right away:

use \MediaEmbed\MediaEmbed;
App::uses('AppHelper', 'View/Helper');
class EmbedHelper extends AppHelper {
	 * @param string $url Absolute URL of the video/audio.
	 * @return string|null HTML snippet or null on failure.
	public function media($url) {
		$MediaEmbed = new MediaEmbed();
		if ($MediaObject = $MediaEmbed->parseUrl($url)) {
			return $MediaObject->getEmbedCode();

Isn’t that awesome? You now have the full PHP5.3+ (GitHub) lib variety out there at your disposal. You might want to check out this list of cool libs.

Private repos

With the externals, it was quite easy to pull from your own repo URLs. Composer makes this a little bit more difficult.
To overcome the issue for GitHub private repos, for example, you can use vcs:

"require": {
	"your-username/cakephp-some-private-plugin" : "*"
"repositories" : [{
		"type" : "vcs",
		"url" : ""

Note that this will prompt once for your username and password and create a token for re-use:

Your GitHub credentials are required to fetch private repository metadata.
The credentials will be swapped for an OAuth token stored in …/Composer/auth.json, your password will not be stored.

Last tips

This tutorial assumes that you are properly using the current master (2.5.3 at this time) version of CakePHP. Always upgrade to the current master – never use anything older.

Make sure you have a current index.php/test.php file as well as a current APP/Console dir including those cake scripts (current as in master/2.5.3 at least).
You can just copy them over from the CakePHP source folder (Cake/Console/Templates/...) if you are unsure.
Especially for console this is quite important. Otherwise Console/cake might not work out of the box with the new composer approach – even though it would if you had up-to-date files.

Also, don’t forget to .gitignore all included dependencies (both Vendor and Plugin ones). And also the ones from SVN, composer.phar etc.

No Comments

Posted in CakePHP


Using Composer

30 Mar

There are quite a few good articles on this topic, already. Especially on how to leverage it for CakePHP projects.


So I won’t go into detail too much.
It is worth noting that composer really made a few things easier for us in the long run.
And I was really against composer and packagist at the beginning as I didn’t want to use more dependencies than necessary.
But that one sure is worth it if you use it right. And as every project pretty much uses it these days it is
fairly stable and future proof to rely upon.


Easiest way:
Download the phar and run php composer.phar [command]. You can just place this file into your app dir.
You can also install it more globally, of course to just have to run composer [command] directly. The above articles or the composer docs explain that in more detail.


In general you can either use the composer commands to add dependencies or you can directly modify the composer.json file via editor (note that some IDEs support that natively with auto-completion).
You also need to distinguish between "install" and "update" command. The first respects the current composer.lock file. The latter should only be used for development/staging, not for productive systems.
See the basic usage docs for more details.

Composer and CakePHP

Can I switch my 2.x git project from submodules to composer?

Most definitly, yes. And you probably should.
Using submodules really is a great annoyance, especially with the number of plugins increasing in a project.
Unfortunately, getting rid of them is also not always easy – but doable.

You need to

  • git submodule deinit <path/to/plugin>
  • git rm <path/to/plugin>

Which, under windows, for example can proof a little bit difficult sometimes.

Then re-add them to the composer file and don’t forget to exlude the folder in the .gitignore file.

Composer and CakePHP3.x

In 3.x composer will pretty much be the de facto standard for CakePHP. So it is worth getting used to it now.

A few tips and tricks

I can add least talk about a few things I came across working with composer now for a few months.


Version control system repositories can easily be included if they don’t support composer or if you need to run a modified version of a 3rd party plugin/dependency.
We then include the main source in the "require" section and add our specific (tweaked) fork as VCS in "repositories":

"require": {
	"josegonzalez/cakephp-wysiwyg" : "dev-master",
"repositories" : [{
		"type" : "vcs",
		"url" : ""	

Our version then contains some bug-fixes or additional stuff that needed it to branch off here.

dev prefix/suffix?

It kind of confused me when to use the suffix and when to use the prefix for "dev".
I found quite a look explanation from someone I added to this PR:

Basically dev releases are now simply branch names with a dev suffix for numeric branches which are comparable (3.0.*-dev) – or a dev prefix for textual names that are not comparable, like feature branches and master (dev-master)

You should authenticate the server/locally to avoid hitting the API limit

This page describes on how to generate an OAuth token and use this to avoid hitting the limit of requests per minute for GitHub.

Use proper user management to run composer commands

If you log in as root or any user that is not affialited with the www-data user, the files that are updated/created will most likely not be readable/usable.
And using chmor -r 777 * sure is a really bad idea, as well. It is better to create a user that shares the same rights/group as www-data and use this one to deploy or do any changes on the code.

If something aint working

Try it again first – sometimes there are failures in the communication between GitHub, Packagist and your local connection.

Also try the self-update command to make sure you are running a recent version of composer. diagnose can also tell you of there is something wrong.
Maybe you forgot to enable some required PHP extensions, like "curl" (which is necessary for it). But the error message usually tells you what exactly what the issue is.

Last Tip

You can also take a look at my enhanced Upgrade shell. Maybe it can help getting your code to the latest code-base.


Subversion and Git

30 Sep

They usually don’t play nice with each other. But what if we need a plugin/repository available for git AND for svn?

The "new" way

It used to work – but since a few weeks it doesn’t anymore.
It WAS possible to checkout any github rep via SVN. Sounds crazy, but that was really working:[user]/[repository]
Anyway – doesn’t seem to be to stable, yet. So I don’t use this approach anymore.

The classic way

This works no matter what Subversion or Git do. It relies on the fact that they don’t get mixed up.
We exclude the .git and .svn dirs from each others rep.

Let’s say we already have our svn rep. We also want it to be in git.
We first create an empty git rep in the root folder of the rep: "Git Create Rep here".

I assume you already have the following excludes in your global svn settings (called "global ignore pattern"):
_* .git .gitignore
As you can see, i also like to exclude all tmp files (starting with _ like "_test.php").

Create a .svnignore file in the root folder of the rep:


We want to exclude tmp files as well as all svn related stuff.

Now add your files to git "master", commit them and synch with your newly created git rep. Usually the url is something like:[user]/[repository].git

That’s it – your done!
They don’t interfere with each other. So there shouldn’t be any complications. Furthermore you can now chose which merging "engine" you want to use as they both work on the very same rep.

Live Example

Math Plugin: It is located in subversion (rep is not public, though) and in git. If I update the code, I just have to make sure, that i commit to both "sources". Otherwise one will be outdated.
Just to be sure you should consider ONE source the primary one. No matter what this should be the one to commit to, first.

No Comments

Posted in Git, SVN