Who this is for. Everyone with SFTP access to a site, and the lead who decides who has it. Afterwards you know why a server-side edit undoes itself, and what to do when you find one.

Do not change git-tracked files on a git-deployed environment by FTP, SFTP or any other upload. It still happens, usually under pressure: a typo on the live site, a quick fix to a template before a launch. It works for a few hours or days, and then it undoes itself.

Why the change is lost

A deploy does not merge the branch into what is on the server. It resets the environment's folder hard to the branch (what a push does). Every file git tracks becomes exactly what the branch says, so a tracked file edited on the server is replaced by the branch's version at the next push, by anyone, for any reason, and the deploy still reports success. Commit every server-side change to git promptly, before the next push removes it and brings back whatever it addressed, often looking as if the unrelated push caused it.

On a Twig site the edit may not even work in the meantime: on production, Twig keeps its compiled copy of a template until the cache is cleared, so an uploaded template is not served until someone clears it (compiled templates).

The other damage it does

  • An uncommitted server-side change is not in git, so it is not on staging, not in anyone's working copy, not reviewed, and not in the history anyone will read if the same issue comes back.
  • Uploads add; they rarely delete. Renaming or removing a file by upload usually leaves the old file on the server. Anything still pointing at the old path keeps working there, and breaks on every environment that deploys from git, where the old file does not exist.
  • Editors that upload on save can send files you did not mean to change over whatever someone else deployed, and some mirror deletions too.
  • Files that git does not track are not touched by a deploy, so a file created by upload stays on that one environment for good, unexplained, and missing from all the others.

The rule

Every change to a tracked file goes through git, including the urgent ones. An urgent production fix is a hotfix branch from master, which is minutes, not hours (hotfixes). The one exception worth allowing is when deployment itself has stopped working: when pushes cannot reach the server at all, an upload may be the only way to restore service, and it is followed at once by the same change in git.

Uploading to a development environment that is not connected to a branch, as a quick feedback loop while building, is a different thing and is fine. The rule is about environments that deploy from git.

When it has already happened

  1. Do not push to that branch yet. The next deploy overwrites the server's version.
  2. Download the server's version of the changed files and compare them with the branch. If you do not know which files were changed, compare the whole template folder.
  3. Commit the server's version on a branch and take it through the normal flow, as a hotfix if production depends on it.
  4. Push. The deploy now carries the change, and the server and git agree again.
  5. Remove any files that exist only on the server and are not wanted, through whoever has access, and note what was found.

If a deploy has already overwritten it, the server keeps no copy: the change survives only where it was made, in an FTP client's cache, an editor's local history or a colleague's working copy. Look there first, then redo it in git.