Browsing past revisions of a file
The Glog
command makes it easy to examine all previous revisions of a file. It does this by loading each revision into its own buffer, and queuing them in the quickfix list in chronological order.
You can filter the results
command | action |
---|---|
:Glog
|
load all previous revisions of the current file into the quickfix list |
:Glog -10
|
load the last ten previous revisions of the current file into the quickfix list |
:Glog -10 --reverse
|
load the first ten revisions of the current file into the quickfix list (in reverse chronological order) |
:Glog -1 --until=yesterday
|
load the last version of the current file that was checked in before midnight last night |
Browsing past commits
You can also use the :Glog
command to review past commit objects, by appending a trailing --
argument. By default, this will load all ancestral commit objects into the quickfix list. If you supply a filepath after the --
argument, then the list will be filtered to only include commit objects that touched the specified file.
command | action |
---|---|
:Glog --
|
load all ancestral commit objects into the quickfix list |
:Glog -- %
|
load all ancestral commit objects that touched the current file into the quickfix list |
Note that when fugitive loads a commit object into a buffer, it is interactive in a number of ways. See episode 34 for more details.
Working with the quickfix list
I recommend installing unimpaired.vim, another plugin by Tim Pope. This provides lots of useful pairs of mappings, including a handful that make working with the quickfix list much easier:
unimpaired | Vim | action |
---|---|---|
[q |
:cprev |
jump to previous quickfix item |
]q |
:cnext |
jump to next quickfix item |
[Q |
:cfirst |
jump to first quickfix item |
]Q |
:clast |
jump to last quickfix item |
Searching the working tree with Ggrep
The Ggrep
command is a wrapper for git grep
. It uses the results to populate the quickfix list, so you can easily navigate the result list from inside Vim.
If you want to search your working tree for the text ‘find me’, simply run:
:Ggrep 'find me'
The git grep
command only looks inside files that are tracked by the git repository. The fact that it only looks inside tracked files means that it skips over any files or directories listed in the .gitignore
file.
Searching branches, tags and commits with Ggrep
git grep
is not just limited to reading files on the filesystem. It can look inside any git object. So using git grep
, you can search all files in any of your git branches without first having to switch to the branch.
command | action |
---|---|
:Ggrep findme
|
search for ‘findme’ in working copy files (excluding untracked files) |
:Ggrep --cached findme
|
search for ‘findme’ in the index |
:Ggrep findme branchname
|
search for ‘findme’ in branch ‘branchname’ |
:Ggrep findme tagname
|
search for ‘findme’ in tag ‘tagname’ |
:Ggrep findme SHA
|
search for ‘findme’ in the commit/tag identified by SHA |
When you open a file that belongs on another branch, fugitive will automatically create a read only buffer for it.
Searching for text in a commit message
If you want to search the text of commit messages, you can do so by passing the --grep
option to the git log
command. For example, if you wanted to find commit messages containing the text ‘findme’, you could run:
git log --grep=findme
You can also do this from inside of Vim using the :Glog
wrapper. This table summarizes a couple of ways you might use this:
command | action |
---|---|
:Glog --grep=findme --
|
search for ‘findme’ in all ancestral commit messages |
:Glog --grep=findme -- %
|
search for ‘findme’ in all ancestral commit messages that touch the currently active file |
Searching for text added or removed by a commit
Git also makes it possible to search for text that was added or removed by a commit using the pickaxe option. This is activated with the -S
switch as follows:
git log -Sfindme
This tells git to go through every commit, comparing the before and after state of each file that was changed by that commit. If the specified string is present in the file before, but absent from the file after the commit, then it counts as a match. The converse is also true, so if the specified string was either added or removed by the commit, then it will appear the git log results.
Here are a couple of examples demonstrating how the pickaxe option can be used with :Glog
:
command | action |
---|---|
:Glog -Sfindme --
|
search for ‘findme’ in the diff for each ancestral commit |
:Glog -Sfindme -- %
|
search for ‘findme’ in the diff for each ancestral commit that touches the currently active file |
Further reading
:help :Glog
:help :Ggrep
man git-grep
(also,git help grep
)man git-log
(also,git help log
)man gitdiffcore
- the git pickaxe
- Fun with “git grep”
- Fun with “git log –grep”
- Linus’s ultimate content tracking tool