-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit-vimdiff
More file actions
executable file
·133 lines (117 loc) · 3.22 KB
/
git-vimdiff
File metadata and controls
executable file
·133 lines (117 loc) · 3.22 KB
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/bash
#
# Wrapper around git diff that accumulates changes,
# and then calls vim in diff mode on all the changes.
# Unlike gitdifftool, it invokes vim on all the files in
# one go, thereby enabling navigation across all pairs
# of files.
#
# Based on a hack by John Reese (jtr@google.com).
#
# See http://www.kernel.org/pub/software/scm/git/docs/git.html (GIT_EXTERNAL_DIFF)
set -e
# Writes vimdiff rc to temp directory. All in an effort to keep this shell
# script self-contained.
function writerc {
cat >$DIFFDIR/rc <<'ENDRC'
" Color scheme fix:
highlight DiffAdd ctermbg=White
highlight DiffChange ctermbg=White
highlight DiffText ctermbg=Yellow
" Given two open panes, turn on diff mode " and leave the cursor on the left.
" The left one is always the original, so it's set readonly
fun! Diffball()
" help |window-move-cursor| explain these
wincmd w
if expand("%") == "null"
wincmd w | diffthis | set nofoldenable foldcolumn=0
normal <c-w>_
else
wincmd t | diffthis | set nofoldenable foldcolumn=0 readonly
wincmd w | diffthis | set nofoldenable foldcolumn=0
normal ]c " go to first change
endif
" wincmd t
" goto 1
endf
" Go back to the beginning of the list of file pairs.
fun! Diffrewind()
only | set nodiff | rewind | set equalalways | vsplit
wincmd w | next
call Diffball()
endf
" Step to the next pair of files and diff them.
fun! Diffnext()
wincmd t | set nodiff | 2next
wincmd w | set nodiff | 2next
call Diffball()
endf
" Step to the previous pair of files and diff them.
fun! Diffprev()
wincmd t | set nodiff | 2prev
wincmd w | set nodiff | 2prev
call Diffball()
endf
fun! Diffquit()
only | q!
endf
call Diffrewind()
" Bind control-n to next and control-a to rewind.
map <c-n> <c-[>:call Diffnext()<cr>
map <c-p> <c-[>:call Diffprev()<cr>
map <c-a> <c-[>:call Diffrewind()<cr>
map <c-q> <c-[>:call Diffquit()<cr>
ENDRC
}
function main {
export TMPDIR=${TMPDIR:-/tmp}
export DIFFDIR=$(mktemp -d $TMPDIR/git-vimdiff.XXXXXX)
export GIT_VIMDIFF_HELPER=true
GIT_EXTERNAL_DIFF="$0" git-diff $*
if [ -f $DIFFDIR/args ]; then
GIT_ROOT=$(git rev-parse --show-cdup)
if [ ! -z $GIT_ROOT ]; then
cd $GIT_ROOT
fi
writerc
vim -S $DIFFDIR/rc $(cat $DIFFDIR/args)
fi
}
# Invoked on every set of changed files. The
# "old" file is copied to a temp directory and
# made read-only. The new file is copied to
# a temp directory only if it's different
# than the current copy.
function helper {
GIT_PATH=${GIT_ROOT}${1}
OLD_FILE=$2
OLD_HEX=$3
OLD_MODE=$4
NEW_FILE=$5
NEW_MODE=$6
mkdir -p $DIFFDIR/files
# Make a temp dir so that all old file copies are unique.
OUT_DIR=$(mktemp -d $DIFFDIR/files.XXXXXX)
COPY_OF_OLD_FILE=$OUT_DIR/$(basename $GIT_PATH)
cp $OLD_FILE $COPY_OF_OLD_FILE
LEFT=$COPY_OF_OLD_FILE
chmod ugo-w $COPY_OF_OLD_FILE
if [ $GIT_PATH = $NEW_FILE ]; then
RIGHT=$NEW_FILE
else
if diff -q $GIT_PATH $NEW_FILE; then
RIGHT=$GIT_PATH
else
COPY_OF_NEW_FILE=$OUT_DIR/right-$(basename $GIT_PATH)
cp $NEW_FILE $COPY_OF_NEW_FILE
RIGHT=$COPY_OF_NEW_FILE
fi
fi
# Accumulate the arguments for diff.
echo $LEFT $RIGHT >> $DIFFDIR/args
}
if [ $GIT_VIMDIFF_HELPER ]; then
helper "$@"
else
main "$@"
fi