Getting started with GIT for Version Control

GIT version controlGIT is a de-centralised version control system. A version control system manages the state of a ‘repository’ as it is called. A repository can contain an entire application, a single file or something in between. A version control system keeps a history of all changes in the repository. This is handy for a person working on their own in that they can access previous changes to their work if they find they are going down the wrong route. It is especially useful for teams of people working on the same work. Multiple people can contribute their changes and the entire history is available to everyone in the team.

By being de-centralised, GIT differs from some other version control systems like Subversion (SVN) that stores the history of the project on one central server — a single point of weakness if the project were to become corrupted or lost. With GIT, all users have a full working history of the project so the problem of a central repository is solved.

GIT has many features beyond simply tracking changes within a repository. For example, branching is useful for working on a feature of a project without affecting the main project. Once you are happy with a feature, you can merge your changes in the main branch. All the daily-use features of GIT will be discussed in this article.

First of all, let’s take a look at what a repository might look like:

.git/
.gitignore
README
index.html
css/
– styles.css

This is what a very simple website might look like in a GIT repository. There are 2 things to notice. First, the .git/ directory. This contains the entire history of the repository. Unlike SVN, a .git/ directory only appears in the root of the repository and not in every sub-directory as well. Secondly is a file called .gitignore. This is a plain-text file containing line-separated rules that tell GIT to not track the changes of specific files. For example you might want to disable tracking of cached files, config files etc that would be be unique to each person working on the project.

First make sure you have GIT installed on your computer (link in the useful resources at the end of this post). I assume you are using Linux or Mac — I have no experience with using GIT on Windows…

OK, so how do we create a repository? Navigate to the root path of the directory you want to become a repository in the terminal and type:

Your directory is now a repository! At the moment GIT knows about the files in the repository but isn’t doing anything with that information. The files are in an ‘untracked’ state. There are three state to be aware of.

untracked/unstaged ——> staged ——> committed

A file that GIT hasn’t seen before, such as a newly added file (or in the case of a newly initialised repository like above, all the files are new to GIT) is labelled as untracked. If a file has been modified or deleted since the last commit, it is labelled as unstaged.

You can check the status of your working copy by issuing the following command:

This will show you which files are untracked, unstaged and which are staged. Staging a file means that you want to commit it to history of the project. To stage a file type:

You can also issue variations on this command to stage different things:

This stages multiple files by space-separated paths.

This stages all untracked and unstaged files.

Once your files are staged and you want to commit those changes to the history of the repository, you type:

It is important that you write a commit message (in fact GIT won’t allow you to commit changes without one) because this will be used by yourself or others in the future to quickly identify the purpose of the commit. An example of a commit message might be “Fixed a bug in the CSS that was floating the header to the left”.

You can also stage and commit in one move:

It is good practice to commit your changes regularly so that you can go back to previous versions incrementally if something goes wrong rather than just committing when a feature is complete.

Once your changes are committed to the repository’s history you can type:

This will show you the history of your repository. Each commit gets a unique identifier which can be used to return your working copy to that commit. By typing:

you revert your working copy to that commit. Note that you don’t have to type the entire commit identifier — the first 6 or 7 characters are usually unique enough for GIT to realise which commit you mean. By checking out a different part of the history of the project, you will notice that the actual files in the directory will change to reflect the history of the project at the time of the commit.

You will actually need to stage and commit these files if you want to save this back to the top of the history as this will become a new commit. But if instead you want to go back to the top of the history just type:

HEAD is a special identifier that always points the last commit of the project.

Perhaps you want to see exactly what you’ve changed rather than just what files you changed since the last commit (remember, use git status to see what files are untracked/unstaged). You can use the following command:

This will show the lines in the files that have been changed. Red lines represent lines that have been removed and green lines show new lines that have been added. Red lines followed by green lines show where you have modified a line or lines (GIT assumes you removed the lined and replaced it with a modified version of the line)

To just get a summary of the changes (just the number of lines added/removed for each file) type:

There are various other commands that are useful for manipulating the status of a staged file, such as git reset , git rm  and git mv  but I won’t be discussing them here.

Next up, we’re going to look at branching. Branching is a great feature of GIT. Say for example that you want to start an experimental feature of a website that you’re not sure will work out (it’s experimental after all). You can create a separate branch to work on that feature while keeping the main branch (called ‘master’) clear to do your main work. You can create a branch by typing:

This also switches you to working on the new branch. Any work you now do will be committed to this branch (which also contains all the history up to the point at which you branched off). You can carry on using GIT in the same way until you are happy to merge the changes you made in this branch into the master branch (or perhaps just discard the branch as it didn’t work out).

You can get a list of branches by typing:

To switch between branches, just type:

This reverts your working copy to that branch.

To merge the changes from the experimental branch into the master you must first checkout the branch you want to merge into (in this case master). Then type:

This will merge the changes you made in the experimental branch into the master branch along with the history of commits you made while you were on that branch. Most of the time this works fine, but occasionally you may have modified a line in a file in the history of both branches — this causes a merge conflict. GIT will put merge conflict markers in the file that the conflict occurred in. You can manually edit the file and select the version of the line(s) you want to keep and then mark the file as resolved by typing git add conflicted_file_name  and then committing the change. The merge conflict is then resolved.

Finally if you want to delete a branch (make sure you don’t have it checked out at the time) you can type:

This concludes our simple look at how branching works. Next we’ll look at at how to contribute with others.

Perhaps you are not the initiator of a project. But someone else on you team has made their repository available to you. You can clone their repository along with the entire history of the project by typing:

This will clone the repository into your current directory. There are several protocols used to make a remote repository available, git://, ssh:// and http(s)://. There are advantages and disadvantages to each that you can explore yourself.

You can also create a repository on a remote server that everyone on your team has access to. You can then set the remote repository that your local repository should look for when pushing and pulling changes to and from the remote server. Just type:

The remote_name is an identifier that you will use for pushing/pulling. Once you have added the remote repository you can fetch changes from the remote server by typing:

Then to merge the fetched changes into your master branch:

You can also combine the 2 command into one (which I find more useful):

If you have multiple remotes and/or you want to pull a certain branch down to your local repository, you need to type:

After resolving any conflicts you now have the latest working copy from everyone on the team.

To push your own changes to the remote repository, type:

or

I always find it beneficial to pull and resolve any conflicts before pushing my own changes. Pushing your changes doesn’t need to happen as regularly as your commits — maybe once or twice a day depending on how your team works.

There are many complicated working patterns that a team may develop when implementing a version control strategy. For example, you may want all team members to push changes to a particular person that dictates whether to include them in a master repository. Or maybe you might have a testing remote repository that you push changes to for testing on a replica of the production server before pushing to the production repository itself. The sky is the limit for coming up with better ways to work with others.

That’s about all you need to know to get started with GIT. There are of course many more advanced features like stashing, tagging, hooks etc that I haven’t talked about here but the following resources are a great place to start if you want to delve deeper.

Some great GIT resources

http://gitref.org/
http://git-scm.com/book
http://git-scm.com/downloads

GIT repository hosting

The following links point to websites that you can use to host your repository online. You can make the repositories public or private (there may be a charge for private repositories). There are some great features to using these sorts of sites, especially for working with others (such as issue tracking)

https://github.com
https://bitbucket.org

GIT GUI clients

If using the terminal is getting you down or you’re more of a visual person then maybe using a GUI client might be for you. Here is a non-extensive list of free and paid-for applications:

Tower – Paid – Mac
Gitbox – Paid – Mac
GitX (L) – Free – Mac
Git Extensions – Free – Windows
SourceTree – Free – Mac, Windows
git-cola – Free – Mac, Windows, Linux
SmartGit – Paid – Mac, Windows, Linux
GitEye – Free – Mac, Windows, Linux

Leave a Reply