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:
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