Skip to content

Instantly share code, notes, and snippets.

@tanakahisateru
Created November 17, 2011 09:56
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save tanakahisateru/1372816 to your computer and use it in GitHub Desktop.
Save tanakahisateru/1372816 to your computer and use it in GitHub Desktop.
Send changed files under Git via SCP (if SSH password auth)
#!/bin/sh
if [ $# -ne 1 ]; then
echo "$0 <git-commit>" 1>&2
exit 1
fi
git diff --name-status $1
read -p "Press any key to execute..."
rm -rf ./tmp
git diff --name-only $1 | git checkout-index --prefix=./tmp/htdocs/ --stdin
git diff --name-status $1 | awk '{if($1=="D") print $2}' > ./tmp/deleted
auto_ssh()
{
expect -c "
spawn $1
expect {
\" Are you sure you want to continue connecting (yes/no)?\" {
send \"yes\r\"
expect \"password:\"
send \"${2}\r\"
}
\"password:\" {
send \"${2}\r\"
}
}
interact
"
}
auto_ssh 'scp -r ./tmp/htdocs username@hostname.com:/home/vhost/www.hostname.com/htdocs' mypassword
for line in `cat ./tmp/deleted`
do
auto_ssh 'ssh username@hostname.com rm -f /home/vhost/www.hostname.com/htdocs/'$line\' mypassword
done
@codeaid
Copy link

codeaid commented Mar 27, 2012

It doesn't upload unstaged files. I would love to see a script which utilizes "git status --porcelain" to do that and which would use the path of the original file instead of a hardcoded one. Otherwise, nice script :)

@tanakahisateru
Copy link
Author

Thanks to comment. Sorry not useful because it was only technical experiment. You are ok to fork it and modify freely if you want :)

@codeaid
Copy link

codeaid commented Apr 5, 2012

If you're interested, I wrote a bash script which allows you to upload all currently modified files to a remote server at once:
https://gist.github.com/5a97956bb0bacd6a38d5

If you put it in your path and rename git-scp.sh to git-scp then you will be able to execute if just like a git command:
git scp username@domain /remote/target/directory

That will generate a list of all files that have changed and ask if you want to upload them. It will exit if you type anything else but "yes" or "y", otherwise upload all files one by one.

Probably not the most useful script but does the job for me :)

Note - the files will disappear from the list as soon as you commit or revert them. It only lists changed or unadded files as it relies on "git status --porcelain"

@maciej-gurban
Copy link

Hi. I stumbled upon this accidentally, and just wanted to drop a link to similar, but more git-immersed solution: http://stackoverflow.com/a/14714851/2066118

@chernjie
Copy link

Just stumbled upon this. FYI I have done a similar script and have published it at git-extras

Here's how the commands look like

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

Example:

# push all modified tracked files, unstaged
$ git scp web

# push all modified tracked files, including files that has been staged
$ git scp web HEAD

# push a single file
$ git scp web .gitignore

# push a directory
$ git scp web node_modules

# push files that are different between rc1.0.0 and current HEAD
$ git scp web rc1.0.0

@gandrewstone
Copy link

for just a couple of files:
scp git ls-files -m user@ip:dir

@noblige
Copy link

noblige commented Sep 26, 2020

one liner preserving directory structure: rsync -R $(git ls-files -m) user@ip:dir

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment