Skip to content

Instantly share code, notes, and snippets.

@carsonreinke
Forked from codeaid/git-scp.sh
Last active Sep 14, 2016
Embed
What would you like to do?
SCP added and modified GIT files
#!/bin/bash
IFS=$'\n'
escape() {
echo -e "\033[$1"
}
# misc styles
c_reset=`escape 0m`
c_bold_on=`escape 1m` ; c_bold_off=`escape 22m`
c_underline_on=`escape 4m` ; c_underline_off=`escape 24m`
# foreground colors
fg_default=`escape 39m`
fg_black=`escape 30m`
fg_red=`escape "1;31m"`
fg_green=`escape 32m`
fg_brown=`escape 33m`
fg_blue=`escape 34m`
fg_magenta=`escape 35m`
fg_cyan=`escape 36m`
fg_white=`escape 37m`
# background colors
bg_default=`escape 49m`
bg_black=`escape 40m`
bg_red=`escape 41m`
bg_green=`escape 42m`
bg_brown=`escape 43m`
bg_blue=`escape 44m`
bg_magenta=`escape 45m`
bg_cyan=`escape 46m`
bg_white=`escape 47m`
me=$(basename $0)
# ensure we have two arguments
if [ $# -ne 2 ]
then
echo
echo " usage: git scp <username@hostname> <target-dir>"
echo
exit 1
fi
username=$1
# remove trailing slashes and escape spaces
targetdir=$(echo $2 | sed 's/\/*$//g' | sed 's/ /\\ /g')
# get list of all changed files
changes=$(git status --porcelain 2>&1)
# exit if git status returned an error code
if [ $? -ne 0 ]
then
echo
echo " ${fg_red}$changes${c_reset}"
echo
exit 1
fi
# file counters
num_modified=0
num_deleted=0
# file length counters
maxfilelength=0
filelength=0
# extract added and modified files
files_modified=$(echo "$changes" | sed -nE 's/^[AM]+[ ]+//p' | tr -d "\"")
# extract deleted files
files_deleted=$(echo "$changes" | sed -nE 's/^[D]+[ ]+//p' | tr -d "\"")
# print modified files (if any)
if [ "$files_modified" != "" ]
then
echo
echo " The following files will be COPIED:"
for file in $files_modified;
do
echo " ${fg_green}$file${c_reset}"
((num_modified++))
filelength=$(echo "$file" | wc -c)
if [ $filelength -gt $maxfilelength ]
then
maxfilelength=$filelength
fi
done
echo " ${fg_cyan}Total files: $num_modified${c_reset}"
fi
# print deleted files (if any)
if [ "$files_deleted" != "" ]
then
echo
echo " The following files will be DELETED:"
for file in $files_deleted;
do
echo " ${fg_red}$file${c_reset}"
((num_deleted++))
filelength=$(echo "$file" | wc -c)
if [ $filelength -gt $maxfilelength ]
then
maxfilelength=$filelength
fi
done
echo " ${fg_cyan}Total files: $num_deleted${c_reset}"
fi
if [ $num_modified -eq 0 ] && [ $num_deleted -eq 0 ]
then
echo
echo "Nothing to sync"
echo
exit 0
fi
echo
echo -n 'Do you want to continue (yes/no)?: '
read answer
# exit it "yes" or "y" not received
if [ "$answer" != "yes" ] && [ "$answer" != "y" ]
then
echo
exit 1
fi
echo
# copy files
if [ "$num_modified" -gt 0 ]
then
echo " ${c_underline_on}Copying:${c_reset}"
for file in $files_modified;
do
mask=$(printf '%%-%ds' $maxfilelength)
printf " $mask " $file
filedir=$(dirname "$file" | sed 's/ /\\ /g')
output=$(scp -q "$file" $username:"$targetdir/$filedir" 2>&1)
if [ $? -eq 0 ]
then
echo "${fg_green}ok${c_reset}"
else
echo "${fg_red}failed${c_reset} ($output)"
fi
done
echo
fi
# delete files
if [ "$num_deleted" -gt 0 ]
then
echo " ${c_underline_on}Deleting:${c_reset}"
for file in $files_deleted;
do
mask=$(printf '%%-%ds' $maxfilelength)
printf " $mask " $file
filedir=$(dirname "$file" | sed 's/ /\\ /g')
output=$(ssh -q $username rm -f "$targetdir/$file" 2>&1)
if [ $? -eq 0 ]
then
echo "${fg_green}ok${c_reset}"
else
echo "${fg_red}failed${c_reset} ($output)"
fi
done
echo
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment