When reviewing code changes in a terminal, running git diff tells you what changed, while git blame tells you who last touched a specific line and when. However, standard Git commands don't combine these two views natively. If you want to see a diff where each deleted or context line displays its associated commit hash or author metadata, you need a specialized tool or script.

In this guide, we will explore several modern solutions to get inline blame context directly within your terminal diff output.

Method 1: Using Modern Terminal Diff Viewers (Recommended)

The easiest way to get enhanced diff output with built-in context in the terminal is by using dedicated CLI tools designed for Git visualization.

1. Delta (git-delta)

Delta is a syntax-highlighting pager for Git that dramatically improves terminal output. While Delta focuses primarily on side-by-side and syntax-highlighted diffs, it can be integrated with Git aliases or run alongside interactive blame viewers.

2. Tig (Text-mode Interface for Git)

If you need an interactive terminal session where diffs and blames live together seamlessly, Tig is the standard solution.

# Install tig (macOS / Linux)
brew install tig       # macOS
sudo apt install tig   # Ubuntu/Debian

# Open tig blame view for a file
tig blame path/to/file.py

Inside tig blame, pressing d on any line opens the main diff for that specific commit in a split window, giving you immediate contextual diff and blame history.

Method 2: Custom Python Script to Annotate Git Diff with Blame

If you want a non-interactive CLI output that directly prints the standard diff hunk decorated with the commit hash from git blame, you can parse the diff output using a lightweight Python script.

Save the following script as git-diff-blame.py in your PATH:

#!/usr/bin/env python3
import re
import subprocess
import sys

def run_cmd(cmd):
    return subprocess.check_output(cmd, shell=True, text=True)

def diff_with_blame():
    # Get standard diff
    try:
        diff_output = run_cmd("git diff HEAD")
    except subprocess.CalledProcessError:
        return

    current_file = None
    hunk_re = re.compile(r"^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@")

    for line in diff_output.splitlines():
        if line.startswith("--- a/"):
            current_file = line[6:]
            print(line)
            continue
        elif line.startswith("+++"):
            print(line)
            continue
        
        match = hunk_re.match(line)
        if match:
            old_start = int(match.group(1))
            print(line)
            current_old_line = old_start
            continue

        # Process removed or context lines
        if (line.startswith("-") or line.startswith(" ")) and current_file:
            try:
                blame = run_cmd(f"git blame -L {current_old_line},{current_old_line} --porcelain HEAD -- {current_file}")
                commit = blame.splitlines()[0].split()[0][:8]
            except Exception:
                commit = "00000000"
            
            print(f"[{commit}] {line}")
            if line.startswith("-") or line.startswith(" "):
                current_old_line += 1
        else:
            print(line)

if __name__ == "__main__":
    diff_with_blame()

Make the script executable and add a Git alias for convenient usage:

chmod +x git-diff-blame.py
git config --global alias.diff-blame "!python3 /path/to/git-diff-blame.py"

Now running git diff-blame will prefix changed lines with the 8-character commit hash responsible for that line prior to your modifications.

Method 3: Native Line-Level History (`git log -L`)

If you are trying to understand how a specific block of code evolved alongside its diffs, Git provides a powerful built-in command without requiring extra tools:

git log -L <start_line>,<end_line>:<path/to/file>

For example, to trace lines 15 to 30 of app.py along with the commit diffs that affected those lines:

git log -L 15,30:app.py

This outputs the exact sequence of commits, authors, commit messages, and the corresponding diff for those specific lines over time.

Summary

  • Use Tig for a fast, interactive terminal UI combining diff and blame.
  • Use a custom Python script if you require raw terminal stdout containing line hashes embedded inside diff hunks.
  • Use git log -L to inspect historical diffs for specific line ranges without third-party dependencies.