Unspoken git secrets that save you mountains ⛰️ of time as an engineer
And no, it's NOT `status`, `add`, and `commit`.
This isn’t another article or set of tips on the most basic git commands you already know and use. This article will teach you the lesser known commands and configs that save you tons of time and effort. These are tricks I’ve learned over the years that I wish I knew when I first started—and people are 🤯 when they find out they existed.
These will help you with:
Rapidly navigating between branches
Finding the exact piece of code that introduced a bug
Tracing the history of a function or variable through time
And more. There are plenty of bonus tricks throughout the article.
Let’s jump right into it!
1) git checkout -
I use this one at least 5-10 times per day and it saves me so much time.
What does it do? It switches you to your previous branch. Instead of typing it all out, you can just say "-".
`git checkout jcutler/my-feature-branch` becomes `git checkout -`. I even have an alias set up for git checkout so it becomes `gco -`
This pattern is used in a couple of other popular areas too.
`git merge -` merges the previous branch you were on into your current
`cd -` switches to the previous folder you were in
2) git bisect
This is one of the best debugging tools few engineers know about.
If you find a bug that you knew wasn’t there before, you can find the exact commit that introduced it. First, you go back in time to some commit in the past when it was working.
My favorite way to do this is with this bonus trick:
git checkout HEAD@{1.week.ago}
This is the quickest way to go back in time and check if it was working at that point. You can replace it with other time frames too.
For now, let’s assume you checked the feature, and it was working one week ago. The problem is that hundreds of commits occurred between today and a week ago, and you need to figure out which one broke it.
`git bisect` makes it easy to figure out which commit introduced the bug in a few minutes. Instead of checking 100+ commits, you can check less than 7.
Here's how it works:
Run `git bisect start` -> this starts the process
Run `git bisect bad <commit>` where <commit> is a commit hash you know things are broken on
Run `git bisect good <commit>` where <commit> is a commit hash you know things were working (it can even be 100+ commits back)
Now, it will find the midpoint between those 2 commits, pause, and wait for you to tell it `git bisect good` if the bug is gone or `git bisect bad` if it's still there.
Based on what you tell it, it will take you to a new mid-point commit where you repeat the process. It's running binary search on your commits to help you find which commit introduced the bug in lg(n) time! Even if there are 100 commits between the good and bad one, it will take 7 checks at most. It's one of the few, actually useful applications of binary search.
Once the process finishes, it will end with a message like: "abc5678 is the first bad commit" and include the author and commit log so you can go chase them down 😂. In my case, it's usually me who introduced it though.
Another bonus trick: If what you’re checking to see if the bug is gone is protected with a test, you can automate this whole process. Just run:
git bisect run {script}
If the script exits successfully, it will consider that a “good” commit, and if it fails, it will consider it a “bad” commit.
Simply start the bisect process, get a coffee, and come back with the bug figured out.

3) git log -G “regex” (docs)
Combine this with Rahul Pandey’s nice `git log` pretty format script to get this:
# list all commits that had changes to package.json including the string "next"
glp -G '"next"' -- package.json
Add the `glp` alias to your .bash_profile or .zsh_profile like this:
alias glp='git log --pretty=format:"%C(yellow)%h%Creset - %C(green)%an%Creset, %ar : %s"'
Note that -G searches for any commits with that “next” string inside. However, use -S to find when the number of occurrences of that string changed.
In the case of searching for dependencies, `-S` only returns one result if we run:
glp -S '"next"' -- package.json
This is because we’ve only added “next” once to package.json and never removed it.
4) git merge -X theirs
This trick saves you time from dealing with merge conflicts when you know which branch should win in a conflict.
Let’s say we have a few branches: master → branch-A → branch-B
This could be because you started on branch-B while you’re waiting for review on branch-A. You want to update branch-B with the latest from branch-A, but you know it will cause a conflict. However, you know that in the conflict, you want branch-A to win.
You can run the following command, which will update branch-B with branch-A’s changes and allow branch-A to win any conflicts.
# while on branch-B
git merge branch-A -X theirs
Similarly, you can do the inverse and say your current branch should win any conflicts.
# while on branch-B
git merge branch-A -X ours
In this case, you might have made some more up-to-date changes on branch-A that you want branch-B to get, but in the conflicts, you still want branch-B to win.
Sometimes, I do this when merging the latest `main` or `master` branch, too, if I know that my changes should win or lose. It saves me a lot of time from fixing the conflicts manually.
5) Config settings
These two add a file monitor and caching to speed up commands like `git status`.
git config core.fsmonitor true
git config core.untrackedcache true
Use the following command to output branches from `git branch` in order of commit date rather than alphabetical. Use `-committerdate` if you want to reverse it.
git config --global branch.sort committerdate
Use this so you never need to do `git push -u origin HEAD` or `git push -u origin branchname` again. It will automatically set up the remote for you. After this, just run `git push` when you’re ready to push to GitHub.
git config --global push.autosetupremote true
Finally, use this for a better `git diff` output (more info here)
git config --global diff.algorithm histogram
👏 Shout-outs of the week
Skip the endless code review loops with Baz AI Code Review. Get precise feedback, resolve conflicts in record time, and catch mistakes before your teammates do—for a real, hassle-free LGTM. 👍 Try it free now at Baz.co!
Thank you to Baz for sponsoring this week’s newsletter.
Here were my top reads for the week:
The art of dealing with ambiguity on
— Quick, insightful read on how to fully understand the problem before diving into solutions. This was super helpful for me as I’m driving prioritization efforts right now.20 Business terms every Engineering Manager should know on
— Article geared toward engineering managers, but I firmly believe it’s valuable for software engineers too. The closer you can be to the business and driving solutions for it, the more impact you can make.
Thank you for reading and being a supporter in growing the newsletter 🙏
You can also hit the like ❤️ button at the bottom of this email to support me or share it with a friend to earn referral rewards. It helps me a ton!
Man, love how you balance the softer skill posts with such technical thingies 🙃
I remember I’ve read about bisect sometime ago, but totally forgot about it. Went over 20 commits in my personal project last week… so thanks for the reminder 🙃 (not tests to automata it though 😂)
Very useful commands. Thanks Jordan