How I got over my irrational fear of git

Anwesha Chatterjee
codeburst
Published in
6 min readOct 14, 2017

--

(Spoiler alert: It isn’t that scary!)

When I first started using git, about 2 years ago, I was quite intimidated by it. As a graduate engineer just starting off, I didn’t entirely understand why we needed version control. But as I started coding as a part of a team that got bigger and bigger, the need for git became obvious to me. Git makes collaboration and backing up easy — and also provides a clear and easy way to store versions of projects. These are the main reasons why git has been indispensable in my life as a software developer. However, despite this, I always had this lingering fear of git — and it was because I didn’t really understand it.

Initially my plan was simple. Only use the things that I know. git clone. git pull. git commit. git add. git push. And if anything didn’t work out as planned, panic. I got heavily dependent on the merge tools in PyCharm (PyCharm is awesome, btw), but that back fired. The abstractions provided by IDEs can be very neat, but I feel like they can get in the way of really understanding whats going on under the hood.

Recently, a few things got me to shake my bad git habits and really get into the nitty-gitty (see what I did there 😛) of git. Mainly, it was a change of workplace. In a previous workplace (maybe due to the large team size) I could get away with some bad practices. My commit messages didn’t make a lot of sense because I didn’t think they were that important.

Somewhat like this. (https://imgs.xkcd.com/comics/git_commit.png)

My reliance on PyCharm for any form of merging, as well as working on a branch with atleast one other person meant that I had all these stray “merge commits” littered in my pull request. But recently I started working at a company where they’re a lot more strict about the quality of pull requests, right down to the wording of the commit messages. So I’d like to share with you my story of how I stopped being petrified of git rebase

Merging and rebasing

In order to understand merging and rebasing, let’s look at a few scenarios.

  • Scenario 1
Scenario 1: 1 unmerged commit in master

In this simple scenario, you had created a branch off the master branch in your project. The master branch had one commit at this point — commit “A”. Since then, there has been another commit added to master — commit “B”. Now, upon merging with master:

git merge master
The result of a merge in Scenario 1

The commit “B” is now a part of my-feature branch. Nice!

  • Scenario 2
Scenario 2: a local and a remote commit

Moving along, you have created a commit in your local branch (commit “D”), and someone has pushed a new commit onto master as well (commit “C”).

Hmm… what to do. Let’s try merging…

git merge master
Result of a merge in Scenario 2: A “merge commit” is created.

See the red commit “E” — that’s the “merge” commit that was created to get my-feature branch back on track with master. Note how the commit “E” has two “parents” (“C” and “D”), because it’s a result of merging the changes brought about the commits”C” and “D”.

The “stitching pattern” look after another merge: 2 new remote commits and 1 new local commit

Now, if scenario 2 keeps happening, (as in, we keep merging master into our branch) this is what our workflow will start looking like. As you can see, this can become a bit messy. Everytime there is a new upstream commit, you end up with a merge commit.

  • Scenario 3: Enter git rebase…
Scenario 3: situation after rebasing — commit D is replaced by commit D*

In this scenario, when there is a new upstream commit, as well as a new local commit, we try rebasing instead.

git rebase master

This time, instead of creating a whole new commit (like commit “E”), our local commit “D” is now replaced by a new commit “D*” (The purple commit), that incorporates the local changes from the previous local commit “D” onto the parent commit “C” (the new upstream commit in master).

As you can see, rebase and merge essentially do the same thing — they just do it differently. Rebase leaves the git log much cleaner and easier to navigate. It also makes the history more linear, as opposed to the stitching pattern look in scenario 2 brought about by merging.

Interactive rebase

Rebasing can also be used to amend a commit that is not the previous commit. In this case, you would have to do an interactive rebase

git rebase -i master
Interactive rebase

You can also give rebase the commit hash you would like to rebase to. First, you would have to replace the “pick” next to the commit you want to amend with “edit”. Then, making the necessary changes, you would amend the commit, followed by completing the rebase

git commit -a --amend
git rebase --continue

If at any point, things go south, you have the option of aborting the rebase

git rebase --abort

If you’re still worried, you can also try out the rebase in a temporary branch first, to see how it goes. Interactive rebase can also be used to “squash” multiple commits into one commit. One word of warning about using git rebase though…

Do NOT rebase public branches that others have created new commits on top of.

If you would like to learn more about why this is so, or just in general about merging and rebasing, I highly recommend the atlassian documentation as well as Git for Computer Scientists.

Some other tips and tricks I picked up along the way…

  1. If you would like to pull from master while making sure your branch is rebased and not merged, you can do that using:
git pull --rebase

Another scenario where I found this helpful was when I accidentally committed onto a branch I wasn’t supposed to commit to. The steps to get out of a situation like this would involve something like…

git reset --soft <commit-hash-to-reset-to> 
git stash
git pull --rebase
git checkout <the-correct-branch>
git stash pop
git commit -a

So basically,

  • Do a soft reset to the latest “good” commit hash
  • Stash the changes
  • Do a rebase-pull from your origin, so it doesn’t fetch your misguided commit
  • Checkout the correct branch
  • Unstash changes
  • Commit the changes
  • Live happily ever after 😍

2. I have also sometimes gotten into a situation where I accidentally “lose” a commit after a rebase (It’s usually because I gave it the wrong commit hash). If this happens, rest assured — you can’t lose a commit. You can either git checkout or git cherry-pick the commit using its hash. How do you find the hash?

3. Reflog! Embrace git reflog as soon as you can. The more you read it, the easier it will get to pick out the commit and the corresponding commit hash that you need.

4. Also worth looking into what tilde and caret mean in git as this was something that took me a while as a noob.

And that’s it! That’s my git story so far. I’m certain that I have many git wars to fight yet, as my journey as a software engineer continues — but I look forward to coming out the other end reinforced with even more git knowledge, and hopefully a little less scared of the powers of git!

--

--