Git useful commands, code management

Git first cover
Reading Time: 6 minutes

Hi all. In this blog, we will continue to explore some of the useful git commands. These commands would help when we are working on a remote shared repository. This is in continuation to my previous post on git working areas. So, I am assuming that all are familiar with git working areas, if not please go through the blog here. Let’s explore them now and see how they effect the git working areas.

Git Useful Commands

Here are a few useful git commands that we are going to cover in this blog:

  1. Configuration
  2. Reset
  3. Revert
  4. Rebase
  5. Merge

We will see how these commands work and helps developer(s) with their code and projects. Let’s go through them in details now.

Configuration:

Well this is not just a command, instead configuration is the first step when working with Git. Configuration is the minimal set of information required to work on a remote project. We use `git config` command to pass in the configuration. Following information should be provided:

1. User name associated to git, creates the author name that would be assosciated with our commits.
git config --global user.name "Prashant Sharma"

2. Email, author's email assosciated with the commits.
git config --global user.email prashant.sharma@knoldus.com

3. To list Remote url:
git remote -v

4. To add a remote repository, so that local repository is connected to a remote server:
git remote add origin <repo_url>

That is how we provide some minimal amount of information to Git for a smooth start. Next, is the 3 R’s git commands, let’s see.

In our lives we do certain things, that later, we would want to undo but life does not works like that, right? 🙁 Fortunately for us(developers), Git understands this situation well and provides certain strategies to perform rollbacks in our working model. 🙂 We apply these strategies through the use of commands like: Reset, Revert, and Rebase. Let’s go through these one by one.

Reset:

Reset does different things in different contexts but in general it provides a rollback from a faulty state to a working/functional state. It does so by setting the current HEAD to the state specified. Let’s see a practical use-case. Let suppose, I have added a wrong/irrelevant commit to my repository say commit id-C4. I do now realize that this commit is faulty/unnecessary. Further, I want my repository to be clean of such commits and no traces of them should be there. Certainly, the git reset command is the favorable choice here. Let’s see how reset works with the help of diagrams below:

Git useful commands - git:reset
Currently HEAD is at the Commit-4, which is the faulty one.

Now let’s try to rollback from Commit 4 to commit 2 with the commit id say C2:

git reset C2

After Reset, we can see the following state changes in our repository:

git useful commands- after:git-reset
It is clear that after reset command the head moved to commit 2 and the other commits c3 & c4 were ultimately moved to a separate flow which will be garbage collected eventually.

Thus, using reset we end up in a clean state. Additionally, let’s see some of the options with reset.

  1. –hard: If used, –hard would force copy the contents from the Repository area to the Index and Working areas both. The work done in a faulty commit and its traces are now non recoverable.
  2. –soft: This effects Repository area only and leaves the Indexing and Working areas untouched. They still would contain the contents added in the faulty commit.
  3. –mixed: It is the default option with Reset. It would copy the contents of the safe commit to the Repository and the Index areas. Though, the working area remains untouched. So when we wrote git reset C2 we actually meant git reset –mixed C2.
Revert:

The Revert command works much like the reset command as they both would help us reach to a safe state. The only difference is that unlike moving the HEAD back to a safe commit in the tree, Revert adds a new commit in the hierarchy. To summarise, Reset is used to undo the changes we did whereas Revert is used to cancel the changes. Let’s see how revert works:

git revert HEAD~1
This reverts the changes from the second last commit in the HEAD. It creates a new commit with the reverted changes.

Since this introduces a new commit, Git prompts for a commit message when working on revert command. Let’s see through a visualization.

Git useful commands - revert operations.
This is how the structure looks like after performing the revert operation.
A word of caution

Making these kinds of Rollback changes in the local repository, to code, we haven’t pushed yet is fine. But avoid making changes that rewrite history if the commits have already been pushed to the remote repository and others may be working with them. In other words, consider using revert instead of reset when working on a shared repository to minimise the conflicts and issues.

Rebase:

The Rebase command is a bit different than the other two rollback commands. Both in the way it is implemented and the way it changes the commit history. Rebase works on multiple branches and not just one branch. As per the git documentation a rebase reapply commits on top of another base tip. Let’s understand this with the help of an example. Suppose we have 2 branches, one is the master branch and other is a feature branch. Feature branch was cut-off when master was at commit c2, and then there were multiple commits done to both the feature and master branches. This is shown in the diagram below:

Git useful commands - rebase.
As can be seen commit c2 is the common point from where the two branches diverge.

Now, it is time to do a rebase. Perform the following steps:

1. Checkout to the feature branch: git checkout feature
2. Do a rebase on master to pick up the changes done to the master branch: git rebase master

And, this is how the state looks like after the rebase.

Git useful commands - rebase applied.
After rebasing, feature branch moves in sequence with the master branch. The diverged commits C3 & C5 still exist but there aren’t any branch that refers to them. Thus marked as probable candidates to be picked up during garbage collection. 🙂

Finally after the rebase, feature branch would contain all the commits from C0 to C5.

Merge:

When you’ve completed development in your branch and everything works fine, the final step is merging the branch with the parent branch (dev or master). This is done with the git merge command.

Git merge integrates your feature branch with all of its commits back to the dev (or master) branch. It’s important to remember that you first need to be on the specific branch that you want to merge with your feature branch.

For example, when you want to merge your feature branch into the dev branch:

First you should switch to the dev branch:

git checkout dev

Finally, you can merge your feature branch into dev:

git merge <branch-name>

Imp: Make sure your dev branch has the latest version before you merge your branches, otherwise you may face conflicts or other unwanted problems.

Ques: How to learn and understand a git command?

Ans: To understand and learn a particular git command, we should try to answer the below 2 questions. If we are able to answer these questions, we will easily understand the behavior of the command. These two questions are:

  1. How does this command moves information across the 4 working areas of Git. For understanding of working areas refer here: https://blog.knoldus.com/git-working-areas/.
  2. How does this command change the repository?

I hope that if you are able to answer the above two questions for any git command you will be able to understand that command well.

Conclusion

We went through the most common and useful commands in Git that would help in daily life. Most of the times developers face challenges where they need to resolve a lot of issues raising due to merge conflicts. The commands we studied above will help us in reducing issues during merge. I hope this blog was useful. Please feel free to add your suggestions & queries in the comments section below. 🙂 Until next time, tcre bbye.

References

Knoldus-blog-footer-image

Written by 

Prashant is a Senior Software Consultant having experience more than 5 years, both in service development and client interaction. He is familiar with Object-Oriented Programming Paradigms and has worked with Java and Scala-based technologies and has experience working with the reactive technology stack, following the agile methodology. He's currently involved in creating reactive microservices some of which are already live and running successfully in production, he has also worked upon scaling of these microservices by implementing the best practices of APIGEE-Edge. He is a good team player, and currently managing a team of 4 people. He's always eager to learn new and advance concepts in order to expand his horizon and apply them in project development with his skills. His hobbies include Teaching, Playing Sports, Cooking, watching Sci-Fi movies and traveling with friends.