Comment by ozay

2 years ago

git blame shows only who made the last change. Maybe that person only changed the name of a variable, applied a codestyle change, moved a function declaration to another file or many other things that the change was almost irrelevant to the code behavior.

There are a few options that help you out with this:

-M Detect moved or copied lines within a file

-C In addition to -M, detect lines moved or copied from other files that were modified in the same commit.

--ignore-rev <rev> Ignore changes made by the revision when assigning blame, as if the change never happened

--ignore-revs-file <file> Ignore revisions listed in file

https://git-scm.com/docs/git-blame

I wish they would make long option names for everything, including -C and -M. (Perhaps I should contribute that..)

I use short options interactively on the command line, but in scripts and when communicating with other people, I prefer longer options because they are self-documenting and can catch most typos. (For a long option, typos are more likely to result in an invalid option, and thus an error message. For one-letter options, a typo could result in anything..)

  • FWIW, -C has precedents: `make` and `tar` have the same option with the same meaning.

    • Yes, sticking to precedent is a good idea in general, too. But that's independent of long options.

I recommend just skipping blame and going to git log -L to see the full evolution of a range of lines, I set up a little keybind in vim which does this for the current visual selection and it works much better than blame.

  • Nice. Can you share your vim configuration for that?

    • My config is kind of cluttered so this is a simplified version without dependencies. Glogr is for range history, GLogf for file history and <leader>gc for showing a commit based on hash:

          nnoremap <leader>gc :Gshow <C-R><C-W><cr>
          command! -nargs=1 Gshow enew | set ft=diff buftype=nofile | 0r!git log -p -n 1 "<args>"
          command! -nargs=0 Glogf tabnew | set ft=diff buftype=nofile | 0r!git -C "#:h" log -p --follow "#:t"
          command! -nargs=0 -range Glogr tabnew | set ft=diff buftype=nofile | 0r!git -C "#:h" log -L "<line1>,<line2>:#:t"

These are the things that can be a chore to find in man pages. There needs to be a way to "sort" man page elements to show most commonly used switches first.