Starting with git

Mahavir Parekh
8 min readSep 19, 2018

I have been working a long time in the software industry but until recently didn’t get a chance to play with git. At all my previous work places we used mercurial which is a fine distributed repository, however I got intrigued to learn and figure out how to transition to git from mercurial so I started with a sample project and set-up using git.

Here I plan to describe some basic workflows that I use with git coming from the mercurial world.

If you haven’t set-up your own repository system before but just used existing central repositories there are a few concepts that might be new here. Feel free to skip it if you are aware of them

Bare repository

Think of this as you backup server. i.e. you don’t actively work on this copy but instead you work on a local copy of the repository and routinely sync changes from your local copy to the bare repository. In typical environment this is the repository that is set-up for you on the server at your work environment. Git allows you to create bare repositories in different drives and not just on a server. However a lot of the usual workflow includes starting with a bare repository. We can use bitbucket.org or github.com to host our repositories and when you create a new repository on there, GitHub/bitbucket will automatically create the repository as a bare repository

In order to do that manually in a local/network drive you need to first open the directory in your terminal and then run the following commad:

#cd <path_to_your_directory>
cd git_test
git init --bare

Creating a central repository

At the time of writing this bitbucket.org allows you to create private as well as public repositories for small teams for free while github only allows public repositories for free. I am choosing github since I want this tutorial to be open sourced. You can choose either and everything still remains same

Once you set-up your account and login, there is an button on top right ‘+’ that allows you to create a new repository. Click on that a set-up a new repository with a name of your choice. In this tutorial, I have named my project ‘git_test’. Once created you should see something like this:

new repository page of github.com

This is going to act as your bare repository. When creating the repository github gives you the option to choose your LICENSE and README files and those are generally good to have, however if you have some local source code that you plan to use to initialize this repository creating an empty repository makes it a lot easier to start with.

Initializing with a local repository

If you have already created a local directory and added some code to it we will use that to initialize our repository.

.gitignore

One of the first things you want to do is tell git what not to track in the source repository. This is very useful when you have local files and folders that are needed for development environment but not the source itself for e.g. if you use VS code for development that there will be a .vscode directory under your folder. You don’t want to store this in your repository as it isn’t something everyone working on the project needs. We can set this up using the .gitignore file. (Note: You can create as many .gitignore files in any sub-directories as well to scope to the files within that sub-director’s tree)

Lets create a .gitignore file in your source directory and tell it to ignore some test file in order to understand this feature. I created 2 files in my directory: file.test and .gitignore and we are going to have git ignore any file that ends in .test

Add the following to you file.test

some test script goes here

Add the following to your .gitignore

*.test

Now lets set-up some configuration for git if you haven’t already done so. These settings are used to identify your commits in your repository

git config --global user.name <your name>
git config --global user.email <your email>

I have a sample file in my directory called README.txt. Now lets initialize git in this directory so we can start tracking changes to this direcotry

git inittree -aL 1 .
.
├── file.test
├── README.txt
├── .git
└── .gitignore

Now we have a basic git set-up locally. Lets see what git is tracking.

git status
On branch master
No commits yetUntracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
README.txt
nothing added to commit but untracked files present (use "git add" to track)

git knows that there are two items .gitignore and README.txt that have changed but not recorded. We can ask git to start staging them

# git add <file or directory>
git add .
# now lets see what git has changed
git status
On branch master
No commits yetChanges to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: README.txt

We can see from the output of ‘git status’ that there are two new files that git is now aware of. The next step is to commit the changes locally

#git commit -m <commit message>
git commit -m "setting up source"
2 files changed, 2 insertions(+)
create mode 100644 .gitignore
create mode 100644 README.txt

git has now recorded changes to our source and this becomes our local checkpoint. We can see all check points using ‘git log’

git log
commit 0126da85aeb10a462abcb4f839d7585ad303dfcb (HEAD -> master)
Author: <name> <email>
Date: Wed Sep 19 14:49:36 2018 -0700

Connecting your local repository to remote repository

In order to connect this to the github repository lets go back and revisit our repository page. In order for this to work you will have to configure github to recognize and authorize your local machine. Follow the instructions here https://help.github.com/articles/connecting-to-github-with-ssh/ and then continue below

# tells git that we want to set-up a remote repository identified
# by git@github.com:newt10/git_test.git and we will give it an
# alias of 'origin'
git remote add origin git@github.com:newt10/git_test.git
# tells git to push the current commits to the master branch
# on origin
# git push -u <destination> <branch>
git push -u origin master

Refresh your github repository page and you should see the changes from your local source directory here:

From now on our workflow is as follows:

  1. Create changes
  2. Stage changes
  3. Commit them locally
  4. Push changes to origin

Using branches

So far we have been working with just one branch called ‘master’ which is the default one that git created for us. Lets understand how to use branches to leverage the power of collaborative workflows in git. In git terminology ‘branch’ is used to create virtual and independent work streams.

Lets say we create a couple more commits called ‘commit 2’ and ‘commit 3’ our version history is going to look like picture on the left. The ‘tip’ is the last commit on a given branch (in this case master)

We can create additional branches to represent workstreams like in a web application you can create two branches called frontend and backend and use them for independent web development. Additionally you can create a branch called ‘in_progress’ to denote all the commits that you are commited and you want your team members to review them. Once they are reviewed you can merge them into master so that master now points to stable revision

Branching allows you to work on multiple commits in one particular focus so that there are fewer clashes between different

Lets go ahead and play with branching on git. We will create a new branch on github called ‘in_progress’ as shown in the picture to the right

Next we want our local repository to also reflect this change so lets sync and ask git to switch us to our new branch

git pull
Enter passphrase for key '/home/m/.ssh/id_rsa':
From github.com:newt10/git_test
* [new branch] in_progress -> origin/in_progress
Already up to date.
# ask git to switch to branch 'in_progress' for local work
git checkout in_progress
Branch 'in_progress' set up to track remote branch 'in_progress' from 'origin'.
Switched to a new branch 'in_progress'
# lets check our current branches
git branch
* in_progress
master

From the above output you can see that we are now switched to this new branch. I am updating README.txt so that I have some new changes to commit

this is a sample project to play with git commands
created a new branch on github
pulled and checkout to the new branch 'in_progress' in my local workspace.

Next lets follow our stage -> commit process to get ready to push this change

git add .
git commit -m "on a new branch"

We will use a similar command to upload our changes with the difference that this time we are push our changes to in_progress branch in origin (github.com)

git push origin in_progress

Now if you go to github.com you will see a new header showing that you pushed changes to your branch ‘in_progress’. Here we will do something called compare and pull request which basically means we will compare commits in in_progress with another branch and merge changes into the new branch. This allows others to review the code before we can push it to our stable version

Once you create a pull request and get past compare revisions you will see this. Click on the merge pull request will merge the changes from your pull request into master.

After that you can decide if you want to continue using the branch or delete it and create a new one.

After merging the pull request (See on the side there is an option to delete the branch completely)

There are times when if multiple people are working on different branches and lets say your colleague pushed his changes and merged them into master before you. You will be in a situation similar to the picture below

When you try to do a pull request you are based off of different version of the master so git isn’t going to allow you to commit your work to a remote branch until your branch and the remote branch have the same base. You will have to pull in all the changes from the remote origin, base your branch of the tip and then be able to commit and merge your branches.

Hope this short tutorial was helpful. Please add comments and let me know if this helped you.

References

  1. https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf
  2. https://www.git-tower.com/blog/git-cheat-sheet

--

--