This post was originally written on Watermelon's blog
Git clone, git commit, git push. That’s part of the bread and butter of any developer nowadays.
But why stop there? Git is a much more powerful software and it would be boring to only do such. Here are 5 not so well known tricks that have saved me hours in my life as a software developer.
Let’s look at the 5 tricks using Watermelon’s repo as an example.
git reflog
Run this when you screwed everything and need a time machine
This is the one I use the most. A lot of times you want to go back in time to when stuff worked. Sometimes you accidentally delete stuff, or merge bad code. Reflog fixes this.
You will see the list of all things you’ve done across branches. With reset, you will be able to go back to that moment.
git reflog
# git reflog will show you everything you have done across branches
# 843e14a (HEAD -> dev, origin/feature/pr-titles, feature/pr-titles) HEAD@{0}: reset: moving to HEAD@{3}
# ff22923 (origin/dev, origin/HEAD) HEAD@{1}: reset: moving to HEAD@{3}
# ff22923 (origin/dev, origin/HEAD) HEAD@{2}: reset: moving to HEAD@{2}
# 6068d94 HEAD@{3}: reset: moving to HEAD@{2}
# 843e14a (HEAD -> dev, origin/feature/pr-titles, feature/pr-titles) HEAD@{4}: reset: moving to HEAD@{2}
# ff22923 (origin/dev, origin/HEAD) HEAD@{5}: pull origin dev: Fast-forward
# 6068d94 HEAD@{6}: checkout: moving from feature/pr-titles to dev
# 843e14a (HEAD -> dev, origin/feature/pr-titles, feature/pr-titles) HEAD@{7}: commit: Fix merge conflicts from PR #24
# 6068d94 HEAD@{8}: checkout: moving from dev to feature/pr-titles
# 6068d94 HEAD@{9}: checkout: moving from chore/fix-closing-string to dev
# d452489 (origin/chore/betterSidebarSVG, chore/fix-closing-string) HEAD@{10}: pull origin chore/betterSidebarSVG: Fast-forward
# bbc4cc8 (origin/chore/fix-closing-string) HEAD@{11}: pull origin chore/fix-closing-string: Fast-forward
# 6068d94 HEAD@{12}: checkout: moving from dev to chore/fix-closing-string
# 6068d94 HEAD@{13}: clone: from https://github.com/watermelontools/wm-extension.git
git reset HEAD@{index}
# Let's say you type git reset HEAD@{7}
# git will take you back to the point in time before we fixed the conflicts in PR#24
# Unstaged changes after reset:
# M images/wmbw.svg
# M media/main.js
# M package.json
# M src/extension.ts
git log
Run this when when you want to see how a file has changed throughout time
This one is basically a movie rewind. I run this when I want to understand how a file has changed. It might be that I want to understand how those changes are intertwined with changes in some other file of the repo. It might also be that I want to understand who has made certain changes in a given lapse of time.
We are passing these flags to get a list of commit hashes and authors grouped with their respective code diffs.
git log --stat -p --follow -- src/extension.ts
# The command will show what we have done to this file, detailing the commit hash, the author, and the files changed.
# The list goes on but for simplicity we're showing 2 changes
#commit a170d0b8424cde5c718b46fe552ef16296f1a91f
# Author: Juan <juands1903@gmail.com>
# Date: Mon Mar 14 22:12:16 2022 -0500
#
# Merge branch dev into UX/AddCommunityLink
# ---
# src/extension.ts | 8 --------
# 1 file changed, 8 deletions(-)
# commit bbc4cc859957964d51486fe3778ca5317cd0ee7a (origin/chore/fix-closing-string)
# Author: estebandalelr <estebandalelr@gmail.com>
# Date: Mon Mar 14 16:55:15 2022 -0600
#
# Fix closing string, add kbd to instructions
# ---
# src/extension.ts | 4 ++--
# 1 file changed, 2 insertions(+), 2 deletions(-)
git pull –-rebase
Run this when you don’t have many local changes and those don’t deserve to be in a new branch
When learning gitflow you are taught to branch and merge. This makes a lot of sense because you usually don’t push frequently and you accumulate a bunch of changes on the remote branch before pushing.
However, if you’re only making small changes within a short time lapse, this command will help you keep the commit history organized. Using it is pretty straightforward.
git pull --rebase
git cherry-pick
Run this when you accidentally committed changes to a wrong branch
Let’s say that I have a branch called dev and another one called git/cherry-pick. Let’s say that I added a file commited_by_mistake.js to the dev branch and accidentally committed it. This command will help us move such commits to git/cherry-pick.
# Run git checkout {correct-branch}
git checkout git/cherry-pick
# [git/cherry-pick 97d1731] Add wrong commit
# Date: Tue Mar 15 16:28:34 2022 -0500
# 1 file changed, 2 insertions(+)
# create mode 100644 wrong_commit.js
git checkout dev
# Switched to branch 'dev'
# Your branch is ahead of 'origin/dev' by 1 commit.
# (use "git push" to publish your local commits)
git reset HEAD~ --hard
# HEAD is now at 6f7e0aa Merge pull request #35 from watermelontools/feature/pr-titles
git blame
Run this when you want to get the historical context of your code
I use git blame when I want to know who wrote changes in a range of lines of code. This allows me to later ping that person on Slack and ask very specific questions. It’s also very simple to use. Just tell the command which file and range of lines you want to get that context from.
# Run git blame -L {startLine},{endLine} {filePath}
git blame -L 8,12 src/extension.ts
# cc2f380e (estebandalelr 2022-03-09 14:00:02 -0600 8) const path = require("path");
# cc2f380e (estebandalelr 2022-03-09 14:00:02 -0600 9) const { EOL } = require("os");
# 52ccc1ed (estebandalelr 2022-03-09 13:53:22 -0600 10) // selection ranges should be a global var
# 52ccc1ed (estebandalelr 2022-03-09 13:53:22 -0600 11) let startLine = 0;
# 52ccc1ed (estebandalelr 2022-03-09 13:53:22 -0600 12) let endLine = 0;
In fact, Watermelon is a UI for git blame with superpowers. Highlight a piece of code, and within the VS Code UI we tell you who made those changes. We also give you the relevant PR comments around that snippet of code.
Go ahead and download our VS Code extension, and please star us on GitHub to give visibility to the project so that we can continue developing it.
Top comments (0)