DIY Magento: Using GitHub and Symlinks to Manage Your Magento Themes and Extensions

by on April 25, 2012

If you’re like most store owners running a Magento shop, you’re probably editing your store files via FTP. Maybe you have a test store set up in a different folder. You might even being doing it live on production!

There’s a better way to manage your code and deploy updates painlessly: Git.

In software development, Git (/ɡɪt/) is a distributed revision control and source code management (SCM) system with an emphasis on speed.[4] Git was initially designed and developed by Linus Torvalds for Linux kernel development. Every Git working directory is a full-fledged repository with complete history and full revision tracking capabilities, not dependent on network access or a central server.

Wouldn’t it be nice to do the following?

  • Keep track of all your code changes in a secure environment.
  • Collaborate on changes with others and see who changed what (now and for the future).
  • Stop deploying updates manually using FTP and push only changed files instead.
  • Use symlinks to update Magento on the fly without worrying about your themes or extensions.
  • Create separate “branches” of your source code to work on new features without disrupting your current code.

In this article I’m going to walk you through how to set up a GitHub account, create a repository for your store, show you some desktop applications that can help you use Git without the command line or terminal, discuss Git basics, create symlinks, and lastly how to deploy to production. Trust me, learning how to use source control is worth it!

Sign Up for GitHub

Go to Github and create a new account for $7/mo. This gives you 5 private repositories. If you’re going to include multiple people in your project go for the $12/mo package.

Getting Started with Git

Github provides a fantastic resource guide on everything Git for beginning to advanced users. We’re going to use their tutorials to get you started on Git and then I’ll dig into the Magento-specific details.

First let’s get the hardest part out of the way: You’ll need to set up Git and some SSH keys to securely upload and download files to your GitHub account. Follow GitHub’s guide and you should be up and running in less than 10 minutes.

Create A Repository

Now we just need to create a repository for your Magento themes and extensions. Here at Fast Division one repository handles all of our code but you’re free to separate various projects into different repositories.

Follow this simple guide to create a new repository. You’ll jump on Github, create the repo, and then return to the command line to make your first commit.

When you create a repo for the first time you might be wondering what you should include. The entire Magento folder? A separate folder with just your code? It’s completely up to you but here’s some smart choices:

The Quick Way: Add an entire Magento store with your code to the repository. Filter out unnecessary files such as /app/code/core later with a .gitignore file.

More Organized & Difficult: Separate your code. Make a new folder specifically for the repo and copy over the following folders (and more):

  • /app/code/local/*
  • /app/design/frontend/*
  • /app/etc/modules/*
  • /js/*
  • /skin/frontend/*

Now your code won’t run immediately after pulling from a repo, but you’ll be able to use symlinks and make your code completely version-agnostic. This means you’ll be able to pull down your code and test in any version of Magento. It isn’t stuck in a specific installation. We’ll cover symlinks later.

At this point you should have a GitHub account, a brand new repository, and committed your initial code to the repository via the command line. Next we’ll discuss how to keep track of your changes and collaborate with others.

Managing Your Git Repository

You can control your Git repository via command line or desktop application. Personally I prefer SourceTree for Mac because it makes it very easy for anyone to manage a Git repository. You don’t have to worry about learning all of the commands and it’s much more visual than the command line.

If you’re on Windows there’s a large variety of Git clients to choose from.

As you make updates to your code you’ll want to commit frequently. Here’s a common workflow you’ll be applying:

  1. Make changes to your Magento code.
  2. Commit those changes with a small explanation.
  3. Push your commits to GitHub.

The nice thing about Git is that everyone has a local copy of the repository on their machine. This means you can make changes and commit without having to push the changes right away. You can work without an internet connection and still enjoy the benefits of version control.

Another huge benefit to Git is collaboration. Now that you have a basic idea of how changes are tracked you may want one of your teammates to pull down your changes. Committing, pushing, and pulling is all you need to know to be productive with Git. Here’s how a teammate could collaborate:

  1. Your teammate makes a free GitHub account or uses an existing account.
  2. You invite your teammate to the Magento repository.
  3. Your teammate gets access and can now push and pull to the repo if they have their SSH keys set up.
  4. When your teammates makes an update you’ll pull the latest version of the repo.

After pulling the latest version you may run into conflicts when two or more people are editing the same file. These can easily be resolved and most desktop apps provide a tool to review conflicts.

Git has its complexities but this is all you need to get started. The next feature I suggest you look at is branches, which allow you to silo projects and major changesets into separate areas. For instance if you were upgrading to a new version of Magento and needed to make extensive changes you would create a new branch and merge that branch into your master (default) branch once the changes are ready for production.

Gitignore

If you decided to leave your Magento code inside an actual Magento store (no symlinks) you’ll probably need to use a .gitignore file to filter out certain files. Magento is a very big solution and including all of its files will only bloat your repository. Check out a sample gitignore file for Magento here, or use the gitignore file I typically use below. My copy allows a few extra directories you might be using when building themes or extensions.

app/code/community/Find/
app/code/community/Phoenix/
app/code/core/
app/design/adminhtml/default/default/locale/
app/design/adminhtml/default/default/template/
app/design/adminhtml/default/find/
app/design/frontend/base/
app/design/frontend/default/blank/
app/design/frontend/default/default/
app/design/frontend/default/iphone/
app/design/frontend/default/modern/
app/design/install/
app/etc/modules/Find_Feed.xml
app/etc/modules/Mage_All.xml
app/etc/modules/Mage_Api.xml
app/etc/modules/Mage_Authorizenet.xml
app/etc/modules/Mage_Bundle.xml
app/etc/modules/Mage_Centinel.xml
app/etc/modules/Mage_Compiler.xml
app/etc/modules/Mage_Connect.xml
app/etc/modules/Mage_Downloadable.xml
app/etc/modules/Mage_ImportExport.xml
app/etc/modules/Mage_PageCache.xml
app/etc/modules/Mage_Persistent.xml
app/etc/modules/Mage_Weee.xml
app/etc/modules/Mage_Widget.xml
app/etc/modules/Mage_XmlConnect.xml
app/etc/modules/Phoenix_Moneybookers.xml
app/etc/config.xml
app/etc/local.xml.additional
app/etc/local.xml.template
app/.htaccess
app/locale/en_US/
app/Mage.php
cron.php
cron.sh
downloader/
errors/
favicon.ico
get.php
includes/
index.php
index.php.sample
install.php
js/blank.html
js/calendar/
js/extjs/
js/flash/
js/index.php
js/jscolor/
js/lib/
js/mage/
js/prototype/
js/scriptaculous/
js/spacer.gif
js/tiny_mce/
js/varien/
lib/3Dsecure/
lib/flex/
lib/googlecheckout/
lib/.htaccess
lib/LinLibertineFont/
lib/Mage/
lib/PEAR/
lib/phpseclib/
lib/Varien/
lib/Zend/
LICENSE_AFL.txt
LICENSE.html
LICENSE.txt
mage
media/
nbproject/
pear
pear/
php.ini.sample
pkginfo/
RELEASE_NOTES.txt
shell/abstract.php
shell/compiler.php
shell/indexer.php
shell/log.php
skin/frontend/base/
skin/frontend/default/blank/
skin/frontend/default/blue/
skin/frontend/default/default/
skin/frontend/default/french/
skin/frontend/default/german/
skin/frontend/default/iphone/
skin/frontend/default/modern/
skin/install/
var/

Symlinks

Symlinks, or symbolic links, are shortcuts to files and directories. Think of it as a link or reference that points to something.

ln -s ~/magento-source-control/app/design/frontend/my_theme/ ~/magento-live-store/app/design/frontend/my_theme

The first path in the “ln” command is the directory we’re referencing. The second path is the location of the symlink itself. Pay special attention to the use of slashes. Notice the reference path includes a trailing slash since we’re referencing a folder.

What makes symlinks so useful? Simple: It let’s you separate your custom code from your Magento installation. That way you don’t have to constantly move your custom code over to a new Magento folder when you upgrade. It’s also useful for testing and source control because it removes the Magento bloat and makes your code transportable.

You can either set up the symlinks by hand or even better, write a bash script to automatically add symlinks for your folders. Once you’re done setting up the symlinks you need to jump on to your Magento admin panel and go to System > Configuration > Developer. Enable symlinks:

Here’s a rough sample of my symlink bash script. Use this code at your own risk! It’s Mac-only and requires Homebrew to be installed.

#!/bin/bash
# Adds symlinks to all of the folders for a new Magento installation
echo -n "Enter the path to your Magento installation: "
read -er MAGEPATH
 
# Sample Path:
# /Users/Jake/Sites/magento-1.7
# No backspace!
 
# brew install coreutils for greadlink
ln -s "`greadlink -f ./app/design/frontend/avalanche/`" "$MAGEPATH/app/design/frontend/avalanche"
ln -s "`greadlink -f ./app/etc/modules/FastDivision_All.xml`" "$MAGEPATH/app/etc/modules/FastDivision_All.xml"
ln -s "`greadlink -f ./app/code/local/FastDivision/`" "$MAGEPATH/app/code/local/FastDivision"
ln -s "`greadlink -f ./js/avalanche/`" "$MAGEPATH/js/avalanche"
ln -s "`greadlink -f ./skin/frontend/avalanche/`" "$MAGEPATH/skin/frontend/avalanche"
 
echo "Symlinks set up!"

If you primarily develop Magento extensions you should look at Colin Mollenhour’s Modman (Module Manager) on Github. It makes it much easier to deploy extensions, keep them organized in version control and set up symlinks on the fly.

Deploying to Production

Uploading your files via FTP is old school! It’s time to start deploying your repository to test and production servers. It’s faster, more secure and much easier. You no longer have to worry about which files were changed, accidentally overwriting something, or taking your store down for extended maintenance. Although it will take some initial set up time the preparation is worth it. You’ll need SSH access to your server to get started.

Deploying is simple: Your server will pull the latest version of the repo from GitHub. To do this we’ll need to install Git and authenticate the server by setting up SSH keys. Same as before. All set up? Syncing is easy as:

git pull

That’s it! Just be wary of including .htaccess and config files (/app/etc/local.xml) in your repo if deploying to production. It could interfere with your production configuration.

You can take it a step further and set up automatic pulls but I only recommend this for your test installation. Pull manually when you’re ready to deploy to production.

Wrapping Up

This article served as a basic introduction to Git and how to use source control for your Magento projects. If you have any questions about how to set up your repository or deploy leave a comment. Good luck and enjoy the benefits of version control!

  • http://www.wiziq.com/tutorial/251882 Jonathan Hays

    Hey that was really needful. Thanks for sharing. I’ll surely be looking for more.

Previous post:

Next post: