How to setup GIT for Magento extension development

How to setup GIT for Magento extension development

The idea behind this article is to show how we can use GIT for Magento extension development. What we want to achieve is a git repository that contains only the files specific to our extension, and not the entire Magento. This kind of repository can then easily be pushed to GitHub or other remote public repository so that entire community benefits from your work.

Entire process described below is a result of a slight frustration of GIT submodules functionality and .gitignore file limitations. Or at least my understanding of the two :).

If we break down the structure of a valid Magento extension, we see that this is not that easy to achieve, or at least not that straight forward with the GIT’s .gitignore file.

Let us dive into the extension structure first. Imagine our company name is Inchoo and our module name is Persona (as in Mozilla Persona).

Here is the folder structure that should be sufficient to hold all of our extension files:

/app/etc/modules/Inchoo_Persona.xml
/app/code/community/Inchoo/Persona/*
/app/design/frontend/default/default/layout/inchoo/persona/*
/app/design/frontend/default/default/template/inchoo/persona/*
/skin/frontend/default/default/css/inchoo/persona/*
/skin/frontend/default/default/js/inchoo/persona/*
/skin/frontend/default/default/images/inchoo/persona/*
/lib/inchoo/persona/*

Usually you will see extensions use /app/design/frontend/default/default/layout/inchoo_persona.xml in place of what I personaly prefer /app/design/frontend/default/default/layout/inchoo/persona/somefile.xml. Its all the same to Magento. For the sake of this article, we will stick to my way /app/design/frontend/default/default/layout/inchoo/persona/*.

Now that we have the all the possible directory structure outlined we have a foundation upon which we can build our solution.

Imagine your Magento installation is installed under /Users/branko/www/magento1702_ce/ folder. This is a clean Magento installation, without any custom coded added to it. This installation/folder is not a GIT repository.

Now imagine you need to build Inchoo_Persona when you are done you would like to push it to a GitHub repository, but only the extension related files, not entire Magento.

You create another folder, lets say /Users/branko/www/magento-extension-inchoo-persona/ folder and you create the above mentioned folder structure within it. One you create all of the subfolders you then go back to /Users/branko/www/magento-extension-inchoo-persona/ and do a “git init”. This will be our GIT repository for this extension. Remember, folder /Users/branko/www/magento1702_ce/ that holds our entire Magento installation is not a GIT repository. Folder /Users/branko/www/magento-extension-inchoo-persona/ does not hold any of the Magento files, only the files you create for that extension.

Now we can move on to the next step, that is symlinking.

ln -s /Users/branko/webapps/magento-ext-inchoo-persona/app/etc/modules/Inchoo_Persona.xml /Users/branko/webapps/magento1702_ce/app/etc/modules/Inchoo_Persona.xml
 
ln -s /Users/branko/webapps/magento-ext-inchoo-persona/app/code/community/Inchoo/Persona/ /Users/branko/webapps/magento1702_ce/app/code/community/Inchoo/Persona
 
ln -s /Users/branko/webapps/magento-ext-inchoo-persona/app/design/frontend/default/default/layout/inchoo/persona/ /Users/branko/webapps/magento1702_ce/app/design/frontend/default/default/layout/inchoo/persona
 
ln -s /Users/branko/webapps/magento-ext-inchoo-persona/app/design/frontend/default/default/template/inchoo/persona/ /Users/branko/webapps/magento1702_ce/app/design/frontend/default/default/template/inchoo/persona
 
ln -s /Users/branko/webapps/magento-ext-inchoo-persona/skin/frontend/default/default/css/inchoo/persona/ /Users/branko/webapps/magento1702_ce/skin/frontend/default/default/css/inchoo/persona
 
ln -s /Users/branko/webapps/magento-ext-inchoo-persona/skin/frontend/default/default/js/inchoo/persona/ /Users/branko/webapps/magento1702_ce/skin/frontend/default/default/js/inchoo/persona
 
ln -s /Users/branko/webapps/magento-ext-inchoo-persona/skin/frontend/default/default/images/inchoo/persona/ /Users/branko/webapps/magento1702_ce/skin/frontend/default/default/images/inchoo/persona
 
ln -s /Users/branko/webapps/magento-ext-inchoo-persona/lib/inchoo/persona/ /Users/branko/webapps/magento1702_ce/lib/inchoo/persona

Once you run these commands (remember you need to use your paths, not mine :)) you will get effect as if your Inchoo_Persona code is living right there in /Users/branko/www/magento1702_ce/ folder, meaning your Magento installation will see the Inchoo_Persona extension.

There is however one more thing you need to do in your Magento installation under /Users/branko/www/magento1702_ce/ folder. You need to login to Magento admin, go under “System > Configuration > Advanced > Developer > Template Settings > Allow Symlinks > Yes” (thanks to Tsvetan Stoyhev for reminding me of this one :)).

Now you can open your favorite text editor / IDE, lets say Netbeans, point it to /Users/branko/www/magento1702_ce/ folder and start working on adding the code files under the Inchoo_Persona directory structure. These code files will actually end up in the proper /Users/branko/webapps/magento-ext-inchoo-persona/ folder and from there you can easily add/commit/push them in your GIT repository. Its important to know that the above mentioned linking is something you need to do only once. Since you symlinked folders, each file / subfolder you create within that folder is visible by Magento.

At first, entire process seems a bit too much to handle, but in practice its really quick. I personally like it because it does two things for me: (1) it forces me to follow and respect Magento extension directory structure, (2) it enables me to have a GIT repository with just my extension files that I can then easily push to GitHub.

In case you find this approach a little “too much”, you can read the Ashley SchroderUsing Git submodules and @import with Modman for Magento” article that demonstrates the use of Colin Mollenhour modman deployment script. It sort of works on a similar approach, utilising the symlinks.

Hope it helps, cheers!

You made it all the way down here so you must have enjoyed this post! You may also like:

How to generate SSH keys for Git authorization Hrvoje Ivancic
, | 21

How to generate SSH keys for Git authorization

Magento 2 Product Quick View Tomas Novoselic
, | 5

Magento 2 Product Quick View

How I learned to stop worrying and love 3rd party modules for Magento Luka Rajcevic
Luka Rajcevic, | 2

How I learned to stop worrying and love 3rd party modules for Magento

10 comments

  1. I just initialise the repo with the full Magento load, then start adding stuff to the .ignore file; you can force land your repo on any Magento version and makes it easier to include some Magento config stuff if you need to.

  2. I went with installation scripts that launch through a makefile. It’s a very short fairly easy reconfigure script. All it does is try an rsync -van ( vn is for verbose a dry run ) and then it asks if I want to continue. I included a silent mode to work with makefiles.

    I’ve found symlinks are hairy with some existing modules I have to maintain, and magento deems allowing them unsafe.

    I still have to version control the entire installation for deployment purposes. I still have to look into better CI and configuration management solutions.

  3. And what if I need to edit extension that has own repo and I don’t have blank Magento project.
    If I have magento project repo can I:
    – create branch submodule_name
    – add submodule as git submodule
    – using modman create sym links
    – edit submodule
    – commit changes only in submodule_name branch of magento project
    – push the changes only to remote submodule repo (not affecting remote branch of magento project repo)

    How I should do the last two steps?

  4. Thank you for the article. It saves my life.
    I want to publish some modules on Github and this technique it the best wat till now.

  5. Branko, the advantage of using modman is that the mapping of symlinks can be committed to your git repo so that the next fellow doesn’t have to type all of those “ln -s …” commands or copy files around, or when you take your repo into production you don’t forget a critical symlink, or the next dev to work on the project isn’t banging his head on the desk. My primary Magento project uses currently 429 symlinks in 92 modman files in 21 separate repositories. Managing those without modman would be… hell. A dev environment can be setup by simply extracting Magento and cloning the necessary modman modules.

    On committing Magento into your repo or not, I like to setup the primary Magento directories in my IDE as include paths so that the IDE (PhpStorm) doesn’t treat them the same as my project files. Also, git commands get kinda slow with everything in one huge repo..

    FYI, I just updated modman today to create relative symlinks instead of absolute symlinks since it seems lots of users like to move their Magento folders around in their file system and/or commit the symlinks to their repositories. I suppose if you did the commit every file to your repo thing you could commit your symlinks and then not need to use modman, but you’ll eventually want to have one of your modules in a separate repo (DRY) and then that approach will no longer work.

  6. Nice idea, Branko 🙂
    With .gitignore, it’s possible to ignore all magento folder and add only needed files/directories, forcing them (git add -f path/to/file.ext).
    In that case, you have all Magento directory structure in the IDE (some like it, others don’t. I do.).

    One great advantage of your solution is that it would be easier to test under several Magento versions (without having to push/pull the repository for every Magento version every time a change was made to the code).

  7. Interesting article!

    Have you ever tried git patch for extension development? I find this approach quite easy to use. I develop on a blank installation of Magento, then start a new branch with my extension, and as soon as I have something ready, I create a patch and apply it to an empty repository. This patch contains of course only files included in the newly created module.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.