Git version control in detail with important commands and their uses

The definition of Git from wiki says, Git (/ɡɪt/) is a distributed version control system for tracking changes in source code during software development. It is designed for coordinating work among programmers, but it can be used to track changes in any set of files.

Objective

This tutorial aims to expose the reader to the version control tool, why we need them, and the different tools available. I also want to make it a reference point for myself. I will use git as the version control tool with GitHub as a repository.

What is version control?

Version control systems are software tools that help a software team manage changes to source code over time. Version control software keeps track of every modification to the code in a special kind of database. If a mistake is made, developers can rewind the clock and compare earlier versions of the code to help fix the mistake while minimizing disruption to all team members.

Why version control?

The source code is the most precious asset for all software projects whose value must be protected from unwanted and unidentified modifications. It is a repository of an entire team’s knowledge about a problem domain. So what happens if we don’t store the entire code in a place from where every team member can access it and update it? In such cases, the individual team member will write his code and keep it to himself. What would you do if the machine storing that code crashed? What would you do if someone overwrites the existing working code with some errors?

To answer the above question, we require a version control software to keep our source code safe and track all the modifications or actions performed. It helps us to prevent loss of the source code and in case of an error, we can revert the modification to a previous version with minimal effort.

Available tools

There are many version control tools available. Refer to some of the following.

  1. SVN
  2. VSS
  3. Git
  4. Mercurial
  5. CVS

Introduction to Git

Git an open-source version control tool originally developed in 2005 by Linus Torvalds, the famous creator of the Linux operating system kernel. It is a Distributed Version Control System rather than having only one single place for the full version history. In Git, every developer’s working copy of the code is also a repository that can contain the full history of all changes.

Why git?

One of the biggest advantages of Git is its branching capabilities. Unlike centralized version control systems, Git branches are cheap and easy to merge. This facilitates the feature branch workflow popular with many Git users. Let see some of the major benefits of git.

1. Feature Branch Workflow: Feature branches provide an isolated environment for every change to your codebase. When a developer wants to start working on something “no matter how big or small” they create a new branch. This ensures that the master branch always contains a production-ready code.

2. Distributed Development: Git is a distributed version control system. Instead of a working copy, each developer gets their own local repository, complete with a full history of commits whereas, in SVN, each developer gets a working copy that points back to a single central repository.

Git version control
@PC Bitbucket

3. Pull Requests: Many source code management tools such as Bitbucket enhance core Git functionality with pull requests. A pull request is a way to ask another developer to merge one of your branches into their repository.

Introduction to Github

Github is a source code management tool for version control and collaboration. It lets you and others work together on projects from anywhere. To start with Github you need a GitHub account. Once an account is created you can follow the below steps to start.

  1. Create a repository by clicking on the new button.
  2. Enter repository name
  3. Check the public radio button
  4. Tick initialize this repository with a readme file

Refer to the below image.
Git Repo

Installing git for windows

  1. Download git from https://git-scm.com/downloads
  2. After completion open “git bash” from the start menu
  3. Check git version by running, git –version
  4. git version
  5. Time to clone the repository we created earlier using,
    $ git clone https://github.com/user_name/repository_name.git

Installing git for Linux

  1. $ sudo apt-get update
  2. $ sudo apt-get install git
  3. Check git version by running, $ git –version

Once git is installed successfully on your machine, the next step is to configure your Git username and email using the following commands, replacing dummy with your own name and email. These details will be associated with any commits that you create.

$ git config –global user.name “dummy user”
$ git config –global user.email “dummy_user@someemail.com”

Git core concept

Repository: The repository contains files, history, config managed by git.

Git Repository

States of Git: Mainly there are three states of Git

  1. Working directory – The working directory is the directory in your computer that holds all the private and application files. Files in the working directory may or may not be managed by Git. However, git is aware of them. It is the place where all the changes are made.
  2. Staging area – In between the working directory and git repository is the git staging area. Often referred to as a git index. That is a holding area for queuing up changes for the next commit. Since the files in the staging area are not yet committed, hence you can move files in and out of the staging area. Without impacting the git repository and its history of changes.
  3. Repository (Commit) – Generally in the working directory there is a git folder named “.git” that contains the git repository. The git repository manages the git commit history. That is all the changes there are finalized in the permanent part of the git repository.

git work flow

These three states of the git are specific to the local git repository.

Remote Repository: Remote repository is another repository with its own three states mentioned above. It is the last step in the basic git workflow.

Master branch: Conceptually branches in other source control contain the timeline of your changes. But in git branches contains commit. The default branch in git is the master branch.

Git basic with a project

We have discussed a lot about git in the above sections, it’s time to get your hands dirty with some practicals. In this section we will perform the following tasks:

    • Create a fresh project
  • Set remote repository
  • Add files to the project
  • Move files to the staging area
  • Commit files
  • Push the changes to the remote repository
  • Create a GitHub branch
  • Pull changes from the repository

Let’s start by creating a fresh project in our local machine. To create a project git-demo-app with a .git file we use the git init git-demo-app command. Refer to the following image for detailed commands.

git init

Once created we can check the status of the git repository by using the git status command. It will tell us we are on the master branch and there is no file to commit.

git init status

We will set up the remote repository. Create a repository in GitHub with a readme file and then copy the repository URL from the clone or download section. I have created a git repository https://github.com/Kuldeep-Rana/git-demo-repository.git

Run the following commands to add setup to the remote repository.

git add .
git commit -m “init commit”
git remote add origin “remote-repository-URL”
git remote -v
git pull origin master
git push origin master

In my case remote repository URL is https://github.com/Kuldeep-Rana/git-demo-repository.git.

It’s time to add a file to our project, create a “first-file.txt” using the nano first-file.txt command. This will open an editor where you can write your text and press ctrl+x in the window. After that, if we again run the git status command it will display the following details. This means we have a file here but git is not tracking it yet.

git status untracked file

To track the newly added file we have to use the git add command to add this file to the git index or git staging area.

The syntax to add a file is git add file-name. See the below-detailed commands. After adding the files if we again run the git status command it will tell us that a new file is added and ready to commit. This means this file is in the git index or git staging area.

git add file

At this stage, we can either commit this file or we can back up this file which will never gonna impact the git history. However, at this stage, I will continue with committing this file. I will show later how to back up a file.

To commit the file, we have to run git commit -m “ commit message.” The hyphen m is used to specify the commit message. We can also combine both add and commit in one command that I will show you later. Refer to the below-detailed commands.

git commit

Also, notice the (root-commit) highlighted in the above image, which tells us that this is our first commit. Again run the git status command and git will tell us that we have nothing to commit, and our working directory is clean.

The file is committed in our local git repository it’s time to push it to the remote repository. To push the changes to the remote repository run git push origin master. See the command below.

git push

If the file is pushed successfully you can see the file in the Github repository like below.

git repo file

Till this time we are working on the master branch also known as the default git branch. Before proceeding ahead let’s create a branch in GitHub. To create a branch follow the below steps.

  1. On GitHub, navigate to the main page of the repository.
  2. Click the branch selector menu.
  3. Enter branch name and press enter key
    git branch
  4. Switch to the newly created branch

Once the branch is created run git fetch && git checkout “branch-name” from the git bash terminal. See the below image.

git branch switch

Let’s create a new file inside the new branch using the nano commands, refer to the following detailed commands.

git branch new file
Once a file is created, add and commit the new file using git add ., git commit -m “commit message” and push it to the remote branch repository using git push. Refer to the below image.

git branch file add commit and push

You can verify the remote by refreshing your remote branch, it should display the new committed file.

git branch file after commit

Most used commands

CommandUseExample
git statusThe git status command displays the state of the working directory and the staging area.
git add "file name with path"Used to add a single untracked file to git index or git staging area.git add /home/mywork/screen.png
git add *Add all files in the current directory, except for files whose name begin with a dot.
git add .Adds the entire directory recursively, which is almost the same, but including files whose names begin with a dot.
git add - uAdd only new files.
git commit -m "commit message"Commit the tracked file to the repository.
git pushPush the changes from local repository to remote repository.
git pullPull the updates in a branch from the remote repository.
git merge "branch name"Merge the provided branch in the current branch.git merge master
git reset --hard HEADRemove all your uncommitted changes.
git checkout "branch name"Switch to the provided branchgit checkout first branch
git stashRecord the current state of the working directory and the index and bring you to the clean working directory.
git stash applyBring the stash changes back in the branch.
git checkout "file name with path"Override the modified file with previous commit. git checkout second-file.txt
git stash listDisplay slist of all the stash by latest on the top$ git stash list

Output:

stash@{0}: WIP on master: b4d12f1 changes
stash@{1}: WIP on master: 3bafb44 dev profile
stash@{2}: WIP on master: 8aced9a seperated prop files
git stash apply stash@{index value}Bring the stash changes back in the branch for given stash index. git stash apply stash@{1}

Will bring the changes back from for stash index 1
git reset --hard HEAD^Going back to the commit before HEAD
git reset --hard HEAD~2Going back two commits before HEAD
git log -S "search term" file pathThis command will provide details of all the commits which include the piece of code as search term in the specified file.
It also provide the commit ID.
git log -S ActivityEnum.ACTIVE.getValue
src/main/java/com/service/
ActivityService.java
git show "commit ID"This command display all the files commit in a the given commit ID.git show
ee0b7cd7a42b0c96ffcac6b1a
git branch -d localBranchNameDelete a branch locallygit branch -d bugfix/ISSUE-1001
git push origin --delete remoteBranchNameDelete a branch remotely
git reset (file path)Unstage all changes for a particular filegit reset src/main/java/User.java
git resetUnstage all changes
git reset --soft HEAD~Undo all the commits that are not pushed yet
git commit --amendGit edit commit message
git branch | grep 'branch name or pattern'git branch | grep ' feature/'List all the git branches matching the given name or pattern
git branch | grep 'branch name or pattern' | xargs git branch -Dgit branch | grep ' feature' | xargs git branch -DDelete all the local git branches matching the given name or pattern

Ignoring files

We use git for version control but there are some files we don’t want to be tracked. Like some system-generated files, or in the case of java the .class files, generated war/jar files. To achieve this git provides a very simple solution by adding a “.gitignore” file. The .gitignore is a text file that is used to specify the files we want to ignore.

Git ignore pattern: we have to use the following pattern to add file/files or folder while adding into the .gitignore file.

Specific File : user.txt
File Pattern: *.txt
Folder: images/

To see how it works let’s do the following:

  1. Create a users.xlsx file using nano users.xlsx
  2. Check git status, it will tell us that we have an untracked file users.xlsx
  3. Suppose we don’t want to track the .xlsx file
  4. Create a .gitignore file and add *.xlsx
  5. Again check git status, you will see the users.xlsx file is no more available as an untracked file, however, we will see a new file .gitignore
  6. Add .gitignore using git add command and commit it using git commit -m “ commit message”
  7. Create another file data.xlsx
  8. Run git status this time the data.xlsx file should not appear as an untracked file and git will ignore all the .xlsx files we created here.

See the below commands execution.
git ignore steps 1
git ignore steps 2

Git cherry-pick

While working on an application we can have multiple branches to manages the codebase. Like we can have a master branch, a release branch, and several dev branches created by each developer. There will always be a need to merge a specific commit or multiple commits from one branch to another branch. While using git we can use the git cherry-pick command to achieve this.

 Syntax: git cherry-pick commit id/hash

Example

$ git cherry-pick 5bad429511a15fd89f924e31a0a675103af8b2c4
[release 50468e6] issue fixed
Date: Wed Jan 20 12:10:00 2021 +0530
1 file changed, 2 insertions(+), 1 deletion(-)

Git provides the ability to cherry-pick a range of commits.

To cherry-pick all the commits from commit A to commit B (where A is older than B), run:

git cherry-pick A^..B

If you want to ignore commit A, run:

git cherry-pick A..B

Git delete multiple branches

To delete a single branch we use git branch -D “branch name“. But after working for some time we have too many branches in our local and deleting these branches one by one will defiantly take some time.  To save that time we can combine a couple of commands and delete them using a pattern.

we can combine grep and delete command together.

The grep command: git branch | grep ‘ pattern’

e.g. git branch | grep ‘ bugfix/’

There delete command: git branch -D “Branch name”

We can combine these two commands as below.

git branch | grep ‘pattern’ | xargs git branch -D

e.g. git branch | grep ‘ bugfix/’ | xargs git branch -D

This command will delete all the branches starting with the name bugfix.

Happy Learning !!