I am searching for something like git blame
but instead of showing the commit the line was last changed in, I am interested in what version this line was committed.
So instead of the revision ID, I need the most recent tag at the time of the commit.
You can use the command
$ git blame <file> | awk '{ cmd="git describe --always --tags --abbrev=0 $(echo "$1" | tr -d \"^\") | tr -d \"\n\""; cmd | getline tag; $1=tag; close(cmd); print }'
or in long form
$ git blame <file> | awk '{
cmd="git describe --always --tags --abbrev=0 \
$(echo " $1 " | tr -d \"^\") | tr -d \"\n\""
cmd | getline tag
$1=tag
close(cmd)
print
}'
This command replaces the first column in the git-blame output with the output of git describe --always --tags --abbrev=0 <rev>
. The first column will contain one of two possible values:
If you want to pad/truncate the first column to have a fixed number of characters, you can use
$ git blame <file> | awk '{ cmd="git describe --always --tags --abbrev=0 $(echo "$1" | tr -d \"^\") | tr -d \"\n\" | xargs -0 printf %10s | head -c10"; cmd | getline tag; $1=tag; close(cmd); print }'
which adds | xargs -0 printf %10s | head -c10"
to marshal the first column to have exactly 10 characters. Replace both instances of 10
with your desired width.
Here's an example of the output using the README file from CPython:
v3.12.0b1 README.rst (Thomas Wouters 2023-05-22 21:15:32 +0200 1) This is Python version 3.13.0 alpha 0
v3.11.0b1 README.rst (Pablo Galindo 2022-05-08 03:40:52 +0100 2) =====================================
v1.6a1 README (Guido van Rossum 2000-04-11 17:11:09 +0000 3)
v3.9.0a1 README.rst (Steve Dower 2019-12-16 11:15:08 -0800 4) .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg
v3.9.0a1 README.rst (Steve Dower 2019-12-16 11:15:08 -0800 5) :alt: CPython build status on GitHub Actions
v3.9.0a1 README.rst (Steve Dower 2019-12-16 11:15:08 -0800 6) :target: https://github.com/python/cpython/actions
v3.9.0a1 README.rst (Steve Dower 2019-12-16 11:15:08 -0800 7)
v3.10.0a7 README.rst (Pablo Galindo 2021-05-03 23:36:55 +0100 8) .. image:: https://dev.azure.com/python/cpython/_apis/build/status/Azure%20Pipelines%20CI?branchName=main
v3.7.0a4 README.rst (Steve Dower 2018-09-24 08:04:33 -0400 9) :alt: CPython build status on Azure DevOps
v3.10.0a7 README.rst (Pablo Galindo 2021-05-03 23:36:55 +0100 10) :target: https://dev.azure.com/python/cpython/_build/latest?definitionId=4&branchName=main
v3.7.0a4 README.rst (Steve Dower 2018-08-31 08:11:35 -0700 11)
v3.10.0a6 README.rst (Erlend Egeberg Aasland 2021-04-02 05:30:40 +0200 12) .. image:: https://img.shields.io/badge/discourse-join_chat-brightgreen.svg
v3.10.0a6 README.rst (Erlend Egeberg Aasland 2021-04-02 05:30:40 +0200 13) :alt: Python Discourse chat
v3.10.0a6 README.rst (Erlend Egeberg Aasland 2021-04-02 05:30:40 +0200 14) :target: https://discuss.python.org/
v3.7.0a4 README.rst (Steve Dower 2018-08-31 08:11:35 -0700 15)
v3.7.0a4 README.rst (Mariatta 2018-06-29 13:43:45 -0700 16)
v3.12.0a3 README.rst (Benjamin Peterson 2023-01-08 09:13:25 -0600 17) Copyright © 2001-2023 Python Software Foundation. All rights reserved.
v2.4 README (Guido van Rossum 2007-08-30 17:16:55 +0000 18)
v3.6.0b2 README.rst (Zachary Ware 2017-02-13 22:01:03 -0600 19) See the end of this file for further copyright and license information.
Some additional implementation notes
--always
is needed in the git describe
invocation to output the commit ID when no tag can be found.--abbrev=0
is needed in the git describe
invocation to only output the closest tag.--tags
in the git describe
invocation enables both lightweight and annotated tags.git blame
is processed through tr -d "^"
to remove the ^
prefix present when the line was last modified in the root commit.