Blogs >> 2021 >> Version Control by Git & Github
Hands-on Tutorial on Version Control by Git & Github
1. Fundamental concepts
In plain words, git is a version control system. Github is an online code repository built around the idea of git. Github is primarily designed to facilitate collaboration aided by git's version control technology.
1.1.   What is version control?

Development and deployment often involves managing changes to documents, computer programs, large web sites, and other collection of information. By managing I mean keeping track of changes, undoing changes and reverting back to previous forms, integrating changes while negotiating conflicts and so on. Popular source/version control systems widely used are CVS, SVN, git, perforce.

Git is a distributed source control system (not required to be decentralised). Massively scalable (because of its distributed nature) and open sourced, it was developed by Linus Torvulds. Most operations in git are actually local and very few operations require network connection. Any version control system facilitates collaboration among the developers in large scale projects.

1.2.   Characteristics of git
Git is a decentralized and distributed version control system. However most people choose a central server to store the project routines because of its distributed nature. Following Characteristics make git very popular among the developers.
  1. Massive scalability
  2. Open source
  3. Develped originally for linux project requirements (comes free with linux)
  4. Most operations are local. Very few comands require internet connection.
  5. Very fast (since local)
  6. Active community
1.3.   Fundamental working principles

The two fundamental concepts needed to learn git are the version control stages and the idea of branching. Fig. 1 illustrates the version control stages of the documents. Four stages of git are listed below and refer to the figure caption for the explanation.

  1. LOCAL-1: Working directory
  2. LOCAL-2: Staging area (pre-commit holding area)
  3. LOCAL-3: Repository on the local machine (Commit)
  4. REMOTE: Remote repository as the 4th and last stage

Git and github
Fig. 1   Version control stages   Git recognizes four stages in a version control pipeline. Working directory is where one does the development and makes changes to the project files. The accrued changes are then stored temporarily, using the command $ git add, in an intermediate zone called staging area. At some point all the stored chenges are finally submitted to the local repository by applying the command $ git commit . To be able to work in a collaborative fashion one can push the local repository to a cloud-based central and remote repository, Github in this case, for other collaborators to see and access such changes. Note the bidirectional arrows in this phase which means the developer can also pull other's work/changes from the Github cloud to integrate in his/her own project files.

We have introduced the idea of $ git commit in Fig. 1. The second fundamental concept for understanding git is how "commits" are tied together serially, one after another, to constitute a branch. Essentially, the commits compose the branches as shown in Fig. 2. When the project is created the branch one starts with is called the master branch, this is the naming convention of main or default branch. During development new branches are created to carry out the development-isolated-from-the-master-branch and merge them later with the master when the objective is achieved. Fig. 2 shows such branches, namely feature-01 and feature-02. A branch that fixes some database bug is shown too (bugfix-database-01).

Git and github
Fig. 2   The idea of branching   Serial commits are tied together to build a branch. New developments (e.g., feature-01 and feature-02, or even critical bugfixing) are tried in isolation in their respective branches before merging them with the master branch (the default main branch).
2. Git: Getting started
We shalll start with the installation on Ubuntu platform.
2.1. Installation and setting up
$ sudo apt update
# Install git
$ sudo apt install git
# Is git installed? Check version
$ git --version
# git requires two bits of information
$ git config --global user.name "Your Name"
$ git config --global user.email "youremail@example.com"
$ git config --global --list
# git should get back with list and names

Once the git has been set up locally the next part is to set up a Github account on Github. After registering an account with Github the next step is to generate a token (classic); Github has deprecated the password based authentication and recommends now the token based authentication. There are primarily two ways to manage repos on Github: either with tokens or with SSH keys. In this tutorial we shall follow the token based approach. Remember, while pushing your code to Github you will need to present the token string in terminal for authentication; hence preserve it safely, you need to use the token string just like your password.

In summary,

  • Create an account on Github.
  • Click on settings > Developers setting > create a new token > copy the token
  • Preseve the token somewhere in a safe place. You need to use this as your password.

Two important cases are presented next for getting started: (i) cloning from Github followed by local development and (ii) native project pushing to github.
2.2. Cloning → local development → remote

You can create a remote repo on Github, add a README.md, and then clone it to your local machine as follows.

$ git clone https://github.com/<username>/<repo-name>.git
$ cd repo-name 
# you will notice the hidden .git folder inside 
$ git status      # check git status 
                  # nothing untracked at this point
$ echo "Hello World" > file.txt
$ git status      # what do you see?
# Add the changes to staging area
$ git add file.txt # alternative commands: git add -A or git add --all
# Commit the changes to local repo
$ git commit -m "Created file.txt" -m "Some description"
$ git push 
# At this point the system will ask you 
# username -> provide your github username
# password -> provide the token string

