WordPress Full vs View: Dua Repo Git, Dua Isu Berbeda
Satu WordPress, dua repo Git: repo full di Forgejo untuk pemulihan, repo view di GitHub hanya untuk sumber yang saya tulis sendiri.
Mula-mula cuma pertanyaan sepele: .gitignore seperti apa sih untuk WordPress? Lama-kelamaan pertanyaan itu berubah jadi disiplin yang lebih mendasar: satu WordPress, dua repo Git, dua isi yang beda total. Repo "full" di Forgejo untuk pemulihan, repo "view" di GitHub untuk kode sumber publik. Yang bikin rumit ternyata bukan git-nya, tapi keputusan soal isi: apa yang boleh masuk ke masing-masing repo.
Repo full itu set pemulihan, bukan dump
Anggapan umum: repo privat yang full berarti semua byte ikut masuk. Dua hal membuat anggapan itu salah. Pertama, secret plaintext. wp-config.php atau file env berisi nilai asli tetap saya keluarkan, bahkan dari repo privat sekalipun. Alasannya sederhana: kalau secret sudah masuk riwayat git, langkah pertamanya adalah rotasi atau pencabutan akses, bukan sekadar hapus file; menulis ulang riwayat butuh koordinasi dan punya banyak efek samping[4].
Kedua, dump database mentah. Isinya bukan kode sumber, melainkan artefak backup: hash password user, email, setting plugin. Jadi di repo full pun *.sql saya blokir; yang masuk git hanya snapshot database yang sudah dienkripsi di backups/db/. Cache, log, dan file runtime lain juga dibuang karena regenerable, bukan data pemulihan.
Yang justru sengaja tidak dibuang: media uploads/, core WordPress, sampai plugin resmi. Di situlah gunanya repo self-hosted tanpa batas ukuran; repo full harus bisa memulihkan situs utuh, bukan cuma kodenya. Konsekuensinya repo ini memang berat: riwayat git tumbuh setiap kali media berubah. Tapi biaya penyimpanan murah dibanding risiko kehilangan aset saat server mati; media yang berubah tiap hari mungkin lebih cocok di object storage, bukan dipaksakan ke git.
Repo view: cuma sumber yang saya tulis
Repo publik di GitHub dapat porsi berbeda: tema dan plugin kustom, mu-plugins, plus manifest Composer. Plugin resmi seperti Elementor atau WooCommerce tidak ikut, bukan karena dilarang, tapi karena statusnya dependensi, bukan sumber. Dependensi cukup dideklarasikan lewat composer.json yang menunjuk ke WPackagist, indeks paket WordPress untuk Composer[5].
Elementor Pro kasusnya lain lagi: paketnya dikirim sebagai unduhan setelah pembelian, lewat email atau dasbor My Elementor[3], bukan paket wordpress.org. Lisensinya bikin file itu tidak pernah boleh di-commit ke mana pun.
Cara mengisi repo view-nya pakai allowlist rsync yang deny-by-default. Plugin pihak ketiga yang terinstal hari ini tidak mungkin bocor besok, karena dia memang tidak ada di daftar. Urutan penulisan juga penting karena rsync menerapkan aturan first-match: folder induk harus dicatat sebelum isinya. Dari semua pola yang saya coba, ini yang paling sulit salah. Bentuk template-nya begini:
+ /wp-content/
+ /wp-content/themes/
+ /wp-content/themes/<custom-theme>/
+ /wp-content/themes/<custom-theme>/**
+ /wp-content/mu-plugins/
+ /wp-content/mu-plugins/**
+ /composer.json
+ /composer.lock
Penerbitan ke GitHub selalu berupa satu commit snapshot yang menyebut hash produksi di pesannya, lalu push biasa. Tidak pernah force-push; operasi penulisan ulang riwayat itulah yang paling mahal koordinasinya dan paling banyak efek sampingnya[4].
Desain halaman tinggal di database
Satu hal yang sering terlewat saat memecah repo: kalau situs dibangun dengan page builder, desainnya tidak hidup di file. Elementor menyimpan data halaman sebagai JSON di tabel wp_postmeta, berupa custom field[2]. Ekspor Template menghasilkan file *.json yang bisa dipindah antar instalasi[2].
JSON ekspor itu artefak desain yang portabel, jadi sah masuk git; repo view boleh membawanya selama isinya aman untuk publik. Tapi dia bukan pengganti backup. Database tetap satu-satunya sumber kebenaran[1][2], dan aturan praktisnya tetap: simpan 3-5 backup terbaru di lokasi yang berbeda[1].
Ujungnya, dua repo itu menjawab dua pertanyaan yang beda. Repo full menjawab pertanyaan kalau server mati, apa yang saya butuhkan untuk bangun lagi. Repo view menjawab pertanyaan kalau orang lain melihat kode saya, apa yang pantas mereka lihat. Begitu dua pertanyaan ini dipisah, daftar ignore dan daftar include-nya tinggal mengikuti.
Sumber