I’m starting a series on some of the git tips and tricks that I’ve learned during the half-decade that I’ve been using it. We’ll skip the everyday basics push, pull, log, status, diff, commit
and start off with the fundamentals that will help you utilize the true power and convenience of version control.
Let’s begin by creating a **.gitconfig**
file in your home directory. This file is the basis for all your git configurations, customizations, and aliases. In case you’re curious, I have posted a link to mine at the end.
[user]email = [email protected] = Jorge Yau
[core]editor = vimignorecase = false
[push]default = simple
[color "diff"]meta = yellow bold ulfrag = cyan bold ulold = red boldnew = green bold
[color "status"]added = green boldchanged = yellow bolduntracked = red bold
[grep]break = trueheading = truelineNumber = true
[alias]g = grep --extended-regexp --break --heading --line-number
Once the file exists, git will preload and use these configurations for all further commands. Try running a git diff
inside a repo and notice how the colors have changed.
I also have included a git alias, which is basically a shorthand for a command. In this case, git grep
with all the additional flags can be executed as git g
.
# This longer command:$ git grep --extended-regexp --line-number --break --heading
# Is the equivalent of:$ git g
Also notice how there’s a section for [grep]
— this is where you can specify default options and arguments that will be applied every time you run git grep
. If you include the same option in an alias, it will override the default option. Lastly, sections can have subsections, e.g.[section “subsection”]
There are hundreds of settings for every command, each with an expansive number of options that you can customize — read the official gitconfig documentation to discover what’s possible.
While gitignore files are ubiquitous, did you know that you can globally ignore file patterns by creating a **.gitignore_global**
file in your home directory and adding it to your **.gitconfig**
under the core section. I recommend putting software remnants, IDE and OS related files here.
.idea***~.DS_Store
Then either add this line to your **.gitconfig**
file:
[core]excludesfile = ~/.gitignore_global
Or run this command, which automatically appends it to your.gitignore
git config --global core.excludesfile ~/.gitignore_global
Speaking of grep, **git grep**
is my preferred choice for searching through a codebase over alternatives like GNU grep or ack. It’s fast, comes with git, and ignores files in your **.gitignore**
by default.
# Here's how to use it with more options below.$ git grep 'debugger'
# Show the count of occurrences found for each file.$ git grep --count 'debugger'
# Ignore case sensitivity.$ git grep --ignore-case 'debugger'
# Search through untracked files.$ git grep --untracked 'debugger'
# Quiet mode. Exits 0 if match found. Useful for scripts and hooks.$ git grep --quiet debugger
Speaking of grep, the git ls-files command is without a doubt one of the most useful git commands. Very frequently, I use it with grep and sed to perform a bulk find-and-replace or code trimming — occasionally using regex with captured groups (more on this topic in the future). However, I also want to ignore third-party files such as the **node_modules**
directory, which is just not as sexy with regular grep or even ack.
$ grep -E debugger . -rl --exclude-dir={*components*,*node_modules*}
$ ack debugger -l --ignore-dir={components,node_modules}
What if I need a list of all files in the repository — there’s no simple way to accomplish that with regular bash. Well, thankfully **git ls-files**
will list all files in the repository while also excluding the file patterns in your gitignore.
$ git ls-files
.dockerignore.eslintignore.eslintrc.yml.gitignore.gitlab-ci.yml.scss-lint.ymlDockerfileREADME.md...
You can then pipe in the results to grep to filter for certain files. In this case, I’m filtering for all JavaScript files in my repository — the $
is to make sure that .json
files are excluded.
$ git ls-files | grep -E \.js$
Git and grep are often paired together in many other commands. If you want to search through your commit messages you can use **git log --grep**
. Searching through commit messages from what I’ve seen is a seldomly used but exceptionally useful feature for tracking down bugs, tracing feature developing, and analyzing your codebase. More on that to come.
# Search for 'bug' in the git commit message history.git log --grep 'bug'
# I recommend using this flag to ignore merge commits.git log --no-merges --grep 'bug'
# Refine your searches to a particular author.git log --grep 'bug' --author 'codenameyau'
I have an alias to pretty print the shortened commit hash, the date, the author, and the commit message in one line. You can use it like so:
# Put this inside your ~/.gitconfig[alias]search = log --no-merges -i -E --pretty='%h (%ad) - [%an] %s %d' --date=format:'%b %d %Y' --grep
# Then run the command like so:$ git search 'bug'
# Pipe it to wc to get the number of occurences for 'fix' or 'bug'.$ git search 'fix|bug' | wc -l
Git search in action.
In order for **git search**
to be useful, it’s best to have contextual but concise commit message under 80 characters. One very helpful convention is to include a hash (#) followed by the issue number. This will automatically link the commit to the issue for repository managers like GitHub, and it makes documenting and investigating issues much more feasible.
$ git commit -m "#123 - Fix bug with useful git commit message"
Bonus tip: once you’ve grasped the basic fundamentals, definitely check out the git-extras repository. It is an extension of git with extremely useful commands (I’m looking at you obliterate).
https://github.com/tj/git-extras/blob/master/Commands.md
As promised earlier, here’s a link to my .gitconfig file.
codenameyau/dotfiles_dotfiles - My dotfile and text editor configurations_github.com
If you learned something from this article or simply enjoyed it, please recommend it. I would greatly appreciated it!
Here are some other articles in my Git Fundamentals series