by Kaspars Dambis -- konstruktors.com / @konstruktors
We'll assume that your plugin is already hosted on the official WordPress plugin Subversion repository, and we'll use the Easy Digital Downloads plugin as an example.
-
First, we need to get the revision number of the first commit to the WordPress Subversion repository, because otherwise Git will try to go through all 100000+ commits in order to find it.
$ svn log http://plugins.svn.wordpress.org/easy-digital-downloads/
It is the last commit revision you seen on the screen:
------------------------------------------------------------------------ r529177 | plugin-master | 2012-04-09 19:36:16 +0200 (Mon, 09 Apr 2012) | 1 line adding easy-digital-downloads by mordauk ------------------------------------------------------------------------
In this case it is r529177. You can also use the official WordPress Trac browser to determine the first revision number.
-
Now, create a local Git repository and import the first commit from the SVN repository:
$ git svn clone --no-minimize-url -s -r529177 http://plugins.svn.wordpress.org/easy-digital-downloads/
which returns the following:
Initialized empty Git repository in /Users/kaspars/svn2git/easy-digital-downloads/.git/ r529177 = e18c66d09d77e4d8a923f2f300f73606791071e1 (refs/remotes/trunk) Checked out HEAD: http://plugins.svn.wordpress.org/easy-digital-downloads/trunk r529177
Notice the
--no-minimize-url
flag which is required to stopgit svn clone
from moving into the base folder of the remote SVN repository and going through all plugins (see git-svn docs). We also use the-s
flag which is a shorthand way of setting trunk, tags, branches as the relative paths, which is the Subversion default (from git-svn docs). -
Finally, move inside the newly created Git repository:
$ cd easy-digital-downloads
and fetch all the other commits from the SVN repo:
$ git svn fetch
This step will take hours (!), so you can use the
GIT_TRACE=2
flag before the the command to see a verbose output:$ GIT_TRACE=2 git svn fetch
Once this process is finished you have a complete Git commit tree of the project. The final step is to move the SVN HEAD (files from
/trunk
) into our Git master (I assume), which is done using:$ git svn rebase
Now you should see all the latest plugin files in your local repository.
Let's look at all the branches that were created:
$ git branch -a
returns a list of all the available branches:
* master
remotes/tags/1.0.1.1
remotes/tags/1.0.1.2
remotes/tags/1.0.1.3
remotes/tags/1.0.1.4
...
remotes/tags/1.1.8
remotes/tags/1.2
remotes/tags/1.2.1
remotes/tags/1.2.1.1
remotes/trunk
If we look inside .git/config
in our newly created Git repository:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = false
[svn-remote "svn"]
url = http://plugins.svn.wordpress.org/easy-digital-downloads
fetch = trunk:refs/remotes/trunk
branches = branches/*:refs/remotes/*
tags = tags/*:refs/remotes/tags/*
we can see that Git has automatically selected trunk
as the destination for git svn dcommit
which pushes all your changes back to the WordPress repository.
Let's create a new GitHub repository which we'll use as our main repository for our plugin from now on:
Once you have created the repository, simply add it as a remote origin of our local Git repository:
$ git remote add origin [email protected]:kasparsd/wordpress-svn2git-sample.git
and then push our local repository to GitHub:
$ git push -u origin master
Now your GitHub repository should contain all your plugin files as well as all the revision history carried over from the Subversion repository.
Now let's assume that we want to create a new release of the plugin in order to invite the plugin users to report bugs and get involved on GitHub. For that we need to edit the copy of readme.txt
and bump the version number of the plugin.
Once we have made the changes, we can check the status of our local Git repository:
$ git status
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: easy-digital-downloads.php
# modified: readme.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
Let's commit the changes to our local repository:
$ git commit -am "Adding message about moving to GitHub, version bump"
To publish our local commits to GitHub, we use
$ git push
[master addb6cf] Adding message about moving to GitHub, version bump
2 files changed, 12 insertions(+), 1112 deletions(-)
rewrite readme.txt (99%)
Once you have switched to using Git as your version control system, you should always use git svn
to publish changes to the SVN repository. Otherwise, you must use
$ git svn rebase
every time before pushing changes to SVN in order to merge changes from the SVN repository into your local Git repo.
If you are not using trunk
as a release branch for your plugin, you may safely push all your Git changes to the WordPress repository without worrying about users getting update notices:
$ git svn dcommit
Now, because I don't have write access this particular repository, here is a response that I get when pushing one of my own plugins:
Committing to http://plugins.svn.wordpress.org/widget-context/trunk ...
M widget-context.php
Committed r601084
M widget-context.php
r601084 = a1c2a2f8f4f98ec5537aef48545e350ff6270f2b (refs/remotes/trunk)
No changes between b6098f5bb1751cc05309093cad1d5d982a964158 and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk