Git deployment


This article shows proof of concept for git deployment.

It is completely irrelevant where do you host your code as long as you actually do have git repository ๐Ÿ™‚

It is not meant to be used in production environments unless you are aware what it does exactly.

This is just very basic semi-automated code transfer and nothing else.
You can play with it and maybe you can come up with something more useful and robust.

It can be used in order to deploy any git branch to some place where you did cloned your origin repository as long as you have ssh access to such a places ๐Ÿ™‚

So, there are few assumptions:

You are running Linux or MacOS.
-It could work for Windows as well if you are using git bash or something like that, but I haven’t tested it.

Create file in your project root directory and put this inside:


while getopts u:h:b:d: option
        case "${option}"
                u) USERNAME=${OPTARG};;
        	h) HOSTNAME=${OPTARG};;
                b) BRANCH=${OPTARG};;
                d) REMOTE_DIRECTORY=${OPTARG};;

Now, create another file at the same space called and put this inside:


cd $2
git checkout $1
git pull
rm -rf var/cache/

Commit, push and that’s it…

So, now what?!

Go to your project directory and use it like this:


Before you are able to do that, do this:
chmod +x

What will happen next is that it will just execute “git pull” on the server that you are deploying to, so keep your .gitignore in mind etc.
It also deletes cache, which is useless if you keep cache in memcache.

This is just result of me learning bash, it works for such basic stuff, but it is far from done, especially if you are using some CI tools etc.

It is great little toy though…

I hope you got idea how to start with coding your own deploy script using bash…

About Tomas Novoselic

Team Leader/Backend Developer

At Inchoo, Tomas is a Team Leader and Certified Magento Developer who handles Magento modifications at any level. He also works closely with clients on Magento projects of any size and difficulty.

Read more posts by Tomas / Visit Tomas's profile


  1. I do something similar, except I use the post-receive hook that calls a git checkout on the working tree and updates the files (after you push to the from the local repo to the remote one).

    This way I can make local changes, test them, then push them to either a production or QA for further testing without ever having to manually copy files.

  2. @thomas – the main reason we do a fetch and then a merge is because our clients do sometimes have access to the code (i.e letting an extension developer install an extension) and we have to be sure we don’t overwrite any changes. If this is never the case in your specific setup, you can safely just pull the master branch.

  3. Hi Tomas,

    What I did was installing an existing AMI from Bitnami that has Redmine installed already (they call it Redmine Stack), and we just need to click one button ๐Ÿ™‚

    free AMI, you only pay Amazon costs. The cost on a micro instance (Europe) is US$0.02 witch translates to around 16 dollars a month…

    after adding a Dynamic IP, and have that IP on a ANAME, I got to

    Have installed a nice theme (and tweaked the CSS to have a lighter impact), set up my Git acording to Bitnami tutorials

    and voilรก!

    Bitnami is very nice, they even have a Magento AMI ready to run ๐Ÿ˜€

  4. @Bruno – I have tried Redmine, but only to quickly check it out few months ago…
    It is nice piece of software, but unfortunately I’m not one to decide about integrating it in our everyday biz process. Since in general I’m more interested to use some hosted service, I’m more into JIRA. Is there any good hosted Redmine service out there?

    @Bas – Nice point! I’ll do that in the future even though I believe that if you stick to the workflow, master is still quite safe to be pulled. When it comes to git-flow, we gave up on it since for some reason we couldn’t make it to actually do “–no-ff” at the time, but I still didn’t gave up completely.

  5. We use the NVIE branching model. We use git-flow to ensure that we don’t go completely bonkers trying to remember the specifics of the model.

    We deploy manually using the master branch as ‘blessed’ for production. But – we never just do a git pull for various reasons as discussed here ( and here (

    Instead we do a git fetch. This gets all the changes from origin. Now we can do a git diff –name-only origin/master. This will show all the differences between the version that is currently on the live machine and the changes fetched from origin.

    This is your chance to inspect if there’s anything out of the ordinairy. If you don’t see anything wierd you can merge: git merge origin/master. If you do see strange stuff you can look what’s going on and fix possible errors before merging.

    Better safe then sorry!

  6. Hi, Tomas, thank you for the input.

    I’m actually writing for a suggestion to use Redmine with Git (I’m using gitolite for permissions).

    Redmine is awesome as it hooks all commits to your tickets and gives you a really nice integration.

    Give it a try ๐Ÿ˜‰

    P.S. I fallow the same NVIE model ๐Ÿ˜€

  7. Hi Tim,
    First script is running locally and second one is actually containing the code meant to be executed remotely.
    I would need to separate commands with “;” as an alternative, so I believe that in case code meant to be executed remotely increases for few more lines (and it will, as soon as I try to do something more advanced), readability would be nightmare imho…
    Regarding Capistrano… well… I don’t know… personally, I don’t like dependencies it requires compared to bash and in general last time we used it (I wasn’t the one who wrote recipes) every now or then, there were some bugs… and in general, all I do is actually executing set of commands that I would usually execute manually in the shell (if there wasn’t any script)… I don’t know… i just don’t look on that as “deployment”… for me, it is just automatic execution of few shell commands…can it be better than doing it in most native way possible? I don’t know, Capistrano (for ruby people), ant (for Java people), Phing (For PHP people) just seems like a tool to overcome lack of confidence in using any of unix shells…. Maybe I’m wrong though… In any case, I’m just investigating possibilities ๐Ÿ™‚

  8. Hi Tomas,

    Thank you for an article. I have two questions.

    1. Why don’t you merge your 2 shell scripts into one?
    2. What was the problem with Capistrano?

  9. Hi Nick,

    We use Github and to manage our code.

    How we deploy it is another story… we have tried many ways from capistrano, phing and ant to manual ssh & git pull + whatever needs to be done… In my personal opinion any way that results in scripting just to connect automatically to servers via ssh and then doing magic is kind of ok if all you want to do is to move the code (of course, you need to plan your gitignore carefully). When it comes to more serious deployments, we have tried in combination with phing, but then again for most of the projects I have found it little bit overhead so I can say that we are still trying to find some optimal solution. Right now I’m investigating what can we do with bash and hopefully this would result in having real Magento module for deployments that would somehow work in combination with bash… but … hard to say… every project is different and what is worst environments are very different so it is hard to standardize anything….luckily scripting some basic deployment is quite easy… it is much more important to have nicely organized repository.

  10. Thanks for sharing, Tomas!

    We’re also using git for deployment, but we do it without shell scripts. We have a repository with a master (live environment) and sandbox (test environment) branch and merge the sandbox into the master for each release.

    What do you guys use to manage your repositories?

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>.