Using git-ftp for Simpler Project Deployments via FTP/SFTP
Streamline your workflow with this simple tool
Originally published: September 8th, 2015. Updated on: April 29th, 2025.
A vital part of any web project is the final step: pushing your code and assets onto a live server. Not only that, but you also need an easy way to deploy subsequent bug fixes and feature updates. This can become time-consuming, especially if you're limited to FTP or SFTP access on your deployment server. Keeping track of which files changed locally versus remotely can quickly turn into a headache. We've all been there, right?
Some things to consider for deployment:
- How are assets distributed? Filesystem only, or database involved too?
- What kind of access do you have to the production server (e.g., Shell/SSH, or just FTP/SFTP)?
- Are you using version control (like Git) for your source code?
This guide focuses on a solution for situations where:
- You use Git for version control.
- You are limited to FTP or SFTP access on the deployment server (no Git access on the server itself).
Enter git-ftp
git-ftp is a clever script that acts as an FTP/SFTP client specifically designed for Git repositories. It intelligently transfers only the files that have changed since your last deployment, leaving untouched files alone unless explicitly told otherwise.
It's typically run as a shell script from your local command line.
Your Server Environment
If your deployment server is on shared hosting or an otherwise locked-down system, you might not have shell (SSH) access. This means you can't use standard Git commands (git pull
, git push
) directly on the server to deploy. In such cases, FTP or SFTP is often your only way to upload files. git-ftp
bridges this gap.
How git-ftp Works
-
Installation & Configuration: You can find installation instructions on the official git-ftp GitHub page. Once installed (e.g., within Git Bash on Windows, or natively on Linux/macOS), you configure your deployment settings directly within your project's
.git/config
file. This keeps deployment settings version-controlled along with your project. Very handy! Configuration examples (see the man page for full details):# Set username, server address, and password (use secure methods like keys instead of password!) git config git-ftp.user your-ftp-username git config git-ftp.url [ftp.yourserver.com/path/to/public_html](https://ftp.yourserver.com/path/to/public_html) git config git-ftp.password 'YourFtpPassword' # Avoid storing passwords here if possible! # For SFTP (recommended over FTP) # git config git-ftp.url sftp://[sftp.yourserver.com/path/to/public_html](https://sftp.yourserver.com/path/to/public_html) # Consider using SSH keys for passwordless authentication with SFTP.
-
Initial Deployment (
init
): The first time you deploy to a server, you run:git ftp init -v
This uploads all files from your current Git branch to the remote server. The
-v
(verbose) flag provides feedback, which is useful for large uploads. Crucially,git-ftp
also uploads a special log file (usually.git-ftp.log
) to the server. This file stores the SHA hash (commit ID) of the commit you just deployed. -
Subsequent Deployments (
push
): After making changes, committing them locally in Git, you deploy updates using:git ftp push -v ```git-ftp` now does the following: * Checks the commit hash stored in the `.git-ftp.log` file on the server. * Compares that hash with your local Git history to determine which files have been added, modified, or deleted since the last deployment. * Connects via FTP/SFTP and transfers *only* the changed/new files and deletes any files that were removed in your commits.
Example Workflow:
- Initial state:
file1.txt
,file2.php
,file3.jpg
- Run
git ftp init -v
-> Uploads all 3 files +.git-ftp.log
- Local changes: Modify
file2.php
, deletefile3.jpg
, commit changes. - Run
git ftp push -v
-> Uploads the newfile2.php
, deletesfile3.jpg
on the server.file1.txt
is untouched.
Other Useful Features
.git-ftp-ignore
/.git-ftp-include
: Specify files or patterns to explicitly exclude (like local config files) or include (if not tracked by Git) during transfers.- Scopes: Define multiple deployment environments (e.g.,
staging
,production
) within the same.git/config
, allowing you to push to different servers easily (git ftp push -s staging
).
Limitations
- No Server-Side Edits: You cannot make changes directly on the server via FTP/SFTP when using this workflow. All changes must be made locally, committed to Git, and then deployed using
git-ftp
. Editing files directly on the server will put it out of sync with the log file and cause issues on the next push. - Team Workflow: It might not be ideal for large, rapidly-changing teams. Committing new code while a transfer is in progress could potentially cause sync issues. The team needs to coordinate or use it primarily for single-developer or controlled release scenarios.
- Commit Requirement: You must commit your changes locally before running
git ftp push
. This encourages good Git practice (commit often!) but might feel slightly cumbersome if you're used to testing frequently via direct FTP uploads without committing. - Database Not Handled: This method only handles files tracked by Git. It doesn't manage database deployments or migrations. You'll need separate tools or processes for database changes (which is common for most deployment methods anyway).
Conclusion
Despite the limitations, I find git-ftp
incredibly useful, especially for projects hosted on servers with only FTP/SFTP access, or for simpler file-based sites (like those built with static site generators or file-based CMSs like Statamic, Grav, or Kirby). It brings the intelligence of Git diffing to the world of FTP deployment, saving significant time and reducing errors compared to manual uploads. For my purposes, it often provides everything I need.
If you're stuck with FTP/SFTP but use Git locally, give git-ftp
a try – it might significantly streamline your deployment process. Feel free to get in touch if you have questions about setting it up for your project.