Skip to content

Instantly share code, notes, and snippets.

@emillon
Last active August 2, 2022 14:06
Show Gist options
  • Save emillon/15ddc9a972f0ae6faa7d9a629465f513 to your computer and use it in GitHub Desktop.
Save emillon/15ddc9a972f0ae6faa7d9a629465f513 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""
Usage: git-blame-tags <path>
Annotate lines of <path> with the oldest tag each line is contained in.
"""
from functools import cache
import os.path
import subprocess
import sys
def parse(lines):
try:
while True:
line = next(lines)
sha = line[:40]
for line in lines:
if line.startswith(b"\t"):
line = line[1:].decode()
break
yield sha, line
except StopIteration:
pass
@cache
def tag_for_sha(sha):
o = subprocess.check_output(
[
"git",
"tag",
"--list",
"--contains",
sha,
"--format",
"%(objecttype) %(refname:strip=2)",
"--sort",
"v:refname",
]
)
for line in o.splitlines():
match (line.split(b" ", 1)):
case [b"tag", refname]:
return refname.decode()
if __name__ == "__main__":
path = sys.argv[1]
o = subprocess.check_output(["git", "blame", "-p", path])
for sha, line in parse(l for l in o.splitlines()):
tag = tag_for_sha(sha)
print(f"{tag:10s} {line}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment