DEV Community

Cover image for Git Explained: An In-Depth Comparison
Milu
Milu

Posted on • Edited on

Git Explained: An In-Depth Comparison

Git is a very powerful tool and It has a long list of capabilities available at your disposition. Some commands provide slightly similar results and it is worth understanding and comparing them in order to choose the one that satisfies your needs and improves your workflow. This post is going to define and compare the following commands: revert, checkout, reset, merge, and rebase.

Revert vs. checkout vs. reset

These tools allow you to undo and manipulate changes in your repository. The problem is that they are very similar, therefore it is really easy to get them confused. We will define each of them in detail and list their similarities and differences.

Git revert

This is an unconventional and safe way to revoke an operation as it prevents you from losing history. Git revert inverts the changes that were added in a commit and adds a new commit with the inverted content. This command is especially helpful when you have already pushed your changes to a remote repository as it keeps your original commit intact.

To revert using commit hashes: git revert [SHA]

To revert using ranges: git revert HEAD~[num-of-commits-back]

Alt Text

Git checkout

This is a versatile tool, it allows you to switch in between branches, inspect older commits, and undo local uncommitted changes by moving HEAD and updating your working directory accordingly.

To switch in between branches: git checkout [branch-name]

To inspect an older commit using commit hashes: git checkout [SHA]

To inspect an older commit using ranges: git checkout HEAD~[num-of-commits-back]

Alt Text

Notes:

  • When moving HEAD to a different branch or commit, you are going to need to commit or stash any uncommitted changes that could be lost.
  • You will be in a detached HEAD state by switching to an old commit, which is great for inspection but not for modifications. In other words, you are not in your branch anymore so don’t add any commits on a detached HEAD because you are going to lose them when you switch to another branch. If you are planning to commit changes on a detached HEAD, make sure to create a new branch from it.

To undo all local uncommitted changes: git checkout .

To undo a specific local uncommitted change: git checkout -- [file-name]

Git reset

This is a powerful but complex way to undo an operation. There are three available arguments:

--mixed
This is the default mode so git reset --mixed is the same as git reset. By using any of these commands you will move HEAD to the latest commit and all the changes that were added after that commit will be available as untracked changes in your working directory.

--soft
This operation is similar to the one executed using the --mixed argument. HEAD is moved to the latest commit, however, the changes that were added after that commit are left staged.

--hard
Use the command git reset --hard only when you know what you are doing as it is very dangerous. By resetting the hard way, you will move HEAD to the latest commit and destroy the changes that were added after. This cannot be undone so use it wisely.

Alt Text

You should not use git reset when you have already pushed to a remote repository. Removing a commit that other team members have continued building upon is hard and it would disrupt your team member’s workflow.

Bonus action: Use git reset -- [file-name] to unstage a file that hasn't been committed yet.


Merge vs. rebase

When multiple people are working in a project you will need to combine your code at some point. Git rebase and merge have different approaches to consolidate the changes from one branch into another one.

Alt Text

Git merge

It uses a non-destructive operation to combine two branches’ histories without changing them. In addition, it creates a new “merge commit” every time it’s used. This is a great way to consolidate changes, however your commit history could get several merge commits depending on how active your master branch is, which can get cumbersome.

To combine the latest changes from master into your branch:
git checkout [branch-name]
git merge master

Git rebase

This is a destructive operation as it moves an entire branch’s history on top of another one by rewriting the project history with new commits.

This command is useful if you prefer a clean and linear project history. However, it is not safe to rebase on changes that have been pushed to a remote repository master branch because you would be changing the master branch’s history while your team members continue working on a diverged version of it.

In addition, Git will not allow you to easily push a rebased branch back to a remote repository. You are going to need to force it by using git push --force, which overwrites the remote branch and could cause issues with other collaborators. In other words, stop yourself from confusing your team members and creating tedious conflicts by only using rebase to cleanup in-progress features and not the master branch.

I hope you found these comparisons helpful and easy to follow. I explore, define, and explain git concepts every Saturday!

If you are new to git, checkout my previous post Git Explained: The Basics.

Top comments (18)

Collapse
 
rbukovansky profile image
Richard Bukovansky • Edited

Hi Milu,
your Git introductions seems to be great, but I have real issue with that "git merge" graph. When you merge, Git doesn't "flatten" the graph, only creates a new commit that will have two parents (green commit #3 and orange commit #3). Green commit 3 will never have orange commit 1 as its parent commit. If so, the green commit 3 would have different hash and the rest of the commits (orange 2 and 3) as well and you would be in same situation as with rebase.
Please, redo that graph.
Thanks.

Collapse
 
milu_franz profile image
Milu

Hi Richard,
Your comment made me realized my visualization was definitely misleading. I've updated it to reflect that a new merge commit has two parents. Thank you for the feedback!

 
milu_franz profile image
Milu

That is a really great topic, especially since I've also been in that situation in the past (probably most developers have experienced it too). I will make sure to add it in a future post.
Thanks for the suggestion Javier!

Collapse
 
milu_franz profile image
Milu

Thank you for taking the time to ready my post, Javier! I'm glad the illustrations are helping. Please let me know if there is anything else about git you would like to learn more in a future post :)

Collapse
 
vitalykarasik profile image
Vitaly Karasik

"This is a destructive operation as it moves an entire branch’s history on the tip of another one by rewriting the project history with new commits." - there is a typo, 'on the top'.

Collapse
 
milu_franz profile image
Milu

Thanks for catching that typo, Vitaly! I fixed it :)

Collapse
 
adzika profile image
adzika

Thanks, Milu! I find Git a bit scary and it's great to see commands so clearly and simply explained. The drawings make it so much easier to understand.

Collapse
 
milu_franz profile image
Milu

Hi! I'm glad you are finding my explanations and drawings easy to follow. Thank you for reading and the kind words!

Collapse
 
franciscosuca profile image
franciscosuca

Amazing post! this was the simplest explanation about Merge and Rebase differences that I have seen so far!

Collapse
 
milu_franz profile image
Milu

Thank you Francisco! :)

Collapse
 
aftabksyed profile image
Aftab Syed

Very nice post by creating a 5 part series which is easy to learn 👍

Collapse
 
milu_franz profile image
Milu

Glad you found it easy to understand Aftab! And thank you for reading :)

Collapse
 
enriqueedelberto profile image
Edelberto Enrique Reyes

Thanks for sharing. I love it.
Good job

Collapse
 
milu_franz profile image
Milu

Thanks for the support and encouragement Edelberto! I truly appreciate it.

Collapse
 
jsifontez profile image
Juan Sifontez

Incredibly Milu! I like the way that you explained. I never use a reset (just reset HEAD to undo changes of staged before commit) but now I understand it and I'll try to use it. Thanks for all.

Collapse
 
milu_franz profile image
Milu

Thank you Juan! I'm happy you found my git reset explanations useful, I find it to be a very powerful command and personally enjoy using git reset --soft often. Let me know if there is anything else about git you would like me to explain in a future post! :)

Collapse
 
monescse profile image
Monesul Haque

what tools did you use to make that illustrations/visualization ?

Collapse
 
milu_franz profile image
Milu • Edited

Hi Monesul, I used an app called Paper Pro and Photoshop to make my cover image.