Sunday, December 30, 2012

Creating a Spree application


Spree is an open source e-commerce platform that is available as a ruby gem for Ruby on Rails framework. It is intended as a foundation over which developers can build their own e-commerce sites.

Prerequisites

To use Spree you will need to install following:
  1. ruby
  2. imagemagick
  3. nodejs
  4. libxml2
  5. libxml2-dev
  6. libssl-dev
  7. libxslt-dev
  8. postgresql
  9. postgresql-server-dev-9.1
If you are using Ubuntu, you can easily install all of these from repos using aptitude. Imagemagick is required for resizing uploaded images. PostgreSql is selected because it is common in the hosting platforms but if you are not concerned about it, you can simply replace it with sqlite or anything else that you like.

Steps

After installing the above listed softwares, install bundler, rails, rake and spree gem using following command:
gem install bundler rake rails spree
Now create a new rails application. The default database is Sqlite, so we need to specify that we want postgres:
rails new myspreeapp -d postgresql
Edit config/database.yml and add host: localhost to all configurations and also correct database name, username and password. Next, add spree to your app. To do this run following command from withing your applications root directory:
spree install
This will run a wizard which will ask your choices for running migrations, loading seed data and others and perform the required actions. When the wizard ends your spree application is ready and you can now run it on local host using:
rails s
Your basic spree applications is now available at http://0.0.0.0:3000. You will most probably want to customize this application according to your needs. Head over to spree customization guides for a detailed look at customizing spree.

Friday, December 7, 2012

Git: Beware of detached head

In git, every commit is recognized by a 40-character hash known as commit hash. A git repository is essentially a tree of commits, where each commit points to its ancestor(s). In git, a branch head is the last commit in the branch. A Git branch is simply a pointer to this commit, using its commit hash, in the repository. These pointers are kept in .git/refs/heads directory as files. If you look at one of these files you will find that each branch corresponds to a single file which contains nothing but a 40-character commit hash of the commit representing branch's head. So when you have a master branch, there is a file .git/refs/heads/master pointing to head commit of this branch.

There is a difference between a branch head and HEAD. As described earlier, a branch head is the last commit in the branch, whereas HEAD represents your currently checked-out commit. It is also maintained as a pointer in .git/HEAD file. Normally this pointer will point to the head of currently checked-out branch, thus the name HEAD, but it is quite possible for this pointer to point to a commit which is not the branch head. So , for example, if you are working on branch master and you have checked out the head of this branch, the contents of the .git/HEAD file will look like following:
adnan@adnan-laptop: test/> cat .git/HEAD
ref: refs/heads/master
So, in this case, the HEAD points to head of branch master, which then points to a commit. This means that you have currently checked-out head of the branch master. Now if you move one step backward and checkout a commit just before the head commit, you will get a detached HEAD.
adnan@adnan-laptop: test/> git checkout HEAD^
Note: checking out 'HEAD^'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
  git checkout -b new_branch_name
HEAD is now at 123fa7b1... my 1st commit comment
A detached HEAD is a situation where the HEAD pointer is no longer pointing to a branch head. In this case the file .git/HEAD doesn't contain a reference to a branch head but instead directly points to the checked-out commit using its commit hash.

If you now check the contents of .git/HEAD file, you will see it contains the hash of the commit you just checked-out.
adnan@adnan-laptop: test/> cat .git/HEAD 
123fa7b17a2d28fced849ee1bb76e7391b93eb12
It is totally okay to work with detached heads but it is very important to understand the situation as any commits made in this situation will not be part of any branch, as you are not at the branch head, and the only way to refer to it later on will be using its commit hash. Also git garbage collection will run occasionally and remove any commits which are not referenced, directly or indirectly, by a branch or a tag.