CreateIT
CreateIT
BLOG

GIT repository WordPress development strategy

Computer screen with code and people behind the screen

GIT repository WordPress development strategy

SHARE

Challenge:
prepare GIT repo for development purposes
Solution:
keep themes and plugins in repo, without core files. Use WP CLI for automation

In WordPress development, there are different strategies. Some WP programmers keep files locally and upload them using FTP. Let’s talk about a more convenient solution for creating a new WordPress site: keep files in the GIT repository, update site using git pull and apply WP CLI commands for maintenance.

WordPress GIT structure

We would like to keep only the necessary files and be able to update servers really fast (using the git pull command). Here is a simple solution for WordPress development using GIT. We store only themes and plugins in GIT. WordPress core files are not added.

wp-content/

├─ plugins/

├─ themes/

│  ├─ parent_theme/

│  ├─ child_theme/

.gitignore

Staging site setup

Having theme and plugin files pushed to GIT, we can focus on the staging server setup. We will use the automatic approach with git init and git pull. For WordPress core, we will use WP CLI commands. We already have the domain set up, the MYSQL database created, SSH access and we have installed the GIT library. We’re going to follow these steps to set up the WP site:

  1. Use WP CLI to create empty WP site
  2. Use Git init to fetch files from GIT

WP CLI

The WP-CLI command-line interface for WordPress enables the management of a WP installation from the SSH connection: to update plugins, change urls in the database, add users and much more. Nowadays WP-CLI is available on most shared hostings and can be used without any installation. There is also an option to install it from a PHAR file, more info: https://wp-cli.org/#installing

Here is a bash script that will download the newest core files, configure wp-config.php, install a new site, configure permalinks add create .htaccess.

#!/bin/bash
# init-wordpress.sh
WPHTACCESS_TEMPLATE=$(cat <<-END
# BEGIN WordPress
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
END
)
DB_NAME="db001";
DB_USER="user001";
DB_PASS="abc";
DOMAIN="example.com"
WP_PASS="mypass1";
WP_LOGIN="admin123"
WP_MAIL="[email protected]"
printf "\Ininitializing WP Core files..\n"
wp core download
wp config create --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS
wp core install --url=$DOMAIN --title=Website --admin_user=$WP_LOGIN --admin_password=$WP_PASS --admin_email=$WP_MAIL
wp option update permalink_structure '/%postname%/'
# create htaccess
touch .htaccess
echo -e "$WPHTACCESS_TEMPLATE" >> .htaccess
echo -n "All done!";

Opened cmd window

GIT repository for WordPress initialization

Now, we’re going to init git repo. Using GIT commands, we will fetch the newest changes from the repository: themes and plugins. Our staging server directory is not empty (we have core files already), so instead of using git clone, we need to use git init. Here is an example solution:

# init GIT using SSH
git init
git remote add origin https://linktogitdomain.com/project1/wp001.git
git fetch
git checkout -t origin/master
git reset --hard HEAD
git pull

Updating website

Our website uses /wp-content/themes/child_theme/ as an active theme. To update the code or fix any bug, we should:

  1. Edit the code of /wp-content/themes/child_theme/ locally
  2. Commit + push changes to GIT
  3. Execute: git pull (on the staging server)

This strategy has a lot of benefits: we have a history of changes (GIT history), and staging server updates are very fast. Also, we are sure that code on staging and on GIT are the same ( the FTP Client sometimes fails to send all files to the server ).

Updating plugins with GIT

WordPress plugins need to be updated frequently. New versions often include security updates or new features, so it’s important to not forget about site maintenance. Here is the preferred approach when using GIT WP structure:

  1. update plugins locally, test if local site is working fine
  2. delete old plugins: commit and push
  3. add plugins in the newest version: commit and push

Perhaps you’re thinking – why delete old plugins, maybe it’s better to just overwrite the old files? The reason for deleting all old files is that a new plugin version could remove some files, and by overwriting them, we will keep unnecessary files. In addition, if a plugin is auto-loading all files from the directory automatically, we can have a situation when some PHP classes from the old version are initialized automatically on plugin init and that can result in incorrect plugin behavior or PHP errors.

