Git Local WordPress Deployment

How To Set Up Git Locally

When you commit changes with git, it embeds your name and email address into the commit message in order to easily track changes. If we do not configure this information ourselves, git may try to guess these values (probably incorrectly) by using your Linux username and hostname.

  1. Give git the values you wish to use for these parameters with these commands:
    • The configuration changes will be stored in a file in your home directory. You can see them with a normal text editor:
    • nano ~/.gitconfig

      name = Your Name Here
      email =
    • You can also view this information by querying git itself for the current configuration settings:
    • git config --list

      Output: Name Here

Managing and Deploying WordPress with Git

This setup gives the possibility of keeping themes and plugins under version control, while having a reference to the core WordPress package and allowing me to update it with each new release.

  1. Create a new project folder.
  2. Add initial ReadMe file and make your first commit
  3. Output:
    [master (root-commit) 38b1706] Initial commit.
    1 file changed, 0 insertions(+), 0 deletions(-)
    create mode 100644
  4. Add WordPress as a submodule to the project, checkout the last version and commit.
    1. git submodule add git:// wordpress
    2. Output:
      Cloning into ‘wordpress’…
      remote: Counting objects: 226244, done.
      remote: Compressing objects: 100% (78/78), done.
      remote: Total 226244 (delta 44), reused 0 (delta 0), pack-reused 226166
      Receiving objects: 100% (226244/226244), 142.27 MiB | 3.85 MiB/s, done.
      Resolving deltas: 100% (179359/179359), done.
      Checking connectivity… done.
    3. git commit -m "Add WordPress submodule."
    4. Output:
      [master 8bcf108] Add WordPress submodule.
      2 files changed, 4 insertions(+)
      create mode 100644 .gitmodules
      create mode 160000 wordpress
    5. cd wordpress
    6. git checkout 4.3.1
    7. Output:
      Note: checking out ‘4.3.1’.

      You are in ‘detached HEAD’ state. You can look around, make experimental
      changes and commit them, and you can discard any commits you make in this
      state without impacting any branches by performing another checkout.

      If you want to create a new branch to retain commits you create, you may
      do so (now or later) by using -b with the checkout command again. Example:

      git checkout -b new_branch_name

      HEAD is now at 759f3d8… Tag 4.3.1 Built from

    8. cd ..
    9. git commit -am "Checkout latest WordPress version"
    10. Output:
      [master dba1127] Checkout latest WordPress version
      1 file changed, 1 insertion(+), 1 deletion(-)
  5. We will not be touching the WordPress submodule, we will only update it when a new version is released. Therefore, we will have to put our configuration and custom development (themes & plugins) outside the WordPress folder.
  6. Output:
    [master 10d6e93] Moving config and content outside the submodule
    88 files changed, 18037 insertions(+), 1 deletion(-)
    create mode 100644 index.php
    create mode 100644 wp-config.php
    create mode 100644 wp-content/index.php
    create mode 100644 wp-content/plugins/index.php
    create mode 100644 wp-content/themes/index.php
    create mode 100644 wp-content/themes/twentyfifteen/404.php
    create mode 100644 wp-content/themes/twentyfifteen/archive.php
    create mode 100644 wp-content/themes/twentyfifteen/author-bio.php
    create mode 100644 wp-content/themes/twentyfifteen/comments.php
    create mode 100644 wp-content/themes/twentyfifteen/content-link.php
    create mode 100644 wp-content/themes/twentyfifteen/content-none.php
    create mode 100644 wp-content/themes/twentyfifteen/content-page.php
    create mode 100644 wp-content/themes/twentyfifteen/content-search.php
    create mode 100644 wp-content/themes/twentyfifteen/content.php
    create mode 100644 wp-content/themes/twentyfifteen/css/editor-style.css
    create mode 100644 wp-content/themes/twentyfifteen/css/ie.css
    create mode 100644 wp-content/themes/twentyfifteen/css/ie7.css
    create mode 100644 wp-content/themes/twentyfifteen/footer.php
    create mode 100644 wp-content/themes/twentyfifteen/functions.php
    create mode 100644 wp-content/themes/twentyfifteen/genericons/COPYING.txt
    create mode 100644 wp-content/themes/twentyfifteen/genericons/Genericons.eot
    create mode 100644 wp-content/themes/twentyfifteen/genericons/Genericons.svg
    create mode 100644 wp-content/themes/twentyfifteen/genericons/Genericons.ttf
    create mode 100644 wp-content/themes/twentyfifteen/genericons/Genericons.woff
    create mode 100644 wp-content/themes/twentyfifteen/genericons/LICENSE.txt
    create mode 100644 wp-content/themes/twentyfifteen/genericons/
    create mode 100644 wp-content/themes/twentyfifteen/genericons/genericons.css
    create mode 100644 wp-content/themes/twentyfifteen/header.php
    create mode 100644 wp-content/themes/twentyfifteen/image.php
    create mode 100644 wp-content/themes/twentyfifteen/inc/back-compat.php
    create mode 100644 wp-content/themes/twentyfifteen/inc/custom-header.php
    create mode 100644 wp-content/themes/twentyfifteen/inc/customizer.php
    create mode 100644 wp-content/themes/twentyfifteen/inc/template-tags.php
    create mode 100644 wp-content/themes/twentyfifteen/index.php
    create mode 100644 wp-content/themes/twentyfifteen/js/color-scheme-control.js
    create mode 100644 wp-content/themes/twentyfifteen/js/customize-preview.js
    create mode 100644 wp-content/themes/twentyfifteen/js/functions.js
    create mode 100644 wp-content/themes/twentyfifteen/js/html5.js
    create mode 100644 wp-content/themes/twentyfifteen/js/keyboard-image-navigation.js
    create mode 100644 wp-content/themes/twentyfifteen/js/skip-link-focus-fix.js
    create mode 100644 wp-content/themes/twentyfifteen/languages/twentyfifteen.pot
    create mode 100644 wp-content/themes/twentyfifteen/page.php
    create mode 100644 wp-content/themes/twentyfifteen/readme.txt
    create mode 100644 wp-content/themes/twentyfifteen/rtl.css
    create mode 100644 wp-content/themes/twentyfifteen/screenshot.png
    create mode 100644 wp-content/themes/twentyfifteen/search.php
    create mode 100644 wp-content/themes/twentyfifteen/sidebar.php
    create mode 100644 wp-content/themes/twentyfifteen/single.php
    create mode 100644 wp-content/themes/twentyfifteen/style.css
    create mode 100644 wp-content/themes/twentytwelve/404.php
    create mode 100644 wp-content/themes/twentytwelve/archive.php
    create mode 100644 wp-content/themes/twentytwelve/author.php
    create mode 100644 wp-content/themes/twentytwelve/category.php
    create mode 100644 wp-content/themes/twentytwelve/comments.php
    create mode 100644 wp-content/themes/twentytwelve/content-aside.php
    create mode 100644 wp-content/themes/twentytwelve/content-image.php
    create mode 100644 wp-content/themes/twentytwelve/content-link.php
    create mode 100644 wp-content/themes/twentytwelve/content-none.php
    create mode 100644 wp-content/themes/twentytwelve/content-page.php
    create mode 100644 wp-content/themes/twentytwelve/content-quote.php
    create mode 100644 wp-content/themes/twentytwelve/content-status.php
    create mode 100644 wp-content/themes/twentytwelve/content.php
    create mode 100644 wp-content/themes/twentytwelve/css/ie.css
    create mode 100644 wp-content/themes/twentytwelve/editor-style-rtl.css
    create mode 100644 wp-content/themes/twentytwelve/editor-style.css
    create mode 100644 wp-content/themes/twentytwelve/footer.php
    create mode 100644 wp-content/themes/twentytwelve/functions.php
    create mode 100644 wp-content/themes/twentytwelve/header.php
    create mode 100644 wp-content/themes/twentytwelve/image.php
    create mode 100644 wp-content/themes/twentytwelve/inc/custom-header.php
    create mode 100644 wp-content/themes/twentytwelve/index.php
    create mode 100644 wp-content/themes/twentytwelve/js/html5.js
    create mode 100644 wp-content/themes/twentytwelve/js/navigation.js
    create mode 100644 wp-content/themes/twentytwelve/js/theme-customizer.js
    create mode 100644 wp-content/themes/twentytwelve/languages/twentytwelve.pot
    create mode 100644 wp-content/themes/twentytwelve/page-templates/front-page.php
    create mode 100644 wp-content/themes/twentytwelve/page-templates/full-width.php
    create mode 100644 wp-content/themes/twentytwelve/page.php
    create mode 100644 wp-content/themes/twentytwelve/readme.txt
    create mode 100644 wp-content/themes/twentytwelve/rtl.css
    create mode 100644 wp-content/themes/twentytwelve/screenshot.png
    create mode 100644 wp-content/themes/twentytwelve/search.php
    create mode 100644 wp-content/themes/twentytwelve/sidebar-front.php
    create mode 100644 wp-content/themes/twentytwelve/sidebar.php
    create mode 100644 wp-content/themes/twentytwelve/single.php
    create mode 100644 wp-content/themes/twentytwelve/style.css
    create mode 100644 wp-content/themes/twentytwelve/tag.php
  7. We will have to make some changes to these copied files so that WordPress still finds all the necessary files.
  8. In index.php change:


    and in wp-config.php add the following lines:

  9. If we want to use different database credentials for the local development server and the online production or staging server, we can modify the database settings in thewp_config file like this:
  10. Finally we commit these changes.
  11. Output:
    [master 9243d06] define correct paths in config files
    1 file changed, 32 insertions(+), 8 deletions(-)
  12. Edit your /etc/hosts file with the following line:
  13. local_dev local_dev localhost

