blame: allow --contents to work with non-HEAD commit
commit1a3119ed06c8fbb1c00a6aa3615299252575abab
authorJacob Keller <jacob.keller@gmail.com>
Fri, 24 Mar 2023 17:08:00 +0000 (24 10:08 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 24 Mar 2023 19:05:22 +0000 (24 12:05 -0700)
tree681dc2f032eb3f96458a56fb83078cce761b626d
parent73876f4861cd3d187a4682290ab75c9dccadbc56
blame: allow --contents to work with non-HEAD commit

The --contents option can be used with git blame to blame the file as if
it had the contents from the specified file. This is akin to copying the
contents into the working tree and then running git blame. This option
has been supported since 1cfe77333f27 ("git-blame: no rev means start
from the working tree file.")

The --contents option always blames the file as if it was based on the
current HEAD commit. If you try to pass a revision while using
--contents, you get the following error:

  fatal: cannot use --contents with final commit object name

This is because the blame process generates a fake working tree commit
which always uses the HEAD object as its sole parent.

Enhance fake_working_tree_commit to take the object ID to use for the
parent instead of always using the HEAD object. Then, always generate a
fake commit when we have contents provided, even if we have a final
object. Remove the check to disallow --contents and a final revision.

Note that the behavior of generating a fake working commit is still
skipped when a revision is provided but --contents is not provided.
Generating such a commit in that case would combine the currently
checked out file contents with the provided revision, which breaks
normal blame behavior and produces unexpected results.

This enables use of --contents with an arbitrary revision, rather than
forcing the use of the local HEAD commit. This makes the --contents
option significantly more flexible, as it is no longer required to check
out the working tree to the desired commit before using --contents.

Reword the documentation so that its clear that --contents can be used
with <rev>.

Add tests for the --contents option to the annotate-tests.sh test
script.

Signed-off-by: Jacob Keller <jacob.keller@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/blame-options.txt
Documentation/git-blame.txt
blame.c
t/annotate-tests.sh