Quick Primer For ‘git’

There are many good tutorials on the internet on ‘git‘, the famous distributed version control system designed and developed by Linus Torvalds using C language. However, I observed that my students, who are not familiar with the concept of version control at all, find these tutorials quite overwhelming. So, I felt like writing a simple tutorial to introduce the concept of  version control and basic git commands to achieve that.

As an example, we will take case of development of a software for solving quadratic equations using C language. For this project, first, we have to create separate folder (directory). In this folder, the software and its (git) repository would be stored. We will name the folder as ‘learning-git’. To create a repository from scratch, we use the ‘init’ command of git. Initializing a repository creates a sub-folder with name ‘.git’. The interaction goes as shown below-

sanjay@kitenagpur ~ $ mkdir learning-git

sanjay@kitenagpur ~ $ cd learning-git

sanjay@kitenagpur ~/learning-git $ git init
Initialized empty Git repository in /home/sanjay/learning-git/.git/

sanjay@kitenagpur ~/learning-git $ ls -a
.  ..  .git

We will now write the program to solve a quadratic equation. I use vim editor to create source files. Using it, I created the first version as follows-


/* quadratic-equation.c */
#include <stdio.h>
#include <math.h>
main()
{
  double a, b, c, d, r1, r2;

  printf("Enter coefficients of your quadratic equation (a, b, c): ");
  scanf("%lf%lf%lf", &a, &b, &c);

  d = b * b - 4 * a * c;
  d = sqrt(d);

  r1 = (-b + d) / 2 / a;
  r2 = (-b - d) / 2 / a;

  printf("Root 1 = %0.3lf\nRoot 2 = %0.3lf\n", r1, r2);
}       

Next, we will  compile this program and check its correctness by running it on the test data. It goes as follows-

sanjay@kitenagpur ~/learning-git $ gcc quadratic-equation.c -lm

sanjay@kitenagpur ~/learning-git $ ./a.out
Enter coefficients of your quadratic equation (a, b, c): 1 -8 15.75
Root 1 = 4.500
Root 2 = 3.500

sanjay@kitenagpur ~/learning-git $ ls
a.out  quadratic-equation.c

To understand where we have reached, let us inspect the state of our repository with ‘status’ command of git:

sanjay@kitenagpur ~/learning-git $ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	a.out
#	quadratic-equation.c
nothing added to commit but untracked files present (use "git add" to track)

The output of ‘git status’ command shows that git sees two files in our folder and none of them are tracked. The term ‘untracked file’ means that we have not told to git to record the changes in different versions of that file.

We are ready now to store this version of the program in our repository. It is achieved in two steps. First using ‘add’ command of git we ‘stage’ a file, meaning thereby that we ask git to track that file. Out of the two files in our folder, we are going to stage only ‘quadratic-equation.c’. We are not bothered about staging ‘a.out’ file because it can always be re-created using the source file.
In the second step, we issue ‘commit’ command to tell git that the present state of the software is a major milestone to which we may refer to in the future. Also, using ‘-m’ switch, we attach a small description to this commit.
After committing, I issued the ‘status’ command again. To understand what is going on, compare the output of this command with the output of the ‘status’ command given earlier.

sanjay@kitenagpur ~/learning-git $ git add quadratic-equation.c

sanjay@kitenagpur ~/learning-git $ git commit -m "Quadratic equation solver, version 0.1"
[master (root-commit) 5ec6f8c] Quadratic equation solver, version 0.1
 1 file changed, 19 insertions(+)
 create mode 100644 quadratic-equation.c

sanjay@kitenagpur ~/learning-git $ git status
# On branch master
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	a.out
nothing added to commit but untracked files present (use "git add" to track)

Assume that after this stage, you discussed the program with your colleagues and somebody pointed out that it lacks the capability to deal with equations having imaginary roots. So you modify the program and change it to second version, which is as follows-


/* quadratic-equation.c */
#include <stdio.h>
#include <math.h>
main()
{
  double a, b, c, d, r1, r2;

  printf("Enter coefficients of your quadratic equation (a, b, c): ");
  scanf("%lf%lf%lf", &a, &b, &c);

  d = b * b - 4 * a * c;

  if(d < 0)
  {
    printf("The roots are imaginary.\n");
    return;
  }

  d = sqrt(d);
  r1 = (-b + d) / 2 / a;
  r2 = (-b - d) / 2 / a;

  printf("Root 1 = %0.3lf\nRoot 2 = %0.3lf\n", r1, r2);
}

After the editing, you would compile the program and run it against test data. If you are satisfied that it is working as expected, you would commit this version with appropriate descriptive message.

sanjay@kitenagpur ~/learning-git $ gcc quadratic-equation.c -lm

sanjay@kitenagpur ~/learning-git $ ./a.out 
Enter coefficients of your quadratic equation (a, b, c): 1 2 3
The roots are imaginary.

sanjay@kitenagpur ~/learning-git $ git add quadratic-equation.c

sanjay@kitenagpur ~/learning-git $ git commit -m "Added 'imaginary roots' case handling"
[master 8f3b196] Added 'imaginary roots' case handling
 1 file changed, 7 insertions(+), 1 deletion(-)

After some days of writing this version, it may be possible that a situation arises where you want to input data to your program through command line arguments instead of through ‘scanf’ function. So, once more you modify the program (third version), so that it looks as shown below-


/* quadratic-equation.c */
#include <stdio.h>
#include <math.h>

main(int argc, char *argv[])
{
  double a, b, c, d, r1, r2;

  sscanf(argv[1], "%lf", &a);
  sscanf(argv[2], "%lf", &b);
  sscanf(argv[3], "%lf", &c);

  d = b * b - 4 * a * c;

  if(d < 0)
  {
    printf("The roots are imaginary.\n");
    return;
  }

  d = sqrt(d);
  r1 = (-b + d) / 2 / a;
  r2 = (-b - d) / 2 / a;

  printf("Root 1 = %0.3lf\nRoot 2 = %0.3lf\n", r1, r2);
}

We compile the latest version of the  program, run it for the test data and if the results are as per our expectation, we commit this version. The interaction would go as follows-

sanjay@kitenagpur ~/learning-git $ gcc quadratic-equation.c -lm

sanjay@kitenagpur ~/learning-git $ ./a.out 1 -8 15.75
Root 1 = 4.500
Root 2 = 3.500

sanjay@kitenagpur ~/learning-git $ git add quadratic-equation.c

sanjay@kitenagpur ~/learning-git $ git commit -m "Input through command line arguments"
[master 316b149] Input through command line arguments
 1 file changed, 4 insertions(+), 3 deletions(-)


Now comes the real power of ‘git’. Let us assume that we want to discard the “Input through command line arguments” approach and stick to our previous line of development, i.e., of taking the input through ‘scanf’. For this, we will have to go back to second commit state from this last (third) commit state. The ‘git log’ command gives information about commit IDs; adding ‘–oneline’ switch to it gives the info in summary format.

sanjay@kitenagpur ~/learning-git $ git log --oneline
316b149 Input through command line arguments
8f3b196 Added 'imaginary roots' case handling
5ec6f8c Quadratic equation solver, version 0.1

The commit ID to which we want to return to is ‘8f3b196’. For that, we issue ‘checkout’ command with the commit ID and the file name as arguments.

sanjay@kitenagpur ~/learning-git $ git checkout 8f3b196 quadratic-equation.c

If you open ‘quadratic-equation.c’ in an editor, you would find that it has now the second version of the program. Please note here that commit ‘316b149’ (version 3) is not destroyed; you may verify that by issuing ‘git log’ command.  And in future, if we want to pursue again command line arguments approach, we are free to checkout that commit.

In my opinion, a student can start productively using ‘git’ with this knowledge. After executing several projects like this, the student would get insight to version control as well as more confidence in using ‘git’. Then, one can go deeper and the other ‘git’ related material on the internet would become easy to understand.

Summary of commands used above:
git init – to create blank repository.
git status – to display the current state of ‘staging’.
git log – to display ‘commit’ information.
git add – to add files to ‘staging’.
git commit – to add the staged files to repository.
git checkout – to go to particular commit state.


‘git’ installation
Installing git on Linux is easy.
For Fedora-based systems (I tested it on Fedora 15):

# yum install git

For Debian-based systems (I tested it on Ubuntu 14.04 and Linux Mint Maya & Qiana):

$ sudo apt-get install git

One thought on “Quick Primer For ‘git’

Leave a comment