Now we can work on our custom themes and plugins outside the core WordPress folder and keep a record of it in Git. The website should display as normal on our local development server.

Setup MariaDB or MySQL container and user

We’re assuming here you have MariaDB or MySQL already setup. If you do not, see this document on the installation and setup of MariaDB / MySQL.

  1. Login to MariaDB / MySQL mysql -p
  2. Create a new database container create database local_dev;
  3. Create a new user for the database container grant all privileges on local_dev.* TO 'local_admin'@'localhost' identified by 'strong_password_here';
  4. Exit the database server exit;

We now have a new database container and user with the following details:

Database host:
Database name:
Database user:
Database password:

Local Apache httpd VirtualHost configuration

Edit and add this configuration to: /etc/httpd/conf.d/vhosts.conf. If the file does not exist, create it.

Then give this command: systemctl start httpd.service or systemctl restart httpd.service

Install WordPress

Follow the onscreen prompts and fill out the fields as needed.


Login to your newly installed WordPress installation


Post Setup / Update Options

Updating WordPress Core

When a new WordPress version is released, we can update the core WordPress files by using these commands:

Deploying changes to a staging server

let me push local changes to my staging server with a simple command.

We will be creating a Git repository on the same server that hosts our staging version of the website. Each time we push a change to the git repository, the repository will automatically update the code on our staging server.

This means you’ll need SSH access into your server to create a git repository from the command line. Check with your hosting provider if your hosting plan allows this.

  1. First SSH into your server and create a bare Git repository for your website.
  2. mkdir git && cd git
    mkdir mysite.git && cd mysite.git
    git --bare init

  3. Now that we have a repository to push to on the server, we can add this as a remote to our local repository. Execute the following command on your own computer, in your local website folder. Don’t forget to change the hostname and path to the correct values.
  4. git remote add origin name@

  5. Next we can run the following command to push our code from our local machine to the server:
  6. git push origin master

    Now if we have a look at the git log of the server’s repository, we should see that our code has been pushed to the repository. Because this is a bare repository without a working tree, your code won’t actually be visible outside the log.

    If we get a prompt for our password each time we push to the remote server, we can remove this hassle by setting up SSH keys. You can follow these instructions to set up SSH keys.

  7. Finally we will automate the updating of our live server after each push to the git repository. We need to set up a post update hook. Go into your bare repository, then into the hooks directory and create a new script.
  8. Now if you go back to your local code, make a change, commit the change and push it to the origin you will see your code magically update.

    There is only one problem : since we made a bare repository, the automatic checkout will not update submodules. We will have to manually upload the core WordPress folder. Also, each time we update WordPress to a new version we will have to manually upload the new version of the core files to our server. If you have any tips to improve this situation, please let me know.


    Last Modified: 29 Dec, 2015 at 20:50:05