Introduction to Git

Last modified: 01-22-2015

Git is perhaps the most popular version control tool for software developers now. Compare to svn, it takes a little more time to learn, but more powerful, and who has learnt the basic usage will find it actually easier and more convenient to use :) Here we’ll provided a tutorial about the basic usage of git, which covers most of the functionalities we need during daily developments.

Git is distributed

In svn, there’s a central repository, everyone will need to sync with this central repository, and commit to it. However, git is distributed: a repository can be locally, but also can be on the remote server. One can make changes to his local repository without changing the repository on the remote server, thus won’t affect other people who’re using the same remote repo. He can choose to fetch down the changes on the remote repo and merge into his local repo, or push the changes in his local repo to the remote repo to share with others, at any time he wants.

What’s more, git support branches, both locally and remotely. The default branch is master branch, but everyone can create or delete branches as they want. One can switch between different branches in the local repo very easily to develop different features in different branches, and push the changes to the corresponding branches in the remote.

Create a Repo

There’re two ways to create to repo to start to work on.

If there’s an existed git repo, and you want to start your work from that, you can use checkout

>> git checkout {url or path to the remote repo like, https://github.com/WebCoursify/webcoursify.github.io.git}

Or, if you want to create a brand new repo, you can use init

>> cd [the directory you want to create the repo, doesn't match empty or not]
>> git init

Now you have a working repo locally.

Save file changes

In git, the way to make your changes persistent is to commit the changes. To do this, you’ll first need to add the files you have changed and want to save:

# add a file or a directory recursively
>> git add {filepath} 
# tell git you want to remove this file, and this does actually remove it
>> git rm  {filepath} 
# add all changes you make within the current directory and the subdirectories
>> git add .

You can use git status to check the local repo status. For example, at this very moment when I’m writting this post, I’ll see:

>> git status

On branch master
Your branch is up-to-date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   1-IntroToGit.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	index.md

I just use git add to add the file “1-IntroToGit.md”. Now, I want to permanently (actually not really, because we can always rollback…) save the change, I could just:

>> git commit -m "just doing a demo"

Now when I type git status:

>> git status

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	index.md

nothing added to commit but untracked files present (use "git add" to track)

We can use git log to check the history of our modifications:

>> git log

commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # This is the commit id
Author: XXX <xxx@xxx>
Date:   Thu Jan 22 20:49:50 2015 -0500

    just a demo

...

By checking the log we can rollback to a previous point. For example, we want to go back to the point of a specific commit, just find its commit id, then we can:

>> git reset --soft {commit id}

And then you can undo the things you regret. Magic! For more details about reverting and rolling back, please refer to other online resources like this one cuz we’d like to kepp this tutorial simple.

Playing with Branch

Branch in git is extremely useful. One example is we can develop and test feature A on branch one, develop and test feature B on branch two, and A and B won’t interfere with each other until the moment they’re finished and merged into the same branch.

Here’s how to create a branch

>> git checkout -b [branch name]

Switch to a branch

>> git checkout [branch name]

Merge branch B into branch A

>> git checkout A
>> git merge B

Another approach is:

>> git checkout A
>> git rebase B

There’s a great post explaining the differences. Both approaches are used a lot.

And of course, we can delete a branch:

>> git checkout -d [branch name]

Sync with Remote Repo

In git, one can make a local repo keep track of multiple remote repos (which are identified by different names) at the same time, but we only need one in most of the time.

The default name for the first remote repo will be origin. If you use git checkout to create a local repo, then it’s already tracking the remote repo you checkout from as the origin. If not, you need to add a remote repo first. Do this by:

>> git remote add origin {url or path to the repo}

Now, the way to fetch remote changes is:

>> git fetch origin

Now, for example, if there’re updates on the master branch of this remote repo, you can merge these changes into your local master branch by:

>> git checkout master
>> git merge origin/master

Or, you can just use git pull, which is just first fetch then merge.

Now you want to push the saved changes on your local master branch to the remote master branch (remember you need to commit the changes you want to save first), just:

>> git checkout master
>> git push origin master