Deploy only what changed. A fast, git-diff-powered CLI tool that syncs your local git project to a remote server via FTP, FTPS, or SFTP — no CI/CD pipeline required.
Most FTP/SFTP deploy tools re-upload your entire project on every run. local-git-deploy uses git diff to detect only the files that changed since your last deployment, making it:
- ⚡ Fast — uploads only changed files, not the whole project
- 🔒 Secure — keeps passwords and private keys out of your repo
- 🧹 Clean — automatically deletes removed or renamed files on the remote server
- 🖥️ Local-first — works from your machine, no GitHub Actions or CI server needed
- 🏠 Shared hosting friendly — perfect for cPanel, FTP-only hosts, and PHP projects
Install globally via npm:
npm install -g local-git-deployIn the root of your git project, create a local-git-deploy.yml (or .json) configuration file:
server: ftp.your-server.com
user: your_username
protocol: ftp # Options: ftp | ftps | sftp
port: 21 # 21 for FTP/FTPS, 22 for SFTP
remote_dir: /public_html
exclude: # Glob patterns to exclude from deployment
- ".env"
- "local-git-deploy.yml"
- "node_modules/**"
- ".git/**"Security Best Practice: Never put passwords in your YAML config. Use a
.envfile instead (and make sure.envis in your.gitignore).
# FTP / FTPS password
DEPLOY_PASSWORD=your_super_secret_password
# SFTP private key (optional)
DEPLOY_PRIVATE_KEY_PATH=/path/to/private/key.pemTip: If your SFTP server requires both a private key and a passphrase, provide both DEPLOY_PASSWORD and DEPLOY_PRIVATE_KEY_PATH. The CLI handles both automatically.
Commit your changes locally, then run:
local-git-deployThe CLI will:
- Connect to your remote server
- Read the remote
.deploy-sync-statefile to find the last deployed commit - Run
git diffbetween the remote commit and your localHEAD - Upload only new and modified files
- Delete files that were removed or renamed
- Update the remote state file with the new commit hash
| Protocol | Port | Use Case |
|---|---|---|
ftp |
21 | Basic shared hosting |
ftps |
21 | FTP with TLS/SSL (cPanel, etc.) |
sftp |
22 | SSH-based secure file transfer |
- Git-diff powered deploys — only changed files are transferred
- State tracking — maintains a
.deploy-sync-statefile on the server to track the last deployed commit hash - Deletion & rename handling — automatically cleans up removed or renamed files on the remote
- Glob exclude patterns — skip files like
node_modules,.env, config files - Secure credential handling — passwords and private keys loaded from
.env, never from config files - SFTP private key support — supports passphrase-protected keys and two-factor SFTP servers
- Connection timeouts — prevents hanging on unreachable servers
- Self-signed cert support — opt-in with
insecure: truefor FTPS on dev servers - Resume-safe — if a deploy fails midway, run again and it picks up safely
Deployment failed midway?
No problem. The .deploy-sync-state only updates on a successful deploy. Just fix the issue and re-run local-git-deploy — it will re-attempt only the affected files.
Getting a "bad object" error?
This usually means the state file on the server has a stale or invalid commit hash. Delete the .deploy-sync-state file from your remote server and re-run to do a clean sync.
Filenames with spaces not working?
Make sure you are on v1.1.1 or later. Special character support was added in that release.
Pull requests and issues are welcome! Please open an issue first to discuss any major changes.
pablo-codes — GitHub