Skip to content

Git cheatsheet, or how to git gud with the command line

This page is part of the “Cheatsheet of Epicness: JD’s incomplete collection”, continue the read at your own risk.

If you are here, one of two things happened. Either my SEO is great or you saw the cheatsheet collection entry point and my SEO is still pretty good plus you felt like engaging further. I’d thank you for passing by but you came here to grab some of that git sheet. For that, I have two words for you: git gud. You can also keep reading since that is an option. That will help. 

That being said, say goodbye to the world of children using graphical user interfaces on top of git. Welcome to the git CLI realm where real men (and women) belong. Welcome to my hood as DJ Khaled would say.

Committing code

Commit with a message

I’m not really going to go in details for that one as you probably know what it does. If you don’t you can go check it out. Here I want to throw at you a tip. The command I execute over sixty times a day.

git commit -m "Write your message without the awful vi UI"

Yes, you don’t need to deal with a UI for the sixties by appending a simple parameter and your message directly behind it. You will not know how much time it saves you until you have to do it more than twenty times a day. You can thank me later.

Preventing oopsies

Sometimes you can change a file by accident and not be quite sure what its original state is. Using git reset can be an option if you want to scrap everything but for something more granular you will want to use an individual file checkout.

git checkout -- <filename>

This will bring the file back to its last committed state.

Contributing to open-source

Remotes

A key element of open-source development is the handling of remotes. You may be of the main development team that has access to the main repository. In that case, handling remotes is not a concern. However, if you wish to contribute to a project you are not part of the only way to help is to work from a fork.

A fork is a copy of the main project repository where you can work from freely. Once you implemented your bit of contribution you open a pull-request. Then after a civilised exchange and potentially corrections, your code may get merged into the main repository.

Git has that concept of remotes which allows you to point your local code to various repositories. The main way I used remotes is to contribute to open-source and usually, I have two: origin and upstream. Origin would be pointing at your fork and upstream at the main project. Wielding these can allow you synchronizing your fork with the main project to avoid code change conflicts.

Listing remote details

git remote -v

The above command lists the repositories you are working with along with their URLs and actions you may use. Here is a sample output with a project I contribute to.

origin	git@github.com:CodingNagger/validator.js.git (fetch)
origin	git@github.com:CodingNagger/validator.js.git (push)
upstream	git@github.com:validatorjs/validator.js.git (fetch)
upstream	git@github.com:validatorjs/validator.js.git (push)

Add remote

git remote add (remote_name) (remote_url)

This command allows you to add a remote by choosing a name and adding the remote URL. You can use both HTTPS and SSH here like you would for a clone command.

Rebase

Ah, the good old rebase. Wielded correctly it can do great good, especially through the command line. You will move faster in an environment where you have a team working on the same branch. However, the smallest mistake will turn the rebase into your greatest foe. Now you can pick some easy commands or look for more details there

Rebasing on top of a local branch

git rebase (local_branch_name)

Some would think is the least confusing use of the rebase command.  Not necessarily. But here we will focus on the fact that your changes will be reapplied on top of the latest local changes on local_branch_name. You may commonly use a git rebase my_other_local_branch_name  if for some reason you have been developing on two local branches without pushing your changes not to break a remote. Good to prevent remote damage nor local damage due to a broken remote but can create nightmarish situations.

Rebasing on top of a remote branch

git rebase (remote_name)/(remote_branch_name)

That one is your best friend if you need to pull remote changes, especially when dealing with open-source projects. Using git rebase origin/master sometimes is the difference between an approved and a denied pull request. Be wary of not forgetting the / between the remote and the branch name. I did that a few times because I did not remember the about the /. When the branch you want to rebase on top of is the main branch of your remote you will be fine. However, when that is not the case you’re in for an ocean of pain. This is why I always create a branch of my current development branch before attempting a rebase. That way if I screw it up I scrap it and restart.

git cherry-pick but with a range

You may already know about git cherry-pick but did you know you can go faster and grab multiple commits at once? Say you have the following history:

Me ffffffff Somebody help got it all broken again
Me eeeeeeee All fixed
Me dddddddd Broken commit due to refactoring
Me cccccccc Some more refactoring
Me bbbbbbbb Clean up code
Me aaaaaaaa Implement fixes for bug 101
Me 99999999 Writing tests for bug 101
Me 88888888 Something commit
Me 77777777 Last stable commit

I don’t know for you but it doesn’t look like the most stable branch for which the latest commit is 77777777. Now, imagine you need the fix for the bug 101 asap but cannot merge it to the main development branch nor master. Because of the commit 88888888 you can’t just go back. Yet you need these commits 99999999aaaaaaaa and bbbbbbbb. This is one of the cases where a ranged cherry-pick is useful. Here is how you can apply these commits on another branch off of your main one in one command.

git cherry-pick 99999999..bbbbbbbb