File: git-scp

package info (click to toggle)
git-extras 7.4.0-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 2,120 kB
  • sloc: sh: 4,312; python: 994; makefile: 146
file content (181 lines) | stat: -rwxr-xr-x 4,046 bytes parent folder | download
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
#!/usr/bin/env bash

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)
				if ! php -l "$i" > /dev/null; then
					error_count[${#error_count[@]}]="$i"
				fi
			;;
		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 -r 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 $?
}

function scp_and_stage
{
	set_remote "$1"
	shift

	local refhead
	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///}
		# shellcheck disable=SC2086
		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 &&
		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