While writing this tutorial it is observed that cloning private repo is also possible with tokens. One needs to enter username and password (i.e., token string) for authentication. Authentication will also be necessary for pushing any changes from local to github cloud.

Remark #1. If push fails, or cloning of private repo faces issues, make sure your password keychain is not preserving any old login credentials. In such case you may want to delete such credentials if you don't need them anymore.

Remark #2. Always note the github config details with $ git config --list. The user.name and user.email will decide which github account is pushing the changes to the cloud, not the account credentials you used to login (important in case you use multiple github accounts on the same machine).

2.3. Native project → remote
# Make a project directory and place yourself inside it
$ mkdir repo-demo && cd repo-demo
# Add some files if it is an empty project
$ echo "# demo repo" >> README.md
# Start version control with git
# Initialize the .git folder inside repo-demo
$ git init   
$ git status # all the untracked changes will be visible
$ git add README.md # commands: git add -A or git add --all
$ git commit -m "Created README.md" -m "Some description"
$ git push origin master
# You will get error!!! The remote is not setup. 
$ git remote -v # Nothing will show up

That means, you need to create an empty project on Github with the same name as that of your current project directory on our local machine, i.e., repo-demo in our case. Once created we can set up the remote first. Next, we shoudl be ready to push the local files to Github cloud. Check the codes below.

# Create a repo on github with the same repo name, i.e., "repo-demo". 
# Add this remote repo as follows. 
$ git remote add origin https://github.com/<username>/<repo-name>.git
$ git remote -v  # You can view remote origin

# On your machine the default git branch is "master"
# Github has decided to call default git branch as "main"
# Hence, it helps if we locally rename "master" to "main" 
$ git branch -a # check all branches first
$ git branch -M main # rename now

# Next, let us push the local files 
# You need to authenticate with username and token-as-password in the following command.
$ git push -u origin master 

Note that $ git push -u -f origin main also works where -f is forced push (overwrite anything).

What does -u flag do? It sets the remote upstream. That means, if you need to push any further changes, just typing $ git push will be enough in the subsequent commands. No need to type out the full command $ git push origin master.

2.4.   Push an existing repo

Same workflow like before.

$ cd existing-repo
# Set an empty project on Github with the exact name "existing-repo"
$ git remote add origin https://github.com/<username>/existing-repo.git
$ git push -u origin master
3. Basics of git branching

We shall start with branch creation and switching branches. Next, we shall discuss how to merge the branches. The following hands on examples demonstrate the concepts.

# Create the project
$ mkdir demo-branching && cd demo-branching
$ echo "# demo repo" >> README.md

# Default branch is master. 
$ git branch # The current branch is highlighted with star
# Create a new branch (-b flag) and move onto it 
$ git checkout -b feature-01
# Alternatively, if you are on master, the following will do - 
# $ git branch feature-01

# Switching branches
$ git checkout master # back to master
$ git checkout fea* # hit tab and autocompletion works

# Merging branches 
# Stay on feature-01, edit the README.md adding a few lines.
$ git status
$ git add README.md
$ git commit -m "Updated Readme"
# Switch onto master
$ git checkout master
# Check the difference between master and feature-01
$ git diff feature-01
# Merge master with feature-01
$ git merge feature-01
# Check the status
$ git status

The next exmaple demonstrates how to handle pull request using Github. Managing pull request is essential if you intend to collaborate on software development. In such case multiple group of developers build separate parts of the codebase, generate pull request and finally merge them. The small example below introduces you to teh essential idea.


# How to handle pull request on Github?  
$ git checkout -b feature-02 # create a new branch
# Make some new changes. 
$ echo "## Some new changes " >> README.md
Try to push new changes.
$ git push # you will receive an error! Why?

# Set the remote upstream on Github (add the origin).
# ... (Hint: refer to Section 2.3 or 2.4)
# Then push
$ git push -u origin feature-02 # creates a PR
# Move to github website to handle the merging of the pull request
# Click on pull request and you will be able to see the following option
# Merge "base branch <- feature branch"
# Choose: Create a pull request

# The feature-02 is merged with the main branch on Github. 
# How to update the changes on your local machine? 
# Do the following locally. 
$ git checkout master
# Now, pull the changes from Guthub. 
# If upstream is not already set up ...
$ git pull -u origin master
#  ... if the upstream is already setup 
$ git pull 

# We are done with the feature branch.
# But it will still be there though you do not use it.
# You can delete the branch if you wish.
$ git branch -d feature* # tab and autocompletion
# Confirm the deletion ...
$ git branch # check the final staatus
4. Summary & conclusion
In summary, git is a version control system. Github is an online code repository primarily designed to facilitate collaboration aided by git's version control technology.
4.1.   Review of basic commands
4.2.   References
  1. https://git-scm.com/book/en/v2
  2. https://docs.github.com/en/get-started