Rationale for Existence

There are several tutorials on git. I am sure that there are other articles that serve exactly the same purpose as I do, but there is nothing like an article I write to express exactly what is in my head.

This article will explain Git for just one use-case. It aims at being a quick-start-kit for a bunch of people who are planning to work on a project and have never used any VCS before. They most certainly aren't looking to learn about rebasing or cherry-picking. I wouldn't be able to teach anybody the plumbing given that I am not too sure of them myself. They need a way to provide file-level undo and collaborate/merge easily. They also would like to use github.

I wrote a huge section about why VCSs exist. I found it very distracting and so I removed it from this article. You can read it here

I Just Don't Git It

The Config File

This is the first thing you ought to do when you plan to use git.

In a shell, type out the following
$ git config --global user.name "Your Name"
$ git config --global user.email userid@domain.com 

Let me put a couple of "rules" on the table here.

This will set your user-name and E-Mail IDs to the values supplied. The --global flag here indicates that the values are set for all future git invocations.

To do so, you need persistent storage, right? That is where the $HOME/.gitconfig kicks in. The commands above actually went ahead and stored data in a file in your home directory.

[user]
  name = Your Name
  email = userid@domain.com

Git groups together different configuration attributes under different sections. (For instance, [user]).

For the moment, you are done setting up your config file. Do look at the manpage for git-config for further options if you are interested.

Get a Github account

Go to Github and create an account for yourself. Once you have created an account for yourself, go to Account-Settings -> Account Admin Copy your github API Token. Though it is mentioned already in the site, I re-emphasize Keep it secret.

As before, open a shell and type out
$ git config --global github.user your-github-usernae
$ git config --global github.token yourtoken

Note, as before, that in your $HOME/.gitconfig file, there are two new fields under a new section, in this case, [github] .

You need ssh keys for working with github This again is a Get-The-Job-Done kinda section. If you are interested, google on creating ssh key-pairs

$ ssh-keygen -C userid@domain.com

That command creates a new RSA keypair for you. Let the defaults stay. Type in your password when prompted. Remember this password. There is NO WAY you can recover it. After this, you get two files in your $HOME/.ssh directory. Copy the contents of id_rsa.pub. The id_rsa file is your private key. Make sure you do not accidentally paste that instead.
Paste it in the box that you get on clicking "Account Settings -> SSH Keys -> Add New Key" in Github and click add key. You can give your key a meaningful name like Laptop-Fedora or SystemsLab-Debian etc so that you know which key belongs where.
Congratulations. You are now github ready.

Initializing a Repository

The best time to start using Git to manage a project is before you start the project.
$ git init projectName 

That creates a new directory with the name supplied. Now whatever you put into that folder can be controlled by git [Even here, it won't not until you explicitly ask it to]. This is the directory where you will be working in from now on. Your project must be contained in this directory

Opening Git's Eyes

Now, let us assume you have a bunch of files in your project directory. You are worried since Git doesn't seem to be doing anything magical yet. That is true. Git isn't. It is blind to new files. It will not monitor any files under its directory unless you ask it to.

$ git add file1 file2 file3

The command above makes git start monitoring file1 file2 and file3. Most of the time, you would want to recursively add all the files present in the current directory, its subdirectories and so on. For this, you can use

$ git add . 

The add command has two functions.

  1. It gets the files under git's surveillance.
  2. It makes git add the files to the staging area, which is like the launchpad from where git on a commit command makes a checkpoint
Files once tracked are always tracked unless you ask git to stop caring about them with the remove command. Staging, however is not a one-time process. You will have to restage modified/freshly-added files before you commit. You can unstage file using git reset HEAD -- filename . Reset unstages it but does not stop tracking. git rm filename both unstages and stops tracking the file.

Getting Git's Status

$ git status -s

You can see that the files you just added are marked with an "A" before them. This A stands for added. Similarly, "M" is used for Modified, "R" for renamed and "D" is used for Deleted. The status actually is two characters long. The First character is the status of the files in the staging area with respect to the previous commit-point. The second is the status of the files at the current instant to the files in the staging area (from the add that occured previously). You see only one of two characters because you do not have a commit yet. You will see both the characters only when you have added a few files to the stage that haven't been committed yet and also have modified/deleted some files which are currently staged.

$git status
	

I ♥ status

The git status command is my favorite. It is unbelievably helpful. It almost knows what you should do next. In an empty repository it hints that you add files. After staging, it shows you how to unstage. After committing, it shows how you can revert a file to a checkpoint and prompts you to add new files to the stage etc.
When you need more detailed explanation, git help and man are always around

Committing your Changes

The moment has arrived. You have a set of changes that work and have added the files to the stage. Now you want to make a permanent mark that you can go back to any time you want.

$ git commit -m "Message" 

Commit makes an indelible checkpoint. You can now do whatever you want with your working directory, even a rm * and always get back the files as they where when you committed.

When Do I commit

A common doubt is when a commit should be done. Commit is most certainly not equivalent to the Save Option in your editor. Once you commit, your commit point will be visible in logs. People [not only you] can go back to the commit point at will. They would be pissed if they realize that the commit you made actually did not work.

The general rule for commit is that you commit when a particular feature is complete or when a milestone is achieved. Yes. You could have intermediate commits too. But mark so in your commit messages so that no one reverts to them. At a commit, it should be possible to at the very least compile the codebase. The features that you aren't currently editing shouldn't be affected and the feature that you are editing should have some sane "Not Implemented Yet" style message. This is however, more of a guiding sign and not a rule. git doesn't know anything about compilation. You might use git for your poetry collection just as efficiently as you use it to manage your world-domination application. However, good habits take time to sink in. Follow the guidelines unless you have a good reason not to.

Log

Use the log command to see the list of commits till now.
$ git log 

UNDO UNDO UNDO!!!

I promised you that git can rever the state of a file from a checkpoint however badly you messed it up in the current directory. (Even if you deleted it) This is how you do it.
$ git checkout -- filename 
This list of files is similar to that in add
 
$ git checkout -- . 

will bring the whole repository back to the checkpointed state. This is like a mega undo button that you have that works across several reboots, several sessions and several files

Integrating a Github Repo Into the Project

Now that you have a small codebase working, you would want to Github it. Create a repository on github. Click the New Repository link . Give your project the same name as you gave locally, this saves some effort later on. Once you have done that, it is time to notify our local repo that there is a remote repository we know that it should collaborate with now on. Get the link from the github page of the project (Choose ssh and copy the link along with the git@ inside the text-box next to it)
$ git remote add origin linkYouCopied 

Pushing changes to Github

You should push your changes to the repository in github so that others/you can use it somewhere else.
$ git push origin master

The repository at github now gets the entire history of changes you made!!!. So if someone else collaborating with you wants to checkout the code as it was during your second commit can still do so. AWESOME, right?

Updating the Github Copy

If you are the only person on the project, github still provides a safe remote copy in case your hard-disk decides to fail. In this case, you can keep pushing to the remote repo by using git push origin master as before. However, if you are working with others, they would be working on the code too. So they would be making changes and pushing to github too. So before you commit, it is imperative that you pull from github first, ensure that you have no conflicts, commit and push back. This is done by the commands below.

$ git pull # I am not going to cover merging here. Look elsewhere.
$ git commit -m"Message"
$ git push origin master
Remember to always pull before you push when working with collaborators