-
Notifications
You must be signed in to change notification settings - Fork 1
/
git-blamediff
executable file
·88 lines (70 loc) · 2.19 KB
/
git-blamediff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env zsh
setopt extendedglob
[[ $XPLEASE ]] && set -x
if [[ -t 1 ]] || (( $@[(I)--color] > 0 )); then
color_header=$(git config --get-color color.diff.meta bold)
color_hunk_header=$(git config --get-color color.diff.frag cyan)
color_new=$(git config --get-color color.diff.new green)
color_old=$(git config --get-color color.diff.old red)
color=1
fi
toplevel=$(git rev-parse --show-toplevel)
printprefix() {
printf '%s' "$@" ' '
}
parse_porcelain() {
reply=()
output=(${(f)"$(git -C $toplevel --no-pager blame --porcelain -L "$@")"})
output=(${(M)output:#[a-f0-9](#c40)*})
local line
for line in $output; do
reply+=(${line:0:7})
done
}
revs=(${(f)"$(git rev-parse --revs-only "$@")"})
if (( $#revs == 0 )); then
revs=(HEAD '')
elif (( $#revs == 1 )); then
revs=($revs '')
fi
git diff ${color:+--color} "$@" | while IFS= read -r line; do
if [[ $line = ${color_header}diff\ --git* ]]; then
IFS= read -r index
IFS= read -r a_line
IFS= read -r b_line
file=${b_line#*+++ [iwb2]/}
file=${file%$'\e'*}
print -lr -- $line $index $a_line $b_line
elif [[ $line =~ '@@ -([[:digit:]]*)(,[[:digit:]]*)? \+([[:digit:]]*)(,[[:digit:]]*)? @@' ]]; then
oldfrom=$match[1]
if [[ -n $match[2] && $match[2] != ,0 ]]; then
oldto=${match[2]#,}
else
oldto=$oldfrom
fi
newfrom=$match[3]
if [[ -n $match[4] && $match[2] != ,0 ]]; then
newto=${match[4]#,}
else
newto=$newfrom
fi
parse_porcelain $oldfrom,+$oldto $revs[1] -- $file
oldblame=($reply)
parse_porcelain $newfrom,+$newto $revs[2] -- $file
newblame=($reply)
oldindex=1
newindex=1
print -r -- $line
else
if [[ $line = ' '* ]]; then
printprefix $newblame[newindex]
((newindex++))
((oldindex++))
elif [[ $line = $color_old-* ]]; then
printprefix $color_old $oldblame[oldindex++]
elif [[ $line = $color_new+* ]]; then
printprefix $color_new $newblame[newindex++]
fi
print -r -- $line
fi
done