An introduction to using Git
Oct 5, 2013
10 minutes read

Setting up Git

Installing Git

There are few ways to install Git on a mac (I will eventually add guides on Windows and Linux).

  • Install Xcode (and install the command line tools for an added bonus) Simply install via the App Store App.

  • Install via brew Providing you have brew installed (installation instructions on the site), then; once installed run [sudo] brew install git

  • Download direct from git-scm.com As it say’s on the tin, download and install.

Once you have found your way of installing Git, do a simple test buy running git status which should then return:

fatal: Not a git repository (or any of the parent directories): .git

Setting up Git

Setting up Git in it’s simplist form is adding your user credentials:

git config --global user.name "Joe Smith"
git config --global user.email "joe@smith.com"

You can also also change/add configs within your .gitconfig file which on a Mac can be found in your home directory ~/.gitconfig. For an example, your can view mine for extra basic configurable options.

Usefull tools

Command line

When using Git, terminal can be more useful then you think. The best addition to this is to install cheat sheet via RubyGems. This can be installed by running [sudo] gem install cheat. Once installed you simply run cheat git and it displays the document in vi mode. In this, I mean you use arrow up/down to navigate.

A quick guide will be displayed for you to view for those times of need.

You can learn Git within your browser on Github.com which will give you an introduction to Git.

Sourcetree

All functionality is as easy to use in terminal as it is in any GUI. However, there are times when the GUI gives you a better understanding of how certain methods and processes work.

SourceTree is available for Windows, Linux and from the App Store for the Mac.

It is something I have used for a while to get my head around Git as it allowed me to picture the commands better.

Clone or create a repository

Creating a repository

Creating a repository is as simple as git init within the desired directory. From there you would create files and Add then Commit to your repository.

An example of this would be:

git init
touch README.md
git add README.md
git commit -m "Add Readme file for instructions"

Once created, I would suggest creating your branches. That way you will be able to start getting into a workflow and used to switching between branches.

Cloning a repository

To clone a repository (Assuming you are using Github.com) run the following in directory you want the project to be stored:

git clone git@github.com:{username}/{repository}.git

When using Github.com as your hosting for your repository, I would suggest following this guide.

Once you have cloned a repository always work in your own branches so you don’t work in a working repository.

Sidenote

If your repository has been created locally and is empty, set up the code base if you are using a framework.

So,for example; if you were to work on a jekyll project you would then run in your desired directory jekyll new my-awesome-site.

Then you would Commit before working on the project so you can view the history of file or even revert to that point if needed.

Example:

cd ~/my/project/path
git init
touch README.md
git add README.md
git commit -m "Add Readme file for instructions"
git checkout -b dev
jekyll new my-awesome-site
git add *
git commit -m "Add initial code base of jekyll"
git push

Basic functionality

Git branches

Git branches are a way to create features on top of the code base without messing with the actual base of the project.

When working with branches I personaly use the following as default:

  • master –or– prod
  • acceptance –or– uat
  • testing –or– test
  • development –or– dev

These will be the branches in which you merge into when dev for your dev server, then test for your testing server followed by UAT and then into your master branch for release.

Git pull

git pull will update your current repository to match that of the remote repository. In this, I mean it will git fetch and then git merge the remote changes into your local copy of the repository. This is fine if you are wanting to update your local copy.

A good example of this would be if you have finished your recent changes to ‘my-great-new-feature’ and you want to create a new [branch][] called ’even-better-feature’. You would simply git checkout dev (or your main working branch) and then git pull. You can then git checkout -b even-better-feature and rock on with your new feature code.

Do not use this if you want to [fetch][] the changes from remote to local without running the risk of merging remote files into local files you have already changed.

Git fetch

git fetch is the safer way of managing your repository when working with a dirty repository. For example, you are half way through a modification which will could possibly be affected by a change made by another team member, without running the risk of changing anyfiles you have worked on, you would run git fetch on your dirty repository knowing you are safe from any unwanted merges.

Branch management

Say we want a new feature or a bug fix, instead of working directly on the master branch of the project we create a new branch like so:

git checkout dev
git pull
git branch <branch-name>
git checkout <branch-name>

or we can shorthand this by typing:

git checkout dev
git pull
git checkout -b <branch-name>

Now we have our branch we can make changes to the code base.

* Notice the git checkout <dev> and git pull at the start of the code block. This is a must as you want to ensure you get the latest code within the dev branch so you are working with up-to-date code for your bug fix or feature build.

