In the 2nd post of the series I'll show how I extract information from a Git repository. There are three layers I will operate on:
- highlighting output to draw the attention on a particular piece of information on the screen
- formatting a log message
- searching through commit messages or through the codebase
For the purpose of this article I will use two Git repositories:
- a small personal project which has some changes in both the working directory and the staged files,
- Noir framework repository from GitHub
Let’s start by putting some colours on
git status. We have to modify
~/.gitconfig and add the following part:
[color "status"] added = blue changed = yellow untracked = white ul
λ git status
git status will get some nice coloring, like on the
Let’s remove unnecessary information from
git status by adding the
option. I use it pretty often so I have binded it to
git s for convenience.
λ git status --short
As shown below there is only the essential status information
Another area of improvement concerns
git diff command. As before let’s add
some colours to the output by modifing
[color "diff"] meta = white bold frag = magenta ul old = red bold new = green bold
git diff will render an output similiar to the one below
There is a useful option called
--stat which provides a summary for each file
git diff. It can be used for staged files as well.
λ git diff --stat λ git diff --cached --stat
git log shows the commit logs.
λ git log
There is a lot of information here and it takes of lot space. In the following paragraphs I'll propose some neat alternatives.
Log with Diff Stat
We can include
diff stats in the log output using
λ git log --stat
Log with Patch
We can also associate
diff content with each commit in the log output using
-p option. There is also
-2 which limits the output to only the last two entries
λ git log -p λ git log -p -2
Log Format: Graph
We can apply various formats to
git log output. For example, we could display
a ASCII graph on the left thanks to
λ git log --graph --date=short
Log Format: Short
Let's create a more concise
git log output using the following format.
λ git log --pretty=format:'[%h] %an %cr: %s'
I have binded it to
git los alias.
Log Format: Changes
Let's add to the previous output a list of files changed for each commit. It could be done this way:
λ git log --pretty=format:'[%h] %an %cr: %s' --name-status
I have binded it to
git changes alias.
Log Format: Summary
We can go even further and adjust the previous output with a
git diff stats
that visually show how a file or files associated with each commit changed
λ git log --pretty=format:'[%h] %an %ar: %s' --stat
I have binded it to
git summary alias.
Log Format: Changelog
We can also generate a simple change log (aliased to
git changelog) by using:
λ git log --pretty=format:' * %s'
As before I have
git changelog alias for that format in my
Log Format: Full Graph
Or a neat graph which is binded to
git lof in my personal config.
λ git log --graph --pretty=format:'[%h] -%d %an %cr: %s' --abbrev-commit --date=relative
git log output can be filtered in various ways.
Time range can be specified using
λ git log --since=2.weeks
By Author OR By Commit Message
To easily find commits authored by a specific person, I use
git log with
option. If I wanted to search through commit message instead, there is
It can be easily combined with other options, like
--since for example.
λ git log --author=Zaiste! λ git log --grep=Merge --since=1.week
By Author AND By Commit Message
In order to find commits authored by a specific person that contain certain words in the commit message, I could use one of the following commands.
λ git log --author=Zaiste! --grep=Merge --since=1.month λ git log --all-match --grep=Merge --author=Zaiste!
It differs from what says
git help as the first of these commands is supposed
to look for an author OR a message, but it does AND instead; as a result
--all-match is not needed.
At this point, we already know how to look through commit messages, find commits authored by a specific person, etc. Let's learn how to search in the source code.
The simplest command looks like this:
λ git grep <regexp>
It searches for a specifc
regex expression in the working tree. There is a
useful option, called
--function-context which gives a « context » for the
search. Let's compare:
For a more clear
git grep output with filename heading & line numbers, I use
three additional options:
To search in the current head, use the following command:
λ git grep <regex> HEAD
To search only through
.md files, in the working directory, try this:
λ git grep 'map' -- '*.md'
These options can be easily combinated. For example, to search in the
feature and only through
.clj, use following:
λ git grep -e 'map' next HEAD -- '*.clj'
We can also search all revisions for a specified
regexp, like so:
λ git grep <regexp> $(git rev-list --all)
Or, we can limit the search to all revisions between rev1 and rev2, like so:
λ git grep <regexp> $(git rev-list <rev1>..<rev2>)
We can combine several
regexp expressions. For example, to search working tree for lines lines matching both init AND defn:
λ git grep -e init --and -e defn
Or, to search working tree for lines that match at least one of these two
λ git grep -e init -e defn
Finally, the following command will give the names of the files that have both defn and init somewhere in them:
λ git grep -l --all-match -e defn -e init
In this article, I only scratched the surface. There is much more options for
git log and
git grep commands. You can get more details on each of these commands via
git help <command>.
In the next post I'll show how
git can be integrated with our favorite text editor: Vim. Stay tuned!