11

When I'm working on a branch, I want to quickly jump to my "TODO" comments. This means

  1. I only want "TODO" comments that were added on my branch (ignore the ones in master)
  2. I want each match to show the file and line number.

I know two partial solutions: git grep TODO has the right format (with grep.lineNumber set to true), but too many results. git diff master... | grep TODO is a good set of results, but doesn't show file and line number.

Is there an option to tell git diff to prefix each changed line with the filename and line number? (--line-prefix looked promising but seems to take only a fixed string.)

Can I pass --new-line-format=":%dn: %L" (diff - output line-numbers) through git diff?


For example, currently my search results look like this:

$ git diff master... | grep TODO
+    // TODO use a non-fatal assertion
+        // TODO use a non-fatal assertion
+// TODO make this conditional too

But ideally I'd like this:

src/foo/abc.cpp:221:+    // TODO use a non-fatal assertion
src/foo/xyz.cpp:934:+        // TODO use a non-fatal assertion
src/foo/util/extra.h:49:+// TODO make this conditional too
1
  • 1
    This! Did you manage to get src/foo/abc.cpp:221:+ // TODO use a non-fatal assertion working?
    – artemave
    Commented Jun 16, 2021 at 10:19

3 Answers 3

2

You can use the patch mode of git log:

git log -p
# Hit '/' for search mode.
# Type TODO
# Then hit 'n' for next

To restrain to your branch you can add firstcommit...HEAD

1

I wanted to do the exact same thing as OP: find TODOs added on my branch.

So I put together a diff2vimgrep script. And then plugged it in fzf.vim (a fuzzy finder for vim):

command! -bang -nargs=0 RgDiffMaster call fzf#vim#grep("git diff master... | diff2vimgrep", 0, {}, <bang>0)

And voila: demo

0

You almost got it right. From the official git-grep documentation :

-h
-H
  By default, the command shows the filename for each match. -h option is used
  to suppress this output. -H is there for completeness and does not do
  anything except it overrides -h given earlier on the command line.

...

-n
--line-number
  Prefix the line number to matching lines.

This means that the following command

git grep -n TODO

should display all files containing "TODO" along with their name (default behaviour) and the line number for the match (with -n). Example output :

lib/my_script.py:67:    # TODO patch this
      ^          ^            ^
      |          |            |
  filepath    line number   matched line

If there are too many matches, you can use :^some_folder to exclude the folder some_folder from the grep search (see "Examples" paragraph) :

git grep -n TODO :^some_folder

or pipe shell commands like sed or awk to filter the output for only the files or folders you want.

Furthermore, you can set line numbers to be displayed by default (see "Configuration" paragraph) :

grep.lineNumber
  If set to true, enable -n option by default.

which can be set as explained in the different answers to this question, for example with :

git config --global grep.lineNumber true
1
  • Thanks for your answer. I do have grep.lineNumber enabled, and I forgot it wasn't the default (I'll edit my question). Can I restrict the search to lines I added, though? I may have touched a file with dozens of existing TODOs.
    – dpercy
    Commented Jan 12, 2021 at 16:54

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.