Find this post on the Google or someone’s shared link? I’ve discovered an even more magical way to work with Git and Subversion
Having Git properly interface with Subversion is a mysterious black art. If you’re into the Harry Potter stuff, then this post is for you.
First, I must give credit where credit is due. Boone Gorges has a nice writeup detailing how he uses GitHub with WordPress.org Subversion. Unfortunately, it only tempted me. What really set me on the right track was a short piece by Evgeni Golov, which had everything but one crucial piece: checkout instead of merge.
Using checkout instead of merge is likely the most critical piece to this puzzle. What Erik and I found the first time when using merge is that Git treats both versions of the code as equal and tries to find the middle ground between them. Instead, we want to update all of the files in the Subversion repository with their most recent counterparts from GitHub. Checkout gives us exactly this power.
Because I was working on this Monday night with the Assignment Desk, I’ll go step by step with those links as an example. This tutorial assumes you’re doing all of your development with Git, and need to occasionally push to Subversion with releases.
First, clone your WordPress.org Subversion into your local Git repository:
git svn clone -s -r274218 https://svn.wp-plugins.org/assignment-desk
Notice two important flags:
-r. The ‘s’ flag tells Git the code you’re importing follows the normal Subversion folder structure, or /trunk/, /tags/, and /branches/. The ‘r’ flag tells Git to import after the specified revision number; when pulling from a large Subversion repository like WordPress.org, this can save you days of time. You can find the ID for your first commit in your revision log (Assignment Desk example).
Change into your newly-created directory and pull in your Subversion history (could take a bit of time):
git svn fetch
Once all commits have downloaded, add your working GitHub repository as a branch to your local Git repository:
git remote add -f github email@example.com:studio20nyu/Assignment-Desk.git
What’s next is the magic part. We’re going to checkout the code from the ‘github’ branch to the ‘master’ branch (our Subversion checkout), instead of merging the two:
git checkout github/master *
If you use ‘
git status‘ at this stage, you’ll notice all of the files you’ve changed since your last release have nice little M’s next to them. If you had merged, there would be a nasty mess of conflicts you’d have to resolve.
Add all of the files you want to save in the next commit:
git add *
And make your commit:
git commit -m "Updated from GitHub"
Aside: at this point, I tried to push back to WordPress.org and received an error of “Merge conflict during commit: File or directory ‘assignment_desk.php’ is out of date; try updating: resource out of date; try updating at /usr/local/git/libexec/git-core/git-svn line 572,” also known as nonsensical gibberish. Thankfully, the Google pointed me to this Stack Overflow thread.
Before you celebrate, you must practice one last piece of magical foo: rebasing. For reasons we don’t fully understand, rebase holds the key to resyncing your Git commit history with Subversion. Make it happen:
git svn rebase
Push all of your changes back to the original WordPress.org repository:
git svn dcommit
Congratulations! You’ve tamed the beast and progress to the next level.