Git per WordPress: versionare temi, plugin e configurazioni senza caos

Versionare WordPress con Git non è come versionare un'app React. Il core, i plugin, i temi, gli upload — cosa mettere in repo e cosa no. Il .gitignore che funziona, il deploy con Git, e perché commitare wp-config.php è un rischio di sicurezza.
Git su WordPress è un argomento che divide. Metà degli sviluppatori WordPress non usa Git — lavorano direttamente sul server via FTP, come nel 2005. L'altra metà usa Git ma sbaglia: commitano tutto, incluso il core di WordPress, i plugin di terze parti, e peggio il wp-config.php con le credenziali del database. Il risultato è un repository gonfio, deploy lenti, e un rischio di sicurezza quando le credenziali finiscono su GitHub. Git su WordPress funziona — ma richiede disciplina su cosa versionare e cosa no.
Il principio base: Git versionare il codice che scrivi tu, non il codice che installi. Il core di WordPress, i plugin del repository, i temi premium scaricati — non sono roba tua, non vanno nel tuo repo. Quello che versioni è il tema child, i plugin custom, le configurazioni, e gli snippet che scrivi. Tutto il resto è dipendenza che si reinstalla, non codice da versionare.
Il .gitignore che funziona per WordPress
Il .gitignore è il file che decide cosa Git ignora. Per WordPress, deve ignorare il core, i plugin di terze parti, gli upload, e i file sensibili. Ecco un .gitignore completo e commentato:
# .gitignore per WordPress
# 1. Il core di WordPress — non versionarlo, si reinstalla
/*
!wp-content/
!.gitignore
!README.md
# 2. Dentro wp-content, versionare solo il nostro lavoro
wp-content/*
!wp-content/themes/
!wp-content/plugins/
!wp-content/mu-plugins/
# 3. Temi: ignora i temi di terze parti, versionare solo il child theme
wp-content/themes/*
!wp-content/themes/mio-child-theme/
# 4. Plugin: ignora i plugin di terze parti, versionare solo i custom
wp-content/plugins/*
!wp-content/plugins/mio-plugin-custom/
# 5. MU plugin: versionare (sono quasi sempre custom)
# (già incluso sopra)
# 6. Upload: MAI nel repo (binari, pesanti, no diff)
wp-content/uploads/
# 7. File sensibili: MAI nel repo
wp-config.php
.htaccess
*.log
*.sql
*.zip
# 8. File di sistema
.DS_Store
Thumbs.db
node_modules/
# 9. Cache e temporanei
wp-content/cache/
wp-content/upgrade/
wp-content/backup*Il pattern wp-config.php multi-ambiente
Per gestire configurazioni diverse tra sviluppo, staging e produzione senza commitare credenziali, il pattern è un wp-config.php che include un file locale ignorato da Git:
<?php
// wp-config.php — versione sicura per Git
// Configurazioni base (uguali per tutti gli ambienti)
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
// Configurazioni specifiche per ambiente (dal file locale)
if ( file_exists( __DIR__ . '/wp-config-local.php' ) ) {
require_once __DIR__ . '/wp-config-local.php';
} else {
// Fallback per produzione se il file locale non esiste
define( 'DB_NAME', getenv( 'DB_NAME' ) ?: 'wordpress' );
define( 'DB_USER', getenv( 'DB_USER' ) ?: 'root' );
define( 'DB_PASSWORD', getenv( 'DB_PASSWORD' ) ?: '' );
define( 'DB_HOST', getenv( 'DB_HOST' ) ?: 'localhost' );
}
// Chiavi di sicurezza (genera su https://api.wordpress.org/secret-key/1.1/salt/)
define( 'AUTH_KEY', getenv( 'AUTH_KEY' ) ?: '...' );
define( 'SECURE_AUTH_KEY', getenv( 'SECURE_AUTH_KEY' ) ?: '...' );
// ... (tutte le 8 chiavi)
$table_prefix = 'wp_';
define( 'WP_DEBUG', false );
if ( ! defined( 'ABSPATH' ) )
define( 'ABSPATH', __DIR__ . '/' );
require_once ABSPATH . 'wp-settings.php';
// wp-config-local.php (IGNORATO da Git, diverso per ogni ambiente):
// <?php
// define( 'DB_NAME', 'wordpress_dev' );
// define( 'DB_USER', 'root' );
// define( 'DB_PASSWORD', 'password_locale' );
// define( 'DB_HOST', 'localhost' );
// define( 'WP_DEBUG', true );
// define( 'WP_DEBUG_LOG', true );
// define( 'WP_DEBUG_DISPLAY', true );Deploy con Git: dal repo al server
Il deploy con Git può essere semplice o sofisticato. Il modo più semplice è un git pull sul server — ma richiede accesso SSH e Git installato. Il modo più robusto è un pipeline CI/CD (GitHub Actions, GitLab CI) che fa il deploy automaticamente ad ogni push sul branch principale. Ecco un workflow GitHub Actions per deploy WordPress:
# .github/workflows/deploy.yml — deploy WordPress via SSH
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install SSH key
run: |
mkdir -p ~/.ssh
echo '${{ secrets.SSH_PRIVATE_KEY }}' > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Deploy via SSH
run: |
ssh ${{ secrets.SSH_USER }}@${{ secrets.SERVER_HOST }} << 'EOF'
cd /var/www/html/wp-content/themes/mio-child-theme
git pull origin main
# Svuota la cache se necessario
wp cache flush --allow-root 2>/dev/null || true
EOF
- name: Notify
if: always()
run: echo 'Deploy completato'Git su WordPress non è complicato — è disciplinato. Versionare solo il codice tuo, ignorare il resto, proteggere le credenziali, e automatizzare il deploy. Senza disciplina, Git su WordPress è un repository gonfio con credenziali esposte. Con disciplina, è il sistema che ti permette di lavorare con sicurezza, tornare indietro quando qualcosa si rompe, e deployare senza FTP. La differenza è nel .gitignore e nel wp-config.php — i due file che separano un setup professionale da uno amatoriale.
Codice pulito, prestazioni e dipendenze ridotte al minimo.
Sviluppo WordPress personalizzato: temi leggeri, plugin su misura e integrazioni API senza appesantire il sito.
Articoli correlati

REST API WordPress: registrare endpoint custom con register_rest_route e permission_callback
Leggi
Testing e CI/CD per WordPress: pipeline automatizzate per non rompere il sito in produzione
Leggi
