Practical Guide to Git: Part I

Practical Guide to Git: Part I

Let’s start with a classic XKCD covering the situation.

This is the first from a collection of posts of the type “Zero to Hero”. So first things first…

What is Git?

It’s a version control system for text files, so teams can work on the same files and track the changes. Its most popular use is with source code, as it was built for speed and distributed software development in mind.

Did you mean GitHub?

No, Git is not GitHub, Git is the system originally developed by Linus Torvalds & Co that GitHub, GitLab, BitKeeper and many other web portals are built around. They are also the reason for the explosive growth of adoption of version control (VCS for short going forward) in enterprise and open-source development. Other systems, such as SVN also exist, but currently Git is supposedly the one to “rule them all”, due to its speed and flexibility. However, alternatives exist, you can find a well curated list here.

Assumptions

From here onwards I’m assuming you have basic familiarity with the unix shell (cd, ls, which, rm, cp, etc.) and how to use a text editor like vim, emacs or nano. Most of the things we are going to do are shell-based and the only UI we’ll work with is on the GitHub web pages, in the following parts of the Practical Git series.

Installing Git

I have covered briefly how to install git in my post on how to set up Z Shell. But I’ll list the commands here as well.
For Mac OS

sudo brew install git

and for Linux (Debian-based Distributions)

sudo apt-get install git-all

or for Fedora

sudo yum install git-all

Creating a repository from scratch, .gitignore and README.md

You can use mkdir to make a directory and cd into it. Then run

git init

to “initialize” a repository. As the system is not meant to track binary files which will result from compilation for example, you can create a file called “.gitignore” and put inside any extensions or filepaths you don’t want git to track going forward.
For example, you can run

vim .gitignore

and have it contain the following text:

*.o
*.tsk

that will exclude everything that ends in *.o or *.tsk, if you want to include, rather than exclude, you can put in a ! in front of the path. For example: !*.cpp,
the only instance I can think of where you’d actually use include in the .gitignore is if you have it exclude everything, but a subfolder or small set of files.
Example contents would be:

/*
!/only_include_this_folder

You can also create a sample README.md file in the folder with that usually describes the project as it gets picked up by the web portals such as GitHub automatically.
For now you can fill it with any dummy text of your choice.

Git Status, Add, Rm, Commit, Log, Blame

Now that we have 2 files – .gitignore and README.md, you can run

git status

to see which files are “Tracked” and “Untracked”. This area is called “Stage”
to do your first commit, you need to add the files using the git add command. I use

git add .

to add all files, or you can do manually each replacing the . with the specific filepath. If you want to delete and untrack a file, you can use “git rm”, which WILL delete the file and git will stop looking for it. Once done, you can commit using git commit, but it will open a new screen to enter commit information. Thus the most popular shortcuts are

git commit -m "commit message"

as it’s a oneline commiting, followed by

git commit -am "commit message"

which adds and commits at the same time the existing files. Be descriptive of your commits, you’ll thank yourself later.

To check the history of commits you can use

git log

and

git log --oneline

for the more abbreviated version. Each commit has a unique id in the form of a SHA1 code, this code is how we’ll be referring to particular commits going forward and it’s also the mechanism of how the contents of the files are stored in the background. You can also use the first 6 characters, rather than the entire SHA1 key.Last, but not least is my favorite command:

git blame filepath

which display the editor’s name next to every line of the file, so you know who to “blame” if the code doesn’t compile. This one gets fun when you have a large group of people working on the same project.

Branching, Git Branch, Git Checkout

Branches is the killer feature Git has. It allows you to quickly create copies of your current code and develop completely different stuff on the same code simultaneously. Its primary use is when you have to fix say 1 bug and add 2 new features. You can create 3 branches of the last working project code and work on each independently and switch throughout and once done merge into your main branch called master, which you get by default, that branch is not special in any way, compared to the rest you create. Use branches extensively, one truly appreciates their value only after working a while with Git. They are very cheap to create, and help keep your main codebase tidy, when you do multiple things at once.

To create a branch named new_feature, you can use:

git branch new_feature

to switch to that branch, you can run:

git checkout new_feature

to create a new branch and switch to it immidiately:

git checkout -b new_feature2

To get a list of all of your branches:

git branch

To delete a branch:

git branch -d new_feature2

Changes we make to the code in new_feature2 will not reflect in master.
To merge the changes you’ve done in the new_feature branch to master, run:

git merge new_feature master

Next up, working with remotes and where GitHub comes in.

Leave a Reply