Clone, Add, Status, Commit

By this time Harry is done faffing about and is ready to start coding.

Since this is Harry’s first time using Git, he first sets up his .gitconfig file with information that will be used to identify his commits in the log.

[user]
    name = Harry
    email = harry@futilisoft.com

Now he needs to get his own repository instance.

~ harry$ git clone http://server.futilisoft.com:8000/ ./lottery
Cloning into lottery...
warning: You appear to have cloned an empty repository.

Note that Git doesn’t have a checkout command. Or rather, it has git checkout, but that command is equivalent to Update. Git keeps the repository instance within the administrative area of the working copy, so git clone actually performs both clone and checkout.

Harry wonders if Sally has already done anything in the new repository.

~ harry$ ls -al lottery
total 0
drwxr-xr-x   3 harry  staff  102 May 17 07:55 .
drwxr-xr-x  21 harry  staff  714 May 17 07:55 ..
drwxr-xr-x   8 harry  staff  272 May 17 07:55 .git

Apparently not. Nothing here but the .git administrative area. Jolly good then. It’s time to start coding. He opens his text editor and creates the starting point for their product.

#include <stdio.h>
#include <stdlib.h>

int calculate_result(int white_balls[5], int power_ball)
{
    return 0;
}

int main(int argc, char** argv)
{
    if (argc != 7)
    {
        fprintf(stderr, "Usage: %s power_ball (5 white balls)\n", argv[0]);
        return -1;
    }

    int power_ball = atoi(argv[1]);

    int white_balls[5];
    for (int i=0; i<5; i++)
    {
        white_balls[i] = atoi(argv[2+i]);
    }

    int result = calculate_result(white_balls, power_ball);

    printf("%d percent chance of winning\n", result);

    return 0;
}

Typical of most initial implementations, this is missing a lot of features. But it’s a good place to begin. Before committing his code, he wants to make sure it compiles and runs.

lottery harry$ gcc -std=c99 lottery.c 

lottery harry$ ls -l
total 32
-rwxr-xr-x  1 harry  staff  8904 May 17 07:56 a.out
-rw-r--r--  1 harry  staff   555 May 17 07:56 lottery.c

lottery harry$ ./a.out
Usage: ./a.out power_ball (5 white balls)

lottery harry$ ./a.out 42 1 2 3 4 5
0 percent chance of winning

Righto. Time to store this file in the repository. First Harry needs to add the file to the Git staging area (which in Git’s terminology is called the “index”).

Note that Git’s staging area is similar to my notion of the pending changeset, but the semantics are different. The pending changeset is a list of changes in the working copy. The Git staging area can contain things that are neither in the working copy nor the repository instance.

lottery harry$ git add lottery.c

Harry uses the status operation to make sure the pending changeset looks proper.

lottery harry$ git status -s
A  lottery.c
?? a.out

Git is complaining because it doesn’t know what to do about that a.out file. Don’t panic! That’s a compiled executable, which should not be stored in a version control repository. He can just ignore that. Now it’s time to commit the file.

In my examples here I am showing git commit used with the -a flag. This makes git commit automatically detect modified files, like the other tools covered in this book. Without this flag, git wants you to explicitly git add any file which has been modified.

lottery harry$ git commit -a -m "initial implementation"
[master (root-commit) 9a0ca10] initial implementation
 1 files changed, 30 insertions(+), 0 deletions(-)
 create mode 100644 lottery.c