Updating WordPress core using GIT

We can ask WP-CLI to update WordPress to the newest version. This can be achieved using the command:

# WP CLI command for fetching newest core files
wp core update

gitignore with WordPress

When creating a GIT repository, one of the first files created is .gitignore. It should be placed in the main directory. For WordPress development and PHPStorm as IDE, we recommend to just keep themes and plugins. Other things, like core files and uploads, should be kept on the server directly.

# -----------------------------------------------------------------
# .gitignore for WordPress
# Bare Minimum Git
# http://ironco.de/bare-minimum-git/
# ver 20150227
#
# This file is tailored for a WordPress project
# using the default directory structure
#
# This file specifies intentionally untracked files to ignore
# http://git-scm.com/docs/gitignore
#
# NOTES:
# The purpose of gitignore files is to ensure that certain files not
# tracked by Git remain untracked.
#
# To ignore uncommitted changes in a file that is already tracked,
# use `git update-index --assume-unchanged`.
#
# To stop tracking a file that is currently tracked,
# use `git rm --cached`
#
# Change Log:
# 20150227 Ignore hello.php plugin. props @damienfa
# 20150227 Change theme ignore to wildcard twenty*. props @Z33
# 20140606 Add .editorconfig as a tracked file
# 20140404 Ignore database, compiled, and packaged files
# 20140404 Header Information Updated
# 20140402 Initially Published
#
# -----------------------------------------------------------------
# ignore everything in the root except the "wp-content" directory.
/*
!wp-content/
# ignore all files starting with .
.*
# track this file .gitignore (i.e. do NOT ignore it)
!.gitignore
# track .editorconfig file (i.e. do NOT ignore it)
!.editorconfig
# track readme.md in the root (i.e. do NOT ignore it)
!readme.md
# ignore all files that start with ~
~*
# ignore OS generated files
ehthumbs.db
Thumbs.db
# ignore Editor files
*.sublime-project
*.sublime-workspace
*.komodoproject
# ignore log files and databases
*.log
*.sql
*.sqlite
# ignore compiled files
*.com
*.class
*.dll
*.exe
*.o
*.so
# ignore packaged files
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# ignore everything in the "wp-content" directory, except:
# "mu-plugins" directory
# "plugins" directory
# "themes" directory
wp-content/*
!wp-content/mu-plugins/
!wp-content/plugins/
!wp-content/themes/
!wp-content/languages/
wp-content/themes/index.php
# ignore these plugins
wp-content/plugins/hello.php
wp-content/plugins/index.php
# ignore specific themes
wp-content/themes/twenty*/
# ignore node/grunt dependency directories
node_modules/
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties

How to backup the entire WordPress site

Here is the final tip, for creating a manual backup of the entire website. We will use the TAR library (similar to the zip compressing tool). It’s really fast and even sites measured in gigabytes will be zipped in seconds. The first step is to create a database backup, move it to wp-content directory and then zip wp-content directory to one file. The final file will be gzipped, which will ensure the smallest possible size.

Here are SSH commands for preparing a manual backup of a WordPress site:

# backup wordpress site using SSH
wp db export
mv db001-2022-03-24-huw344a.sql wp-content
cd wp-content
tar -zcvf ../wp-backup-2022-03-24.tar.gz .
# clean up
rm db001-2022-03-24-huw344a.sql

That’s it. Now, in the main directory, the wp-backup-2022-03-24.tar.gz file will contain all wp-content files and the .sql database dump.

To restore the backup, place the tar.gz file in the empty wp-content directory and execute:

# restore tar.gz backup
cd wp-content
tar -zxvf wp-backup-2022-03-24.tar.gz
# clean up
rm wp-backup-2022-03-24.tar.gz

That’s it for today’s tutorial. We hope you will understand the topic better and improve your WordPress – GIT workflow. Make sure to follow us for other tips and guidelines, and don’t forget to subscribe to our newsletter.

Need help?

  • Looking for support from experienced programmers?

  • Need to fix a bug in the code?

  • Want to customize your webste/application?

ADD COMMENT

Your email address will not be published.

createIT Contact