How best to sync to remote after local development

I'm trying to set up a workflow roughly as follows:-

  1. clone remote git repo to a local directory
  2. sync those local files with a local (ie same filesystem) apache docroot
  3. have those two local directories stay in sync whenever I edit a file (in the cloned git repo)
  4. sync changes back to a remote server when I need to test on that server (or deploy)

I've got 1-3 working perfectly, but I can't figure out how to sync to the remote server.

  • I can do deployment->upload to, which works fine, but takes forever as it seems to be re-uploading everything.
  • Right clicking on a file/dir in project files and selecting 'sync' doesn't seem to do anything
  • Right clicking on a file/dir in the remote host also takes a long time, gives me more detail than I normally want, and doesn't seem to just give me a simple way to mirror local files to remote

So, currently I use a shell rsync command to do the sync which works perfectly and takes only a few seconds to run... but isn't in PHP Storm and means I have to set up rsync scripts for any syncs I want to do.

Is there a simple way to achieve this in PHPStorm, so I can just right click on a file/dir in a project and have the appropriate remote host quickly mirror my local files?



1 comment
Comment actions Permalink

After some help from support and some trial and error, I've figure out a passable way to do this using 'external tools' as described here.

I created a command line script (see below) in PHP and set up the external tool to run with the following parameters:-
"$ProjectName$" "$FilePath$" "$FilePathRelativeToProjectRoot$" "$ProjectFileDir$"

In every project where I want to rsync deploy, I create a file at the top level of that project called remote.deploy, with contents such as:-


Then I can right click on a directory in the project navigator and select the rsync external tool script. It assumes that rsync is over ssh using a key. I'm doing this on a mac and the key passphrase is in my keychain... YMMV on other systems.

It works... most of the time. The biggest problem I have is figuring out what all the parameters actually are - I couldn't find any detailed documentation describing them all.

The script will probably need some tweaking for other systems, but I hope this helps others, and I really hope rsync deployment is built into PHPStorm before too long. It seems I'm not the only person missing this.


$dry_run =FALSE;

$rsync_options = '-avzP --delete';

$excludes[] = '.git';
$excludes[] = '.idea';
$excludes[] = 'remote.deploy';
$excludes[] = '.svn';
$excludes[] = '.DS_Store';

// No user options below here...

foreach( $excludes as $excl )
    $rsync_options .= " --exclude='$excl'";

$project = $agv[1]; //"$ProjectName$"
$source_path = $argv[2]; //"$FilePath$"
$rel_path = $argv[3]; //"$FilePathRelativeToProjectRoot$"
$project_path = $argv[4]; // "$ProjectFileDir$"
if( !$project_path )
    $project_path = $source_path; //HACK! sometimes project path isn't set

//get remote path
if( file_exists("{$project_path}/remote.deploy") )
    $remotes = parse_ini_file( "{$project_path}/remote.deploy", TRUE );
    die( "remote.deploy file not present at top level of project directory ({$project_path}/remote.deploy)." );

//add slash to end of directories
$source_path = rtrim( $source_path, '/' );
$rel_path = rtrim( $rel_path, './' );
$slash = is_dir($source_path) ? '/' : '';

foreach( $remotes as $remote )
    echo "rsync to {$remote['user']}:{$remote['root']}/";
    if( $rel_path ) echo "{$rel_path}{$slash}";
    echo "\n";
    $ssh = empty($remote['key']) ? '' : " -e 'ssh -i {$remote['key']}'";
    $user = empty($remote['user']) ? '' : "{$remote['user']}:";

    $cmd = "rsync {$rsync_options}{$ssh}{$pw} '{$source_path}{$slash}' '{$user}{$remote['root']}/";
    if( $rel_path ) $cmd .= "{$rel_path}{$slash}";
    $cmd .= "'";

    if( $dry_run )
        echo "$cmd\n";
        echo "DEPLOY NOT ACTUALLY RUN...\n";
        echo $cmd;
        echo `$cmd`;

/* EOF */

Please sign in to leave a comment.