PHPackages                             oliver-thiele/deployer-git-drift - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Logging &amp; Monitoring](/categories/logging)
4. /
5. oliver-thiele/deployer-git-drift

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

oliver-thiele/deployer-git-drift
================================

Deployer recipe: detect and warn about direct server-side file changes before deployment

v0.1.1-alpha2(today)00MITPHPPHP &gt;=8.2

Since Jun 30Pushed todayCompare

[ Source](https://github.com/oliverthiele/deployer-git-drift)[ Packagist](https://packagist.org/packages/oliver-thiele/deployer-git-drift)[ RSS](/packages/oliver-thiele-deployer-git-drift/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (1)Versions (4)Used By (0)

deployer-git-drift — Detect direct server-side file changes before deployment
=============================================================================

[](#deployer-git-drift--detect-direct-server-side-file-changes-before-deployment)

Deployer recipe that detects and warns about files modified directly on the server (via FTP, SFTP, or SSH) before they are silently overwritten by the next deployment.

[![Packagist Version](https://camo.githubusercontent.com/af7b1726068435ad67cea571a508fdc4eb0d8b4adf2f4e54aeba0c23f7f48012/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f6c697665722d746869656c652f6465706c6f7965722d6769742d64726966742e737667)](https://packagist.org/packages/oliver-thiele/deployer-git-drift)[![PHP](https://camo.githubusercontent.com/726c99ab484d28a15f9c7f0032cbcd8832ac332300ce92de3afb08d5bce895bd/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f6f6c697665722d746869656c652f6465706c6f7965722d6769742d64726966742f7068702e737667)](https://php.net/)[![License](https://camo.githubusercontent.com/d2537b6930fbd6526c47a6d675575aab4bc1b84bcb910f455da66209feb09d85/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6f6c697665722d746869656c652f6465706c6f7965722d6769742d64726966742e737667)](LICENSE)[![Changelog](https://camo.githubusercontent.com/6bc02a7bc61afc1cb3faaa53420df6d904b9940d7f3e2e11a463e1fdbb3cd52d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4368616e67656c6f672d4348414e47454c4f472e6d642d626c75652e737667)](CHANGELOG.md)

> **Early Alpha (v0.1.2-alpha3)** — This package is functional but under active development. Task names and configuration keys may change before v1.0. Use in production at your own risk.

The Problem
-----------

[](#the-problem)

Deployer uses an atomic symlink swap for zero-downtime deployments. This means there is no Git repository on the production server — only the deployed files exist. When someone modifies files directly on the server (editing a config file, quick-fixing a bug via FTP, uploading an asset), those changes are invisible. The next deployment silently overwrites them.

This recipe solves the problem by:

1. Initializing a shallow Git repository in each release directory after deployment
2. Checking for file changes in the current release before the next deployment starts
3. Warning the developer and requiring explicit confirmation before overwriting

Requirements
------------

[](#requirements)

- PHP &gt;= 8.2
- Deployer &gt;= 7.0
- Git installed on the remote server

Installation
------------

[](#installation)

While in alpha, you need to allow alpha stability explicitly:

```
composer require --dev oliver-thiele/deployer-git-drift:@alpha
```

Usage
-----

[](#usage)

In your `deploy.php`:

```
require 'recipe/common.php';
require __DIR__ . '/vendor/oliver-thiele/deployer-git-drift/src/GitDrift.php';

// Hook into the deployment flow
after('deploy:symlink', 'git-drift:init');
before('deploy:vendors', 'git-drift:check');
```

Hooks are opt-in by design — the recipe registers tasks only, not automatic hooks.

Configuration
-------------

[](#configuration)

```
// Always abort when drift is detected (default: false — ask interactively)
set('git_drift_abort_on_drift', true);

// Ignore paths that are expected to differ from the Git state
// Typical candidates: generated files, caches, uploads, installed dependencies
set('git_drift_ignore_paths', [
    'vendor/',
    'node_modules/',
    'public/typo3temp/',
    'var/',
    'public/fileadmin/',
]);
```

Available Tasks
---------------

[](#available-tasks)

TaskDescription`git-drift:init`Initialize Git tracking in the release directory after deployment`git-drift:check`Check for drift before deployment — warns or aborts`git-drift:status`Show drift status without deployingRun the status check manually at any time:

```
dep git-drift:status production
```

Example Output
--------------

[](#example-output)

When drift is detected:

```
⚠ Server drift detected:

 public/index.php | 5 +++--
 config/system/settings.php | 12 ++++++++----

Untracked files added on server:
public/fileadmin/direct-upload.zip

These changes were made directly on the server.
They will be LOST after this deployment.

Continue deployment and discard changes? [y/N]

```

How it works
------------

[](#how-it-works)

After each deployment, `git-drift:init` runs `git init` in the release directory, fetches the deployed branch with `--depth=1`, and sets `FETCH_HEAD` as the baseline via `git reset`. Any subsequent server-side file modifications will appear as changes relative to this baseline.

Paths listed in `git_drift_ignore_paths` are written to `.git/info/exclude` (local gitignore, does not modify project files) so generated directories are excluded from drift detection.

License
-------

[](#license)

MIT — Oliver Thiele

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance100

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/5030298?v=4)[Oliver Thiele](/maintainers/oliverthiele)[@oliverthiele](https://github.com/oliverthiele)

---

Top Contributors

[![oliverthiele](https://avatars.githubusercontent.com/u/5030298?v=4)](https://github.com/oliverthiele "oliverthiele (9 commits)")

---

Tags

monitoringservergitdeploymentdeployerdrift

### Embed Badge

![Health badge](/badges/oliver-thiele-deployer-git-drift/health.svg)

```
[![Health](https://phpackages.com/badges/oliver-thiele-deployer-git-drift/health.svg)](https://phpackages.com/packages/oliver-thiele-deployer-git-drift)
```

###  Alternatives

[rollbar/rollbar

Monitors errors and exceptions and reports them to Rollbar

33724.4M84](/packages/rollbar-rollbar)[liip/monitor-bundle

Liip Monitor Bundle

4748.9M19](/packages/liip-monitor-bundle)[datadog/php-datadogstatsd

An extremely simple PHP datadogstatsd client

19126.4M15](/packages/datadog-php-datadogstatsd)[rollbar/rollbar-laravel

Rollbar error monitoring integration for Laravel projects

14110.7M10](/packages/rollbar-rollbar-laravel)[ohdearapp/ohdear-php-sdk

An SDK to easily work with the Oh Dear API

742.9M16](/packages/ohdearapp-ohdear-php-sdk)[inspector-apm/inspector-php

Inspector monitoring for PHP applications.

352.8M28](/packages/inspector-apm-inspector-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
