-
Notifications
You must be signed in to change notification settings - Fork 0
/
git-timemachine
executable file
·89 lines (71 loc) · 1.64 KB
/
git-timemachine
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
89
#!/bin/bash
# Prints the content of a given file, or specific lines of that file, for each revision.
# Based on http://stackoverflow.com/questions/17785265/list-all-the-versions-of-a-given-line-number-in-the-git-history
# Place this somewhere in your path and you can invoke it with `git timemachine ...` (see full usage below)
function usage() {
cat <<EOF
Usage: $(basename $0) FILE [START [END]]
Where START and END use the same format as git blame, i.e.
START can be any of:
- Line number (ex: 100)
- /Regex/ (ex: /foo/)
and END can be any of the above plus:
- +offset (ex: +1)
- -offset (ex: -1)
if END is omitted, only matching lines will be shown
EOF
}
if [ $# -eq 0 ] ; then
usage
exit 1
fi
if [ $# -ge 4 ]; then
usage
exit 2
fi
if [ $# -ge 1 ] ; then
FILE=$1
fi
if [ $# -eq 2 ]; then
if [[ "$2" =~ ^[0-9]\+$ ]] ; then
RANGE="$2,$2"
else
RANGE="$2,+1"
fi
LINES="-L $RANGE"
fi
if [ $# -eq 3 ]; then
LINES="-L $2,$3"
fi
function blame() {
RES=$(git blame $@ 2>/dev/null)
if [ $? -eq 0 ]; then
echo "$RES"
else
echo "NO MATCH"
fi
}
function clean() {
echo "$@" | sed 's/^.*[0-9]) //'
}
function show() {
echo "$@"
echo ""
}
if [ ! -e "$FILE" ]; then
echo "ERROR: file does not exist - '$FILE'" >&2
exit 3
fi
OLD=$(blame $FILE $LINES)
for REV in $(git log --format=format:%H $FILE)
do
NEW=$(blame $FILE $LINES $REV 2>/dev/null)
if [ "$(clean "$OLD")" != "$(clean "$NEW")" ]; then
echo "== As of commit ${PREVREV:0:8} =="
show "$OLD"
fi
PREVREV=$REV
OLD=$NEW
done
echo "== As of commit ${REV:0:8} =="
show "$NEW"