Getting started with Git

Project at FOSSASIA Google Code-In 2015

What is Git?

Git is a distributed version control system. It's free, open source, and can handle various types of projects fast and efficiently, allowing groups of people to work on the same documents together. Google, Facebook, Microsoft, Twitter and Netflix are some of the many companies that use Git. It's easy to learn and can be downloaded from here. Every Git working directory is a repository (there, Git begins version controlling your files) with history and version-tracking capabilities.

git config

Using the git config command, we can specify some Git settings. One important configuration we need to make is setting the name and the email address, for example:


    $ git config --global user.name "Elena Iusco"
    $ git config --global user.email elenaiusco@example.com
        
Because we're using the --global option, Git will remember and use these informations for everything we'll be doing.

git init

This command initializes a new repository, and it's usually the first one to be run, since most of the other Git commands won't work outside a repository. If my current directory is C:/John/, the result would look like this:


    $ git init
    Initialized empty Git repository in C:/John/
        
This allows it to start tracking changes of the project. Typing git init directory will create a repository in the specified directory. Both will create a hidden .git directory, where the necessary data is contained.

git status

The git status command will show you the state of both the working directory and the staging area (the staging area is a file that stores information about what will go into your next commit). Basically, it tells us which files are staged (ready to be commited), unstaged (not yet ready to be commited), and untracked (not yet tracked by Git). For example, let's say that I've added a cheese.txt file to the working directory. After typing git status, it would look something like this:


    $ git status
    # On branch master
    #
    # Initial commit
    #
    # Untracked files:
    #   (use "git add ..." to include in what will be committed)
    #
    #	cheese.txt
    nothing added to commit but untracked files present (use "git add" to track)
      
It is a good idea to run git status often.

git add

A change is made in the working directory. git add adds that change to the staging area. Basically, it tells Git that you want to include the files' updates in the next commit. So, to tell Git to start tracking changes made to cheese.txt, we need to add it to the staging area using git add:


    $ git add cheese.txt
    $ git status
    # On branch master
    #
    # Initial commit
    #
    # Changes to be committed:
    #   (use "git rm --cached ..." to unstage)
    #
    #	new file:   cheese.txt
    #
      
Notice that it says Changes to be committed. This means that our file is in the staging area and ready to be committed! You can also use wildcards, for example git add '*.txt' will add all text files to the staging area.

git commit

To store the changes we've made so far in the repository, we run this command while also specifying what changes we have made.


    $ git commit -m "First commit! Yay!"
    [master b00f045] First commit! Yay!
      1 file changed, 10 insertions(+), 2 deletions(-)
      
And so, the staged snapshot is commited. Unlike other version control systems, Git tracks the entire content of a file in each commit, not the differences between versions, making it much faster. After making a commit, we get a message telling us the number of changed files and the number of insertions and deletions made to the file(s).

git log

The git log command shows us the committed snapshots, allowing us to see the project history. It works like a journal, remembering the changes we've committed. If we've made 2 commits, git log would display something similar to this:


    $ git log
    commit 3852bbeb1634463d0bb4d267edb7b3f9cd02ace1
    Author: name < email >
    Date:   Thu Dec 24 17:30:45 2015 +0200

        Add all txt files

    commit 104bedfd888cd3d5e7fcb857d0dabc5a0fcb5e28
    Author: name < email >
    Date:   Thu Dec 24 12:53:16 2015 +0200

        First commit! Yay!
      
Use git log --summary for more information about each commit.

git push

Using this command, we are able to make transfers from our local repository to a remote one. Its general form looks like this: git push remote branch .


    $ git push -u origin master
    Branch master set up to track remote branch master from origin.
      
In the example above we pushed the changes to the origin repository on GitHub. The -u will make Git to remember those parameters, so the next time we can simply call git push.

git branch

A branch is an independent line of development. Using the git branch command, we can create, rename, delete or list branches, but pay attention, you can't switch between branches (that's git checkout's job, see below). Branches are used by developers so that they could work on more than one task at the same time.


    $ git branch
    * gh-pages
      master
      
git branch lists all of the branches in the repository. gh-pages is the current branch.

    $ git branch name
      
The above command creates a new branch.

    $ git branch -d name
    Deleted branch name (was b10fd05).
      
The above operation deletes that branch, altough Git prevents you from deleting it if it has unmerged changes. To force delete a branch, use git branch -D name instead.

    $ git branch -m name
      
Lets you rename the current branch.

git checkout

This command allows us to switch between branches (i.e between lines of development, between tasks).


    $ git checkout name
    Switched to branch 'name'
      
Once again, Git prevents you from switching to another branch before committing the changes made on the current one.

    $ git checkout -b name
    Switched to a new branch 'name'
      
Creates a new branch and switches to that branch. It is equivalent with running git branch name+ git checkout name.
Using git checkout -- name, we are able to take the files back to their state at the last commit.

git rebase

This command is used to combine, to merge changes from one branch to another branch. The following example moves the gh-pages branch to the tip of the master, and also includes the new commits in master. By using this command, we're getting a much cleaner project history, making it easier to navigate.


    $ git checkout gh-pages
    $ git rebase master
      

git stash

The git stash command is used when we are working on a part of a project and we want to switch branches to work on something else, but don't want to commit the messy work we've done. Stashing will take the messy state and place in on a stack, which we are able to access later. Take a look at the git status example. Changes are not committed, so we can't switch to another branch. After calling git stash, we will get something similar to this:


    $ git stash
    Saved working directory and index state WIP on master: 5e95fb5 Add all txt files
    HEAD is now at 5e75fb5 Add all txt files
    $ git status
    # On branch master
    nothing to commit, working directory clean
      
Notice that after using git status, everything's clean, so we can switch to another branch. Using git stash list, we can see all the stashes on the stack.

git reset

Using git reset, we can remove a number of commits from the current branch. It is a way to undo changes that are not yet shared with somebody else. The following command will make the last 3 commits be thrown away.


    $ git checkout gh-pages
    $ git reset HEAD~3
      
We can also choose between the 3 options of git reset: git reset --mixed is the default option, leaving the working directory unchanged, but bringing the staging area up to date to match the commit; git reset --hard will bring both the working directory and the staging area up to date to match the commit, whereas git reset --soft will leave both the working directory and the staging area unchanged.
Typing in git stash list will show us the stack of stashes.

    $ git stash list
    stash@{0}: WIP on master: 5e75fb5 message
    stash@{1}: WIP on master: c24f051 message
      
Use git stash apply to apply the most recent stash. You can also type in git stash apply stash@{number} to apply a specific stash.

    $ git stash apply
    # On branch master
    # Changes not staged for commit:
    #   (use "git add ..." to update what will be committed)
    #
    #      modified:   cheese.txt
    #
      
Let's commit one last time:

    $ git add cheese.txt
    $ git commit -m "We're finished!"
    [master b20a045] We're finished!
      1 file changed, 6 insertions(+), 2 deletions(-)
      

Hooray! These are the basic functionalities of Git. Visit git-scm.com to get it started, and also try GitHub, a Git repository hosting service. Happy coding!