Installing and updating WordPress plugins from a Git repository

A lot of useful WordPress plugins never go through the wordpress.org directory: internal tools, client-specific plugins, forks, and free plugins published on a self-hosted Git server. Installing them means downloading a zip, uploading it, and doing it again for every update. Git Plugin removes that loop. You paste a repository URL, WordPress installs the plugin, and from then on it shows up in Dashboard → Updates like any other plugin.

This guide walks through installing the Web9 plugins from their repositories, since that is the case most readers here will have.

What Git Plugin supports

Git Plugin accepts a repository on GitHub, GitLab (including self-hosted and nested groups), Bitbucket, or any Gitea or Forgejo instance. Four URL shapes are recognized:

  • https://host/owner/repo (with or without .git)
  • ssh://git@host:port/owner/repo.git
  • git@host:owner/repo.git
  • owner/repo, which is treated as GitHub

For private repositories you can supply a token. It is sent as a bearer token for GitHub and Bitbucket, as PRIVATE-TOKEN for GitLab, and as a token authorization header for Gitea and Forgejo. The token is used for the download and is not stored with the plugin’s source.

Git Plugin needs WordPress 5.8 or later and PHP 7.4 or later. It stays out of the way when DISALLOW_FILE_MODS is set, since WordPress will not install anything in that case anyway.

Step 1: install Git Plugin itself

Git Plugin is the one plugin you have to install the old way, once. Download the zip from its repository at https://github.com/camachopedro3/git-plugin, then go to Plugins → Add New → Upload Plugin and upload it. Activate it.

After activation, the Plugins → Add New screen gets a “Git Plugin” button next to “Upload Plugin”. It opens a small form with three fields: the repository, an optional branch or tag, and an optional token.

Step 2: install a plugin from its repository

Paste the repository URL. For the Web9 plugins, these are:

https://git.web9.live/pcgraphics/kira_page_builder
https://git.web9.live/pcgraphics/formulator
https://git.web9.live/pcgraphics/alemedia
https://git.web9.live/pcgraphics/backinator
https://git.web9.live/pcgraphics/radmin

Leave the branch field empty to install from the repository’s default branch. Click Install Now.

Behind the scenes, Git Plugin asks the host for an archive of the repository at that ref. On GitHub that is the zipball API endpoint; on Bitbucket the /get/<ref>.zip URL; on GitLab the repository/archive.zip API; on Gitea and Forgejo the /archive/<ref>.zip API, after looking up the default branch when you did not name one. The archive is downloaded to a temporary file and handed to WordPress’s own plugin installer, the same code path that runs when you upload a zip.

Repository archives unpack into a folder named after the repo and the commit, which is not what WordPress wants. Git Plugin renames that folder to the plugin’s slug before installation, so the plugin lands in wp-content/plugins/<slug>/ and later updates replace the same folder instead of creating a second copy.

If the plugin is already installed, WordPress shows its usual “Replace current with uploaded” step, and Git Plugin handles the second pass.

Step 3: let updates arrive on their own

Once installed, the repository and ref are remembered per plugin. On each update check, Git Plugin fetches the first 8 KB of the plugin’s main file on the tracked branch and reads the Version: header, using the same pattern WordPress uses for local plugin headers. When the remote version is higher than the installed one, an update appears under Dashboard → Updates with the archive URL as the package. Updating it is a normal WordPress plugin update.

Three rules worth knowing:

  • A pinned tag never updates. If you installed from v1.2.0, the tag does not move, so there is nothing to update to. Install from a branch if you want updates, from a tag if you want to freeze.
  • Plugins with their own Update URI are left alone. The Web9 plugins carry an Update URI header that points at their repository on git.web9.live and bundle their own updater, which checks the repository’s latest release, or its highest version tag, and offers that. Git Plugin steps aside so the two do not compete.
  • Git checkouts are left alone. A plugin folder that contains .git is a development copy. Neither updater touches it.

Git Plugin also adds a “Check for Updates” button on the Plugins screen. It drops the cached release data and re-runs WordPress’s update check immediately, instead of waiting for the next scheduled check.

One more guard: a plugin installed from Git is never matched against a same-named plugin on wordpress.org, so an unrelated directory plugin with the same slug cannot overwrite yours.

Step 4: download any plugin as a zip

Every row on the Plugins screen gets a “Download” link. It zips the installed plugin with its folder as the top level, which is the shape Upload Plugin expects, so you can move a plugin to another site or keep a copy of a specific version. This works for every installed plugin, not only ones installed from Git.

A workflow for your own plugins

If you write plugins for clients, this closes the loop:

  1. Keep the plugin in a repository with a Version: header in the main file.
  2. Install it on each client site from the repository URL, tracking main.
  3. To ship a change, bump the version and push. Each site offers the update on its next check, or immediately with the Check for Updates button.

For sites that must not change without you, install from a tag instead, and move them deliberately.

Share
Keep reading

More from the resources

Ready to build your site?

Pick a kit and host it for $12 a month, or send the form and we set it up for a custom quote. Either way the site is yours.

Get a quote