Barry Coughlan

05 May 2022

Git detective cheatsheet

Here is a little collection of Git tricks for tracking down changes in a codebase. These can help you find when and why a change was made, who to reach out to with a problem, and how to trace the change back to a PR and other discussions.

General tip: using the pager

Git uses less as a pager by default. less has a lot useful vim-like commands for navigating the output, like / for search, G to go to the end. See the man page for the full list.

General tip: browsing git logs

For a lot of these commands it’s nice to have a readable git log format. The alias I prefer is:

[alias]
  l = log --graph --decorate --color --pretty=format:'%h %Cred%an%Creset %Cgreen%cr%Creset %s %C(bold blue)%d%Creset'

Which looks like this:

git log alias

Show history of changes to a file

git log -p -- '**/hello.py'
  • -p Show changes (like git diff)
  • -- Git treats everything after this as a file pattern
  • **/ Search all subfolders

Search commit messages

git log --grep '#123' 

This shows all commits with #123 in the commit messge.

Search commit contents

git log -p -G 'foo' 

This will show all changes where the diff contains foo. The value passed to -G is a regex.

You can also add --all to search all branches which is useful for finding stray unmerged changes.

Show number of commits by each author

git shortlog -sne -100 --no-merges
  • -s Show summary stats.
  • -n Sort by number of commits (descending).
  • -e Show e-mail address of author.
  • -100 Last 100 commits only.
  • --no-merges ignore merge commits.

Sample output:

   279  John Casner <john.casner@gmail.com>
   146  Wendy Hill <wendy.hill@acme.corp>
    76  Hunter Monds <hunter.monds@example.com>

Show all commits by $author

git log -i --author="$author"

-i makes it case insensitive.

The author parameter is a regular expression so you can do partial matches, e.g. --author="bc" will match author bcoughlan.

You can also add other git log options, e.g. add --stat to show the modified filenames.

Exclude author from git log

This can be useful if your git log is full of commits from CI tools:

git log --invert-grep --author="$author"

When was $commit merged to $branch?

Merge commits can contain useful information such as pull request and bug tracker identifiers.

Use git-when-merged to find the merge commit from any commit.

git when-merged -l $commit $branch

-l show merge commit SHA and message.

Which commits are on $branch1 that are not on $branch2?

git log --no-merges $branch1 ^$branch2

Which branches have been recently modified?

git for-each-ref --sort='authordate:iso8601' --format=' %(color:green)%(authordate:relative)%09%(color:white)%(refname:short)' refs/heads

I like to alias this as git wip. Source from this gist by carolynvs.

Which version introduced a commit?

git tag --contains $commit

You can then look for the earliest tag. You can also sort by date if you find it easier:

git tag --contains $commit --format='%(creatordate:short) %(refname:strip=2)' --sort -creatordate

Who last modified each line in README.md?

git blame README.md

… starting at line 100

git blame -L100 README.md

… only show lines 10 to 15

git blame -L10,15 README.md

… only show commits before $commit

git blame $commit^ README.md