diff --git a/bin/git-rscp b/bin/git-rscp new file mode 120000 index 0000000..d34840f --- /dev/null +++ b/bin/git-rscp @@ -0,0 +1 @@ +git-scp \ No newline at end of file diff --git a/bin/git-scp b/bin/git-scp new file mode 100755 index 0000000..6ae8298 --- /dev/null +++ b/bin/git-scp @@ -0,0 +1,178 @@ +#!/usr/bin/env bash + +COLOR_RED() { echo -en "\033[31m"; } +COLOR_GREEN() { echo -en "\033[32m"; } +COLOR_YELLOW(){ echo -en "\033[33m"; } +COLOR_BLUE() { echo -en "\033[34m"; } +COLOR_RESET() { echo -en "\033[0m"; } + +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 $? +} + +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 $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 [ref|file..] # scp and stage your files to specified remote + git scp [] # show diff relative to and upload unstaged files to + git rscp [] # copy 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 diff --git a/etc/bash_completion.sh b/etc/bash_completion.sh index d994a42..de3feaf 100644 --- a/etc/bash_completion.sh +++ b/etc/bash_completion.sh @@ -86,6 +86,14 @@ _git_refactor(){ __git_extras_workflow "refactor" } +_git_scp(){ + __git_complete_remote_or_refspec +} + +_git_rscp(){ + __git_complete_remote_or_refspec +} + _git_squash(){ __gitcomp "$(__git_heads)" } diff --git a/man/git-scp.1 b/man/git-scp.1 new file mode 100644 index 0000000..97d8fdb --- /dev/null +++ b/man/git-scp.1 @@ -0,0 +1,206 @@ +.\" generated with Ronn/v0.7.3 +.\" http://github.com/rtomayko/ronn/tree/0.7.3 +. +.TH "GIT\-SCP" "1" "December 2014" "" "Git Extras" +. +.SH "NAME" +\fBgit\-scp\fR \- Copy files to SSH compatible \fBgit\-remote\fR +. +.SH "SYNOPSIS" +. +.nf + +`git scp` \-h|help|? +`git scp` [\.\.\.|\.\.\.] +`git rscp` +. +.fi +. +.SH "DESCRIPTION" +A convenient way to copy files from the current working tree to the working directory of a remote repository\. If a \fB\.\.\.\fR is provided, only files that has changed within the commit range will be copied\. +. +.P +Internally this script uses \fBrsync\fR and not \fBscp\fR as the name suggests\. +. +.P +\fBgit\-rscp\fR \- The reverse of \fBgit\-scp\fR\. Copies specific files from the working directory of a remote repository to the current working directory\. +. +.SH "OPTIONS" + +. +.IP "" 4 +. +.nf + +The git remote where you want to copy your files\. +. +.fi +. +.IP "" 0 +. +.P +\.\.\. +. +.IP "" 4 +. +.nf + +Any commit, commit range or tree\. Uses `git\-diff`(1) +. +.fi +. +.IP "" 0 +. +.P +\.\.\. +. +.IP "" 4 +. +.nf + +The parameters, when given, are used to limit the diff to the named paths (you can give directory names and get diff for all files under them)\. +. +.fi +. +.IP "" 0 +. +.SH "GIT CONFIGS" +To sanitize files using \fBdos2unix\fR before copying files +. +.IP "" 4 +. +.nf + +$ git config \-\-global \-\-add extras\.scp\.sanitize dos2unix +. +.fi +. +.IP "" 0 +. +.P +You can run the files through PHP lint (i\.e\. \fBphp \-l\fR) before copying files +. +.IP "" 4 +. +.nf + +$ git config \-\-global \-\-add extras\.scp\.sanitize php_lint +. +.fi +. +.IP "" 0 +. +.SH "EXAMPLES" +Make sure you have \fBgit\-remote\fR(1) setup +. +.IP "" 4 +. +.nf + +$ git remote add staging myStagingServer:/var/www/html +. +.fi +. +.IP "" 0 +. +.P +Copy unstaged files to remote\. Useful when you want to make quick test without making any commits +. +.IP "" 4 +. +.nf + +$ git scp staging +. +.fi +. +.IP "" 0 +. +.P +Copy staged and unstaged files to remote +. +.IP "" 4 +. +.nf + +$ git scp staging HEAD +. +.fi +. +.IP "" 0 +. +.P +Copy files that has been changed in the last commit, plus any staged or unstaged files to remote +. +.IP "" 4 +. +.nf + +$ git scp staging HEAD~1 +. +.fi +. +.IP "" 0 +. +.P +Copy files that has been changed between now and a tag +. +.IP "" 4 +. +.nf + +$ git scp staging v1\.2\.3 +. +.fi +. +.IP "" 0 +. +.P +Copy specific files +. +.IP "" 4 +. +.nf + +$ git scp staging index\.html \.gitignore \.htaccess +. +.fi +. +.IP "" 0 +. +.P +Copy specific directory +. +.IP "" 4 +. +.nf + +$ git scp staging js/vendor/ +. +.fi +. +.IP "" 0 +. +.P +Copy files from specific directory to multiple servers +. +.IP "" 4 +. +.nf + +$ for dest in web1 web2 web3; do + git diff \-\-name\-only 4\.8\.3 4\.8\.2 app/code/community app/design skin/ | xargs git scp $dest +done; +. +.fi +. +.IP "" 0 +. +.SH "AUTHOR" +Written by Chern Jie <\fIlim@chernjie\.com\fR> +. +.SH "REPORTING BUGS" +<\fIhttps://github\.com/chernjie/git\-extras/issues\fR> +. +.SH "SEE ALSO" +<\fIhttps://github\.com/tj/git\-extras\fR> diff --git a/man/git-scp.html b/man/git-scp.html new file mode 100644 index 0000000..6a27ed5 --- /dev/null +++ b/man/git-scp.html @@ -0,0 +1,187 @@ + + + + + + git-scp(1) - Copy files to SSH compatible <code>git-remote</code> + + + + +
+ + + +
    +
  1. git-scp(1)
  2. +
  3. Git Extras
  4. +
  5. git-scp(1)
  6. +
