Git for Software Development

In Software Development(Whether it’s small-scale app, large or even enterprise-scale apps) almost everyone works in teams to build, develop, release and maintain those software applications. To easen the struggle, VCS(Version Control System) is created. Git is currently the most successful VCS software used worldwide.

In Git, we can do many stuffs, from something simple (the git add-commit-push routine) to managing the entire enterprise-scale software development projects via elaborate Git Flow framework and development guidelines(like DoD).

Let’s start with the basics.

I will demonstrate this with a Terminal.

Download and Install Git

Go to this page, choose your operating system, install(just follow the instructions, and configure it according to your preferences. Then you should reboot, and when you get back, try typing this in your favorite terminal:

$ git version

It should print something like this(I use windows as my operating system)

$ git version 2.31.0.windows.1

This means that Git version 2.31 is installed on your device and you’re good to continue.

Create a local Git repository

Let’s create a new folder, say “myrepo” in your local computer. It can be anywhere, as long as you can cd to the folder. Then we can initialize the Git repository. Here’s how:

# Let’s say we’re in D:/path/to/repository/ , then the folder will be in 
# D:/path/to/repository/myrepo
$ mkdir myrepo
$ cd myrepo
$ git init

Note: the above might not work on your operating system, but the idea is to create a new folder, get your terminal inside, and then initialize it as a Git repository.

If you already have a repository in your local, online, or want to download someone else’s you can use Git clone. Example:

#clone local repository
$ git clone /path/to/repository
#clone remote/online repository
$ git clone username@host:/path/to/repository
#or
$ git clone website.domain/path/to/repository

Congratulations! You now have a local Git repository.

Git Terms and Workflow

In Git, there are many terms referring to different features/information. Some of them are:

  • Working Directory: The directory where the repository is located. All work is done here.
  • Commit: Records changes inside the repository.
  • Push: Pushes the repository (along with all done commits) to remote refs (to github.com, for example)
  • HEAD: Refers to the last commit we did.

When we finish working in a repository, it’s time to save all the changes and tell Git to record them. We use git add and git commit for this.

# First, we add all files that we want Git to record. We can use
# this one for adding all existing changes
$ git add *
# or this one, for adding specific files/folders
git add <file/folder name>
# To remove selected (added file/folder) use git remove
$ git rm <file/folder name>
# To remove all changes, use *
$ git rm *
# To check the repository's current status, use:
$ git status
# After that, we commit the changes. Commit messages can be
# anything, but try to make it obvious
$ git commit -m "Commit Message"

After committing, all the changes are stored in HEAD. To send it to a remote repository, use git push <remote name> <branch name>. By default, the branch used for pushing is the “master” branch. But it’s currently being slowly replaced by “main”.

# Before pushing, we should add the remote repository first to our
# Git remote list. The default is origin. Example
$ git remote add origin website.domain/path/to/repo
# Then we push it
$ git push origin master

Done. Now all your changes are inside the remote repository, and is ready to be used there.

More about Git

Branching

In Software Development, branching is used to separate between codebase versions. Master branch should only contain production-ready code, staging branch contains updates, and feature branch contains feature code in development.

To create a new branch and switch out between branches, use git branch and git checkout.

# Before creating a new branch, we need to make sure that we're in 
# the correct branch to be used as the starting point.
# Use git branch to find out which branch we're currently in.
# Example:
$ git branch
master
*staging
feature1
feature2
# The * marks the branch we're in. Now, to create a new branch
# (let's say feature3) and switch to that branch:
$ git checkout -b feature3
# When we type in git branch:
$ git branch
master
staging
feature1
feature2
feature3
# We're in feature3!
# If you want to stay in staging instead, you can use:
$ git branch feature3
# To switch back to staging, use:
$ git checkout staging

Update & Merge Local

Let’s say your friend pushed a new update to master, created feature branch feature1, then asks you to merge the feature branch to master. You can update your local repository and merge in just 2 line(Assuming you’re already in master, that is).

$ git pull origin master
$ git merge feature1

Actually, just using git pull will do the same, but we increased the redundancy and clearness of the command by using “origin master” to point and tell Git to get updates from the master branch. Then git merge will merge the given branch to the current branch.

Git by default uses auto strategy to merge, so that it can minimalize merging conflicts.

Git History

If we want to check our commit/push history, we can use git log. This command will also shows some other info, like the commit hash message(acts as the commit ID), commit date and time, and it’s commit message. You can use the hash to checkout to that commit, or cancel the commit with either git reset/merge.

Example of git log in PPL(my PBI branch):

Git Merge vs Rebase

To integrate changes from a branch to another, we can use either Merge or Rebase.

Using merge will create a new merge commit in the destination branch. This commit will contain both the changes from the merging and merged branch. For example, we want to merge feature add-api to master. The command would be:

# To merge Branch B to A, we switch to branch A then merge with B.
git checkout master
git merge branch-to-merge
# For example: git merge add-api
Example of merging. Blue is master, pink is add-api branch.

Merge is the default because it’s easy to perform(and easy to fix merge conflicts). It’s also a non destructive operation(Nothing is modified other than the merge commit itself).

Example of merge shown in VSCode’s Git Graph extension:

Git Merge

So what about Git rebase?

Rebase is the operation where a sequence/branch is moved/combined to a new base commit. The major benefit is making your project commit history cleaner. It doesn’t need a new commit each time it’s performed, unlike git merge. Rebasing will perform each commit in the source branch to the destination branch, one by one. If there’s an error, we can immediately check and fix it, unlike in git merge where all merge conflicts are stored until the whole operation finished(then we must correct all of them at once). This makes it easier to find where bug is first found, and perform necessary operations in response(rolling back, fixing it, etc).

To use rebase:

git checkout add-api // lets say we want to rebase add-api to mastergit rebase master
source: Git Merge vs Rebase + Reset vs Revert vs Checkout | by Manivel Arjunan | Medium

Git Reset vs Revert vs Checkout

Git reset is a rollback operation that can reset any branch to it’s previous state in the repository, much like using CTRL-Z. This command can be used in file level and commit level. There’s 3 options for git reset:

  • --soft – The staged snapshot and working directory is left unaltered
  • --mixed – The staged snapshot is updated to match the specified commit, but the working directory is unaffected. Default option.
  • --hard – The staged snapshot and the working directory are both updated to match the specified commit.

Command to use git reset:

git reset <commit hash># For example:git reset 1it32nv0avwr 
# You don't need to paste the whole hash, but it's recommended.

Git revert is a rollback operation that instead of moving backwards, it moves forward, creating a new commit that doesn’t change anything behind. It is a safer way to undo changes(instead of git reset), since it does not alter the commit history other than creating a new commit.

It works by inversing changes specified in the given branch, no matter where(as long as the given branch is in the history, that is).

Command to use git revert:

git revert <commit hash># For example:git revert 1it32nv0avwr 
# You don't need to paste the whole hash, but it's recommended.

Git checkout is usually used to switch between branches, but it’s capability is far more than that. We can switch to any commits in the history by using the commit hash. This does exactly the same as usual: Moving the HEAD reference to the specified commit.

Command to use git checkout:

git checkout <commit hash or branch ># For example:git checkout 1it32nv0avwr 
# You don't need to paste the whole hash, but it's recommended.

In summary, each of the above command’s scope and common use case can be seen on the table below:

source: Git Merge vs Rebase + Reset vs Revert vs Checkout | by Manivel Arjunan | Medium

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store