Create a gist now

Instantly share code, notes, and snippets.

Please see https://salferrarello.com/wordpress-gitignore/ for the canonical version of this WordPress .gitignore file. Note: I do not receive notifications for comments here (because GitHub does not send notifications on Gists)
# -----------------------------------------------------------------
# .gitignore for WordPress @salcode
# ver 20160309
#
# From the root of your project run
# curl -O https://gist.githubusercontent.com/salcode/b515f520d3f8207ecd04/raw/.gitignore
# to download this file
#
# By default all files are ignored. You'll need to whitelist
# any mu-plugins, plugins, or themes you want to include in the repo.
#
# 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:
# 20160309 Added favicon files as whitelisted files
# 20150302 Added composer.json as a whitelisted file
# 20150227 Created as fork of https://gist.github.com/salcode/9940509,
# this version ignores all files by default
# -----------------------------------------------------------------
# ignore everything in the root except the "wp-content" directory.
/*
!wp-content/
# ignore everything in the "wp-content" directory, except:
# mu-plugins, plugins, and themes directories
wp-content/*
!wp-content/mu-plugins/
!wp-content/plugins/
!wp-content/themes/
# ignore all mu-plugins, plugins, and themes
# unless explicitly whitelisted at the end of this file
wp-content/mu-plugins/*
wp-content/plugins/*
wp-content/themes/*
# ignore all files starting with . or ~
.*
~*
# ignore node dependency directories (used by grunt)
node_modules/
# 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
# -------------------------
# BEGIN Whitelisted Files
# -------------------------
# track these files, if they exist
!.gitignore
!.editorconfig
!README.md
!CHANGELOG.md
!composer.json
# track favicon files, if they exist
!android-chrome-*.png
!apple-touch-icon*.png
!browserconfig.xml
!favicon*.png
!favicon*.ico
!manifest.json
!mstile-*.png
!safari-pinned-tab.svg
# track these mu-plugins, plugins, and themes
# add your own entries here
!wp-content/mu-plugins/example-mu-plugin/
!wp-content/plugins/example-plugin/
!wp-content/themes/example-theme/
@salcode
Owner
salcode commented Feb 27, 2015

It may seem strange that I'm ignoring all files by default. I've started using Git for deploying my WordPress work. In the process, I've found it helpful not to have plugins included in the repo.

In the prior version I worked from, .gitignore file for WordPress - Bare Minimum Git, it was necessary to modify the .gitignore to exclude plugins I didn't want included. I've found, I prefer to exclude the plugins by default.

@josephfusco

Great work. Thank you.

@DanielFris

Thanks!

@mfi-dev
mfi-dev commented Apr 30, 2015

So how do you manage required plugins?

@salcode
Owner
salcode commented May 8, 2015

@mfi-dev, I've been using composer to manage public plugins, see http://salferrarello.com/composer-wordpress-plugins/. I have not worked out a solution for commercial plugins but others apparently have using https://github.com/composer/satis.

@misterzik

Great work, thanks!

@sergibeltran

If your are using Grunt you should to track this file:

!gruntfile.js
!package.json

Thanks, I'll use it.

@salcode
Owner
salcode commented Oct 15, 2015

@sergibeltran I am a big fan of Grunt but I don't ever use it at the root level of my WordPress projects so it isn't included here. I always use it in a specific plugin or theme, most often a theme.

@camaech
camaech commented Mar 2, 2016

@salcode What would you say to do if we've already been tracking our entire WP site? How would you got about implementing your minimalist gitignore?

@salcode
Owner
salcode commented Mar 9, 2016

@camaech I generally I don't make that kind of drastic change to an existing repo. I use this .gitignore on all my new projects but I still have old projects that are using a different version that includes a lot of extra stuff (and I just deal with it). In a few rare cases, I've created a new repo with this .gitignore but then you lose the history of the old repo.

You could add this file to an existing project and then delete files from the repo but leave them on your local disk. See this Stackoverflow Remove file from the repository but keep it locally. However, be careful if you're using git to deploy your website because it will record the deletion of the files and delete them on your server when you deploy.

Short version Don't change existing repos. Use this on new repos. If you really want to use this on an old repo, use the files to create an entirely new repo (and sacrifice your history).

@camaech
camaech commented Mar 9, 2016

@salcode. I ended up allowing the deletion of the files on the server, and then added them back manually. I should be good to go from here, but I know what you're saying. Should only really use this on a new repo.

@AlchemyUnited

re: # ignore everything in the root except the "wp-content" directory.

Um. Then why not just make that directory the repo?

My understanding is, for the sake of consistency and completeness, etc. that you should in fact include WP Core. Why? Because that "snapshot" (of code) if you will is part of the history of the project. It becomes part of the status of the codebase at any given moment.

For example, if such and such (e.g., plugin, custom X, Y or Z, etc.) was added to the project under (say) WP 4.1.1 and that feature goes wonky in (again, just an example) 4.1.2 then you might need to know where WP Core was when that feature was added.

Maybe this is wrong? But when someone explained it to me (or did I read it?) it made much sense.

@salcode
Owner
salcode commented Apr 22, 2016

@AlchemyUnited

re: # ignore everything in the root except the "wp-content" directory.

Um. Then why not just make that directory the repo?

One certainly could set the root as wp-content, I don't for a couple of reasons:

  1. When using git to deploy changes to production, in my experience it is expected that the repo is from the root of the website.
  2. There are some files that get included in the root of my project (e.g. favicon and its many variations, composer.json)
  3. Standardization. All of my web projects, WordPress or otherwise, are based on the root of the project. This eliminates any thinking I need to do about where to clone the repo.

My understanding is, for the sake of consistency and completeness, etc. that you should in fact include WP Core. Why? Because that "snapshot" (of code) if you will is part of the history of the project. It becomes part of the status of the codebase at any given moment.

I understand the desire for a snapshot in time however I don't think the "cost" of including all of WordPress core is worth it for a couple of reasons.

  1. My website backups serve this purpose better than my Git repo
  2. There was a time I included all of WordPress core in my repos and it became painful
  3. I've had the opportunity to interact with developers much smarter than myself and they're not including WordPress core in their repos
  4. If I really wanted this type of setup, I'd use Composer to include WordPress core as a dependency. The WPStarter project has a nice setup for this.

For example, if such and such (e.g., plugin, custom X, Y or Z, etc.) was added to the project under (say) WP 4.1.1 and that feature goes wonky in (again, just an example) 4.1.2 then you might need to know where WP Core was when that feature was added.

All of my client sites update WordPress through the web interface, not by changing the files in the repo. This means I'm going to be out-of-sync anyway. I prefer to run the latest on both development and production, with backups available if something does go wonky.

Maybe this is wrong? But when someone explained it to me (or did I read it?) it made much sense.

I don't think there is one single answer on how to version control your website. Personally, I have found using this .gitignore file has made my life significantly better.

@x-yuri
x-yuri commented May 16, 2016 edited

My website backups serve this purpose better than my Git repo

I bet, the idea was to be able to run the site the way it was at some arbitrary commit. For example, you see the code, but can't figure out what it does. Sometimes it's better to debug the code, then try to do it in your head.

There was a time I included all of WordPress core in my repos and it became painful
I've had the opportunity to interact with developers much smarter than myself and they're not including WordPress core in their repos

Unfortunately, these two doesn't explain anything. They assume whoever reads this post trusts you on your choice. Honestly, I don't. Not since I have reasons to not trust you. But since I have no reasons to trust you yet. So these ones doesn't count for me as they are.

@salcode
Owner
salcode commented May 17, 2016

@x-yuri

the idea was to be able to run the site the way it was at some arbitrary commit

In this case, I would add !composer.lock to my .gitignore file and load WordPress core as a dependency with Composer. This would allow me to track the version of WordPress core (as well as any plugins I load with Composer).

Overall, it sounds like you want to check WordPress core into your Git repo. While I personally wouldn't do that for my reasons listed above, I have no problem if you choose to. Different people like different things. All the best.

@Bloafer
Bloafer commented May 25, 2016

@salcode I would also add

# ignore OS generated files
...
.DS_Store
...
@salcode
Owner
salcode commented Jun 2, 2016

@Bloafer thanks for the suggestion.

Since .DS_Store starts with a . it should already be ignored by

# ignore all files starting with . or ~
.*

The OS generated files we specifically ignore are those that do not start with a .

@michelluarasi
michelluarasi commented Nov 24, 2016 edited

@salcode Since you whitelist some folders (theme, plugins) at the end of the .gitignore file, the previous ignore-rules get revoked. So, how do you prevent i.e. OS generated files inside those whitelisted folders?

(I had this problem with .DS_Store files inside my main theme and for a quickfix I ignored that file again at the very end to remove them from git. But that's not very elegant.)

@salcode
Owner
salcode commented Dec 20, 2016

@michelluarasi I'm not able to recreate the behavior you're describing.

For example if I:

  • create a whitelisted plugin directory, e.g. wp-content/plugins/example-plugin/
  • add a file like .DS_Store inside the plugin directory, e.g. wp-content/plugins/example-plugin/.DS_Store

I still don't see .DS_Store come up when I run git status.

Can you describe the steps to reproduce the behavior you're seeing? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment