Skip to content

Commit 08afa8e

Browse files
committed
Support focus on relevant line ranges; print chart release date.
1 parent 7573e59 commit 08afa8e

1 file changed

Lines changed: 50 additions & 15 deletions

File tree

hack/bin/super-blame.sh

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@ set -euo pipefail
33

44
usage() {
55
cat <<EOF
6-
Usage: $0 [-h] <file> [file ...]
6+
Usage: $0 [-h] <file>[@<lines>] [file ...]
77
88
List commits that changed the given file(s) in chronological order,
99
annotated with the release in which each commit landed on master.
1010
1111
A commit's release is the oldest chart/X.Y.0 tag on master whose
1212
tagged commit is not older than the commit itself.
1313
14+
Line ranges limit output to commits that changed those lines.
15+
Syntax: file.hs@1,15-18 (single lines and ranges, comma-separated)
16+
If no line ranges are given, all commits for the file are shown.
17+
1418
Options:
1519
-h Show this help
1620
EOF
1721
exit 0
1822
}
1923

2024
if [ $# -eq 0 ]; then
21-
echo "Usage: $0 [-h] <file> [file ...]" >&2
25+
echo "Usage: $0 [-h] <file>[@<lines>] [file ...]" >&2
2226
exit 1
2327
fi
2428

@@ -32,32 +36,63 @@ trap 'rm -f "$releases_tmp"' EXIT
3236
while read -r tag; do
3337
commit=$(git rev-list -1 "$tag")
3438
ts=$(git log -1 --format="%ct" "$commit")
35-
echo "${ts} ${tag}"
39+
date=$(git log -1 --format="%ai" "$commit")
40+
echo "${ts} ${tag} ${date}"
3641
done < <(git tag --merged master 'chart/*.0' | sort -V) > "$releases_tmp"
3742

38-
for file in "$@"; do
39-
if [ ! -f "$file" ]; then
40-
echo "Error: file not found: $file" >&2
41-
exit 1
42-
fi
43-
44-
echo "=== $file ==="
45-
46-
git log --follow --format="%H %ct %ai %s" -- "$file" | while read -r commit commit_ts rest; do
43+
annotate() {
44+
while read -r commit commit_ts rest; do
4745
release=""
48-
while read -r ts tag; do
46+
release_date=""
47+
while read -r ts tag rdate; do
4948
if [ "$ts" -ge "$commit_ts" ]; then
5049
release="$tag"
50+
release_date="$rdate"
5151
break
5252
fi
5353
done < <(sort -n "$releases_tmp")
54-
5554
if [ -n "$release" ]; then
56-
echo "$commit $rest [$release]"
55+
echo "$commit $rest [$release $release_date]"
5756
else
5857
echo "$commit $rest [unreleased]"
5958
fi
6059
done
60+
}
61+
62+
for arg in "$@"; do
63+
file="${arg%@*}"
64+
lines="${arg##*@}"
65+
if [ "$file" = "$arg" ]; then
66+
lines=""
67+
fi
68+
69+
if [ ! -f "$file" ]; then
70+
echo "Error: file not found: $file" >&2
71+
exit 1
72+
fi
73+
74+
echo "=== $arg ==="
75+
76+
if [ -z "$lines" ]; then
77+
git log --follow --format="%H %ct %ai %s" -- "$file" | annotate
78+
else
79+
l_args=()
80+
IFS=',' read -ra ranges <<< "$lines"
81+
for r in "${ranges[@]}"; do
82+
if [[ "$r" == *"-"* ]]; then
83+
start="${r%-*}"
84+
end="${r#*-}"
85+
else
86+
start="$r"
87+
end="$r"
88+
fi
89+
l_args+=("-L" "${start},${end}:${file}")
90+
done
91+
git log "${l_args[@]}" --format="%H %ct %ai %s" 2>/dev/null \
92+
| grep -E '^[0-9a-f]{40} [0-9]{10}' \
93+
| awk '!seen[$1]++' \
94+
| annotate
95+
fi
6196

6297
echo
6398
done

0 commit comments

Comments
 (0)