-
Unbreak Your Code With Git Bisect
git bisect
is a helpful tool to assist you in finding which commit introduced a bug.In a world without
git bisect
when you need to find the commit that introduced a bug you’d likely have to go through commits one by one, manually checking each one out and then doing some testing.git bisect
can make that process a bit less painful by automating a binary search of your commits.To start it just execute
git bisect start
.The latest commit likely has the bug so mark it as bad:
git bisect bad
.Now give it a good commit before the bug was introduced:
git bisect good 7df148d3
.git bisect
will now cycle through the commits. For each one you’ll need to mark each one as good or bad. Then it’ll move on to the next commit.Here is an (abbreviated) example below:
» git bisect start » git bisect bad » git bisect good 7df148d3 Bisecting: 35 revisions left to test after this (roughly 5 steps) » git status HEAD detached at 4f5d1140 You are currently bisecting, started from branch 'master'. (use "git bisect reset" to get back to the original branch) » git bisect bad Bisecting: 17 revisions left to test after this (roughly 4 steps) » git bisect good Bisecting: 5 revisions left to test after this (roughly 2 steps) » git bisect bad f01f1b96feed92b6afd60ebac576571a98bcda56 is the first bad commit commit f01f1b96feed92b6afd60ebac576571a98bcda56 Author: Joe Dev <jdev@companyfoo1000.com> Date: Tue Jan 16 15:40:46 2018 -0600 Add super awesome feature that won't break anything
Each time you mark a commit as good/bad it moves to a new commit. You can see the
git status
above shows the current commit. After the lastgit bisect bad
it identified the commit that introduced the bug.With the commit found just clean up with
git bisect reset
and you are good to go!There are quite a few other options with
git bisect
that you can read about in the git docs. -
Level Up Your Git Skills With Aliases!
Like many programmers I use git constantly. And also like many programmers I get tired of typing the same commands over and over and over. So I’ve added the following aliases to my .zshrc to make common commands easier and quicker to type. You could do something similar via .gitconfig or .bashrc.
Some of my most used aliases are
gpb
for pushing a branch,gca
for committing all changes,gs
for getting the status, andgup
for rebasing from master.Let me know if you have any suggestions!
# Git alias g='git' # Shorten common commands alias gst='g status' alias gpl='g pull' alias gpu='g push' alias gf='g fetch' alias gco='g checkout' alias grb='g rebase' alias grbc='g rebase --continue' alias grba='g rebase --abort' alias ga='g add' alias gm='g merge' # More succinct status alias gs='g status -sb' # Show all branches in the order of last change alias gb='g for-each-ref --sort=committerdate refs/heads/ --format="%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))"' # Nicer diff alias gd='g diff --word-diff' # Delete a branch alias gdb='g branch -D' # Fancy git log alias gl='g log --graph --stat --abbrev-commit --date=relative' # Push branch and set the upstream alias gpb='g push --set-upstream origin "$(g rev-parse --abbrev-ref HEAD)"' # Safer force push alias gpbf='g push --force-with-lease' # Pull the latest from master and rebase alias gup='g pull --rebase origin master' # Pull the latest from master and merge alias gum='g pull origin master' # Ammend a commit alias gam='g commit --amend' # Save changes temporarily alias gwip='g add -A && g commit --no-verify -m "WIP"' # Undo the last commit alias gun='g reset HEAD~1 --mixed' # Super undo using the reflog...careful. Undo your undo. alias gungun='g reset "HEAD@{1}"' # Delete all merged branches alias gcl='g branch | grep -v "master" | xargs g branch -d' # Commit alias gc='g commit -v -m' # Add all and commit alias gca='g add -u && g add . && g commit -v -m' # Create new branch alias gcob='g checkout -b' # Add all alias gaa='g add -u && g add . && g status' # Interactive adding alias gap='g add -p && g status' # Interactive rebase for squashing commits alias gir="g rebase -i origin/master"
-
git merge --squash
I’m a fan of rebasing in git. I like being able to make lots of small, messy commits without worrying about a readable history and cleaning it up later. But on occasion I’ve had issues where rebasing and squashing my commits has resulted in many merge conflicts. I’m not really sure why this sometimes happens but it is a pain. Fixing merge conflicts can be error prone and time consuming.
Thankfully I’ve recently come across
git merge --squash
which can help in these situations. To use it do the following:# Checkout master or whatever you branched off git checkout master # Create a new, clean branch git checkout -b fancy-new-clean-branch # Now merge the old, messy branch into the new # branch with git merge --squash git merge --squash old-messy-branch # This will copy all the changes to the current # branch but will NOT create a new commit. Add all # the changes and then commit. git add . git commit -m 'New easy to understand commit'
Now your git history on the new branch will have a new single commit that you can push up and create a pull request for.