+ +

NAME

+

+ git-scp - Copy files to SSH compatible git-remote +

+ +

SYNOPSIS

+ +
`git scp` -h|help|?
+`git scp` <remote> [<commits>...|<path>...]
+`git rscp` <remote> <path>
+
+ +

DESCRIPTION

+ +

A convenient way to copy files from the current working tree to the working directory of a remote repository. If a <commits>... is provided, only files that has changed within the commit range will be copied.

+ +

Internally this script uses rsync and not scp as the name suggests.

+ +

git-rscp - The reverse of git-scp. Copies specific files from the working directory of a remote repository to the current working directory.

+ +

OPTIONS

+ +

<remote>

+ +
The git remote where you want to copy your files.
+
+ +

<commits>...

+ +
Any commit, commit range or tree. Uses `git-diff`(1)
+
+ +

<path>...

+ +
The <paths> parameters, when given, are used to limit the diff to the named paths (you can give directory names and get diff for all files under them).
+
+ +

GIT CONFIGS

+ +

To sanitize files using dos2unix before copying files

+ +
$ git config --global --add extras.scp.sanitize dos2unix
+
+ +

You can run the files through PHP lint (i.e. php -l) before copying files

+ +
$ git config --global --add extras.scp.sanitize php_lint
+
+ +

EXAMPLES

+ +

Make sure you have git-remote(1) setup

+ +
$ git remote add staging myStagingServer:/var/www/html
+
+ +

Copy unstaged files to remote. Useful when you want to make quick test without making any commits

+ +
$ git scp staging
+
+ +

Copy staged and unstaged files to remote

+ +
$ git scp staging HEAD
+
+ +

Copy files that has been changed in the last commit, plus any staged or unstaged files to remote

+ +
$ git scp staging HEAD~1
+
+ +

Copy files that has been changed between now and a tag

+ +
$ git scp staging v1.2.3
+
+ +

Copy specific files

+ +
$ git scp staging index.html .gitignore .htaccess
+
+ +

Copy specific directory

+ +
$ git scp staging js/vendor/
+
+ +

Copy files from specific directory to multiple servers

+ +
$ for dest in web1 web2 web3; do
+    git diff --name-only 4.8.3 4.8.2 app/code/community app/design skin/ | xargs git scp $dest
+done;
+
+ +

AUTHOR

+ +

Written by Chern Jie <lim@chernjie.com>

+ +

REPORTING BUGS

+ +

<https://github.com/chernjie/git-extras/issues>

+ +

SEE ALSO

+ +

<https://github.com/tj/git-extras>

+ + +
    +
  1. +
  2. December 2014
  3. +
  4. git-scp(1)
  5. +
+ +
+ + diff --git a/man/git-scp.md b/man/git-scp.md new file mode 100644 index 0000000..cb63f93 --- /dev/null +++ b/man/git-scp.md @@ -0,0 +1,88 @@ +git-scp(1) -- Copy files to SSH compatible `git-remote` +======================================================= + +## SYNOPSIS + + `git scp` -h|help|? + `git scp` [...|...] + `git rscp` + +## DESCRIPTION + +A convenient way to copy files from the current working tree to the working directory of a remote repository. If a `...` is provided, only files that has changed within the commit range will be copied. + +Internally this script uses `rsync` and not `scp` as the name suggests. + +`git-rscp` - The reverse of `git-scp`. Copies specific files from the working directory of a remote repository to the current working directory. + +## OPTIONS + + <remote> + + The git remote where you want to copy your files. + + <commits>... + + Any commit, commit range or tree. Uses `git-diff`(1) + + <path>... + + The parameters, when given, are used to limit the diff to the named paths (you can give directory names and get diff for all files under them). + +## GIT CONFIGS + + To sanitize files using `dos2unix` before copying files + + $ git config --global --add extras.scp.sanitize dos2unix + + You can run the files through PHP lint (i.e. `php -l`) before copying files + + $ git config --global --add extras.scp.sanitize php_lint + +## EXAMPLES + + Make sure you have `git-remote`(1) setup + + $ git remote add staging myStagingServer:/var/www/html + + Copy unstaged files to remote. Useful when you want to make quick test without making any commits + + $ git scp staging + + Copy staged and unstaged files to remote + + $ git scp staging HEAD + + Copy files that has been changed in the last commit, plus any staged or unstaged files to remote + + $ git scp staging HEAD~1 + + Copy files that has been changed between now and a tag + + $ git scp staging v1.2.3 + + Copy specific files + + $ git scp staging index.html .gitignore .htaccess + + Copy specific directory + + $ git scp staging js/vendor/ + + Copy files from specific directory to multiple servers + + $ for dest in web1 web2 web3; do + git diff --name-only 4.8.3 4.8.2 app/code/community app/design skin/ | xargs git scp $dest + done; + +## AUTHOR + +Written by Chern Jie <> + +## REPORTING BUGS + +<> + +## SEE ALSO + +<>