-
Notifications
You must be signed in to change notification settings - Fork 0
/
git-scp
executable file
·215 lines (187 loc) · 4.56 KB
/
git-scp
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/env bash
# reset environment variables that could interfere with normal usage
export GREP_OPTIONS=
# put all utility functions here
# make a temporary file
git_extra_mktemp() {
mktemp -t "$(basename "$0")".XXX
}
#
# check whether current directory is inside a git repository
#
is_git_repo() {
git rev-parse --show-toplevel > /dev/null 2>&1
result=$?
if test $result != 0; then
>&2 echo 'Not a git repo!'
exit $result
fi
}
is_git_repo
COLOR_RED() { test -t 1 && echo -n "$(tput setaf 1)"; }
COLOR_GREEN() { test -t 1 && echo -n "$(tput setaf 2)"; }
COLOR_YELLOW(){ test -t 1 && echo -n "$(tput setaf 3)"; }
COLOR_BLUE() { test -t 1 && echo -n "$(tput setaf 4)"; }
COLOR_RESET() { test -t 1 && echo -n "$(tput sgr 0)"; }
function _test_git_scp()
{
command -v rsync > /dev/null || _error requires rsync
command -v git > /dev/null || _error requires git
command -v ssh > /dev/null || _error requires ssh
command -v php > /dev/null || _info optional php
command -v dos2unix > /dev/null || _info optional dos2unix
}
function set_remote()
{
remote=$1
if [ $(git remote | grep -c -- ^$remote$) -eq 0 ]
then
COLOR_RED
echo "Remote $remote does not exist in your git config"
COLOR_RESET
exit 1
fi
}
# Check file for PHP syntax errors
# takes a list of filenames
function php_lint()
{
local error_count=()
for i
do
# check if file exists
# check if file ends with ".php"
test ! -f "$i" && continue
case "$i" in
*\.php|*\.phtml)
php -l "$i" > /dev/null
[ $? -gt 0 ] && error_count[${#error_count[@]}]="$i"
;;
esac
done
# syntax check fails, force exit
test ${#error_count[@]} -gt 0 &&
COLOR_RED &&
echo "Error: ${#error_count[@]} PHP syntax error found" &&
echo "${error_count[@]}" | tr " " '\n' &&
COLOR_RESET &&
exit 255
return 0
}
function _dos2unix()
{
command -v dos2unix > /dev/null && dos2unix $@
return 0
}
function _sanitize()
{
git config --get-all extras.scp.sanitize | while read i
do
case $i in
php_lint) php_lint $@;; # git config --global --add extras.scp.sanitize php_lint
dos2unix) _dos2unix $@;; # git config --global --add extras.scp.sanitize dos2unix
esac
done
return $?
}
# after push hooks
# depends on git-ssh
function _afterpush()
{
git config --get-all extras.scp.afterpush | while read i
do
case $i in
chown*) git ssh $remote $i $@;; # git config --add extras.scp.afterpush "chown -v :www-data"
esac
done
return $?
}
function scp_and_stage
{
set_remote $1
shift
local refhead="$(git rev-parse --quiet --verify $1)"
if [ -n "$refhead" ]
then
shift
[ $(git branch --contains "$refhead" | grep -c '\*') -eq 0 ] &&
_error "refhead provided is not part of current branch"
fi
if [ $# -ge 1 ]
then
list=$(git ls-files "$@")" "$(git ls-files -o "$@")
elif [ -n "$refhead" ]
then
git diff --stat $refhead
list=$(git diff $refhead --name-only)
else
git diff
list=$(git diff --name-only)
fi
deleted=$(for i in $list; do [ -f $i ] || echo $i; done)
list=$(for i in $list; do [ -f $i ] && echo $i; done)
if [ -n "$list" ]
then
local _TMP=${0///}
echo "$list" > $_TMP &&
_sanitize $list &&
_info Pushing to $remote \($(git config remote.$remote.url)\) &&
rsync -rlDv --files-from=$_TMP ./ "$(git config remote.$remote.url)/" &&
git add --force $list &&
_afterpush $list &&
rm $_TMP
fi
deleted=$(for i in $deleted; do echo $(git config remote.$remote.url | cut -d: -f2)/$i; done)
[ -n "$deleted" ] &&
COLOR_RED &&
echo Deleted remote files &&
ssh $(git config remote.$remote.url | cut -d: -f1) -t "rm $deleted" &&
echo "$deleted"
COLOR_RESET
}
function reverse_scp()
{
set_remote $1
shift
local _TMP=${0///}
echo $@ > $_TMP &&
rsync -rlDv --files-from=$_TMP "$(git config remote.$remote.url)/" ./ &&
rm $_TMP
}
function _info()
{
COLOR_YELLOW
test $# -gt 0 && echo "$@"
COLOR_RESET
}
function _usage()
{
echo "Usage:
git scp -h|help|?
git scp <remote> [ref|file..] # scp and stage your files to specified remote
git scp <remote> [<ref>] # show diff relative to <ref> and upload unstaged files to <remote>
git rscp <remote> [<file|directory>] # copy <remote> files to current working directory
"
case $1 in
-v|verbose|--verbose) grep -A100 '^#* OPTIONS #*$' $0;;
esac
exit
}
function _error()
{
[ $# -eq 0 ] && _usage && exit 0
echo
echo ERROR: "$@"
echo
exit 1
}
### OPTIONS ###
case $(basename $0) in
git-scp)
case $1 in
''|-h|'?'|help|--help) shift; _test_git_scp; _usage $@;;
*) scp_and_stage $@;;
esac
;;
git-rscp) reverse_scp $@;;
esac