Git add

When you have made changes by changing current code or adding files, we need to add it to the staging area when we are happy with our local testing. We can do this by adding all files in one go:

git add *

This is great to add all files in one go, but this is only relative to the directory you are in.

To add specific filenames, we can do the following, again depending where you are on the project tree, you may need to add the full path or cd to the root folder.

git add <filename> <filename>

Although considered bad practice to make multiple changes to a file or files for different issues or feature enhancements, you can find your self creating a feature by adding modifications that are related but not as one.

For example; you create a feature that includes a config file and certain functions need to access the config file. However, you have created the config.json and modified 3 functions to access this config, tested it works and are ready to commit. If we add them all in one go and commit all in the staging area, it will be a pain and can cause difficulty to revert to a certain revision. As in this instance, reverting to this commit on production due to a bug can cause these functions to possibly break the site completely. So, instead of git add * we look at the code by adding in hunks to further review the code before committing.

Git commit

Once your files are added, we can now commit those changes by doing:

git commit -m "<your-message-message-here>"

For ease of reading commits by another developer, I’ve always said to write you commit message like so:

git commit -m "Capitalized, short (50 chars or less) summary

More detailed explanatory text, if necessary.  Wrap it to about 72 characters or so.  In some contexts, the first line is treated as the subject of an email and the rest of the text as the body.  The blank line separating the summary from the body is critical (unless you omit the body entirely); tools like rebase can get confused if you run the two together.

Write your commit message in the imperative: 'Fix bug' and not 'Fixed bug' or 'Fixes bug'.  This convention matches up with commit messages generated by commands like git merge and git revert.`

Further paragraphs come after blank lines.
 - Bullet points are okay, too
 - Typically a hyphen or asterisk is used for the bullet, preceded by a single space, with blank lines in between, but conventions vary here
 - Use a hanging indent"

This way you will be able to look back at bug and feature commits and know exactly what has happend.

Git merge

Merging in its simplistic view is grabbing your amended code and merging into your working branch. For example, to merge your feature code into the working dev branch, your would:

git checkout dev
git pull
git merge <branch> --no-ff --no-commit

The options are

  • –no-ff :No Fast Forward. Combines all commits into one
  • –no-commit :Merge but do not auto commit, great for merge conflicts and further tweaks

Instead of writing a load to explain the merge conflicts, read the post on gitready merge for a better explanation.

Git hunks

The following git diff gives the changes that have been made:

git diff index.php
diff --git a/index.php b/index.php
index 07464de..26f5539 100644
--- a/index.php
+++ b/index.php
@@ -1,7 +1,7 @@
<h1>Hello World</h1>


-<h3>Git is just lovely to use?</h3>
+<h3>Git is suc a great tool to use?</h3>



@@ -9,4 +9,4 @@



-<footer>This is a foot</footer>
\ No newline at end of file
+<footer>This is a footer</footer>
\ No newline at end of file

As per above, there are several changes in the file, but we only want to add the second section of changes in this commit:

git add -p <filename>

You will then be asked what you would like to do with this:

git add -p index.php
diff --git a/index.php b/index.php
index 07464de..26f5539 100644
--- a/index.php
+++ b/index.php
@@ -1,7 +1,7 @@
1>Hello World</h1>

-<h3>Git is just lovely to use?</h3>
+<h3>Git is such a great tool to use?</h3>



Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? n

We select n and the next section is shown:

@@ -9,4 +9,4 @@



-<footer>This is a foot</footer>
\ No newline at end of file
+<footer>This is a footer</footer>
\ No newline at end of file
Stage this hunk [y,n,q,a,d,/,K,g,e,?]? y

We then select y and this section of the file changes will be shown in our staging area ready to commit.

When we do a git status you will see the file will be in both the Changes to be commited: and Changes not staged for commit:

git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   index.php
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   index.php
#

We can now commit the following changes only for the index file.

-<footer>This is a foot</footer>
+<footer>This is a footer</footer>

Git push

When you have made you changes and are ready to test on another server or make it live, you would then push all commited changes back to the repository like so:

git push

Extra Activities

You can learn git outside of, or before your project with Github’s try github. Alternatively, you can create an empty folder and git init within the folder and play around without effecting any other git repo on your machine…

More Reading

The following is a list of further reading and more detailed information of each section I have covered plus a lot more…

Enjoy!


Previous Next