How to manage remote wordpress website using Git

H

Hello, In this post we are going to learn how we can manage a remote wordpress website/blog. To manage any remote website, we have two tasks at hand

  1. Manage Files
  2. Manage Databases

It would be a lengthy post to explain about both files and database in a single post, so we will discuss about managing files in this post and in other post we will discuss about managing databases

As the post name suggests, we are going to use Git to manage files in our remote website. Previously we used to use FTP to transfer files between web server and our local server. There are times when we missed to update a file on web server from local repository because we were not able to track the changes we have made to the files in our project. With Git, we can easily track changes in our local repository and web repository and ensure that we do not have any version discrepancies between repositories. This post assumes that you have SSH access to your web server, in case if you do not have access you may look for other alternatives such as Git-FTP for managing website but this post needs you to have SSH access.

In our first step, let us create a repository in our local system and this repository is root of our wordpress installation. Since we do not want every file to be managed by git. ( For example, the remote WordPress configuration is different from our local wordpress configuration, hence we do not want to manage “wp-config.php” file ). Let us create a “.gitignore” file and maintain list of files that should not be tracked by Git. I am using following gitignore file but you are free to create your own gitignore file based on your requirement.

# -----------------------------------------------------------------
# .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/uploads/

# ignore these plugins
wp-content/plugins/hello.php

# ignore specific themes
wp-content/themes/twenty*/

# ignore node/grunt dependency directories
node_modules/

 

With “.gitignore” in place, let us now create a local git repository.

$ cd <local_repo_dir>
$ git init
$ git add -A
$ git commit -m "Initial Version"

( <local_repo_dir> will be your wordpress installation directory )

We now have a local repository, let us create a remote repository as well, which will accept the changes from our local repository. Login to your ssh account.

ssh -p 2222 username@ipaddres

Once you logged in, verify if your server has git installed on it, this can be done by executing the command “git”. If command gives you an error, then your server do not have git installed. If you have authorizations, you can install git else you can raise a support ticket with webmaster.

Create a folder for remote repository, preferably above public web folder so that remote repository cannot be accessed from web. Since the remote repository on our server should accept push’s and pull’s from local repositories we need to make it a bare repository.

$ mkdir website.git && cd website.git
$ git init --bare

Now our remote repository is ready to receive the files from our local repository. At this point of time when you push the changes from your local repository to your server, changes would be in remote repository but they will not be reflected on your website because we did not move the files from our remote repository to the document root. If you want to move the files from this repository to document root as soon as you push from your local repository you can utilize the post-receive hook. Following post-receive script is a simple example for moving the changes to actual web repository

$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=<document_root> git checkout -f
$ chmod +x hooks/post-receive

 

Note:

  • A bare git repository keeps files in compressed format so that it can transfer files between local repositories. By providing details of document root to GIT_WORK_TREE and checkout, we are telling git to keep files in working directory.
  • We are using force checkout which will ignore remote repository HEAD detached state.
  • Allowing the post-receive hook to have execution privilege is an important step for git to be able to move files to document root.

Let us now go back to our local repository and configure remote repository details so that we can push changes from local to remote repository. Following are the commands that you should execute

$ git remote add production ssh://yourdomain.com:<port>/<website.git>
$ git push production master

As soon as you execute these commands you must see that document root contains the files from our local repository. At this point of time we have only deployed our website from our local repository to remote repository and moving files from remote repository to document root. We are not tracking any changes to our document root folder and any changes to document root will not be present in our local repository. If you want to track the changes that you have made to the document root, it has to be a git repository as well.

Before we make our document root a git repository, let us add gitignore file from our local repository. Execute following command from your local repo.

scp -P2222 .gitignore username@domain.com:<document_root>

Now let us make our document root a git repository.

git clone ~/<yourwebsite.git> temp
mv temp/.git <document_root>/.git
rm -rf temp

Now we are ready to track changes to our document root using git. It would be a good idea to compare the differences between document root and remote repository before we push any changes from local repository. Alternatively, we can provide temporary path instead of document root and move files between temporary folder and document root but it would be little tedious task.

Making document root a git repository will allow us to push and pull from our remote repo.

git push production master

 

We can also use our remote repo to push or pull changes from our local repository.

git pull production master

 

One more thing that I would like to do before I wrap up this post is to edit your “.htaccess” file. Please add following line to your .htaccess file at top level root directory.

RedirectMatch 404 /\.git

 

In our next post, we will discuss how we can manage our database. Please feel free to provide feedback/comments/suggestions if you have any better way to manage.

About the author

pavankumar.p1990

Add comment

By pavankumar.p1990