Tracking Wordpress in Git
I finally decided to sign up for github. What prompted me was the desire to upgrade this blog to WordPress 3.0, from its current Wordpress MU 1.5.1. I find that it is much easier to pull in an upstream branch and make my own changes on top if I use git as opposed to subversion. And since importing the wordpress svn repository into git was an overnight process, I decided to share the resulting git repo on github, so others can speed up their own wordpress git import should they ever want to do that. And that is how my first ever github repo became a repo that is just tracking the progress of wordpress. Good enough for a start.
I did not use the default git-svn configuration because it was lacking a few feature I like.
First, my local repo is not using the default git-svn branch to tag mapping. Instead, I configure git-svn to prefix all remote branches with "svn" so they are easy to follow. The "trunk" I also push into a branch named trunk, to make it easy to follow on github. I also configured the github remote repo to simply push all remote svn branches to similarly named proper branches. Tags in the subversion repo also become tags in the local repo. So, the flow is: wordpress subversion -> refs/remotes/svn @ local -> refs/heads @ github. And the commands I have to run to update github are just "git svn fetch" followed by "git push github" and eventually "git push github --tags".
The other cool thing is that with this configuration I can do the syncing with a bare git repo.
And here are the relevant parts from the config of my local git repo:
Note that I also do not prefix the fetch line of github with "+" because I do not want the two remote repos - subversion and github - to accidentally overwrite the local tracking branches.
I did not use the default git-svn configuration because it was lacking a few feature I like.
First, my local repo is not using the default git-svn branch to tag mapping. Instead, I configure git-svn to prefix all remote branches with "svn" so they are easy to follow. The "trunk" I also push into a branch named trunk, to make it easy to follow on github. I also configured the github remote repo to simply push all remote svn branches to similarly named proper branches. Tags in the subversion repo also become tags in the local repo. So, the flow is: wordpress subversion -> refs/remotes/svn @ local -> refs/heads @ github. And the commands I have to run to update github are just "git svn fetch" followed by "git push github" and eventually "git push github --tags".
The other cool thing is that with this configuration I can do the syncing with a bare git repo.
And here are the relevant parts from the config of my local git repo:
[svn-remote "svn"]
url = http://core.svn.wordpress.org
fetch = trunk:refs/remotes/svn/trunk
branches = branches/*:refs/remotes/svn/*
tags = tags/*:refs/tags/*
[remote "github"]
url = git://github.com/chutzimir/wordpress-svn
pushUrl = git@github.com:chutzimir/wordpress-svn
fetch = refs/heads/*:refs/remotes/svn/*
push = refs/remotes/svn/*:refs/heads/*
Note that I also do not prefix the fetch line of github with "+" because I do not want the two remote repos - subversion and github - to accidentally overwrite the local tracking branches.
Hi Chutz,
ReplyDeleteThanks for sharing the tips on how to keep track of an SVN repo by creating a mirror of it using Git. Really appreciated. I'm trying to setup a similar local repo for tracking the SVN repo at Google Code for Textpattern CMS.
Now, a little request: please, could you try to explain this sentence a bit more:
"Note that I also do not prefix the fetch line of github with “+” because I do not want the two remote repos – subversion and github – to accidentally overwrite the local tracking branches."
Not only I'm having a hard time trying to undesrtand it and the "+" syntax, but also, I think your suggested config file on the blog post doesn't match with your suggestion at:
https://github.com/chutzimir/wordpress/wiki
There (at wiki), you did prefix the fetch line with plus, running this:
git config remote.github.fetch '+refs/heads/:refs/remotes/svn/'
So, could you please shed some light on using plus/non-plus on fetch, and, by now, which is your preferred method (the one on this post or the one on the wiki)?.
Thanks again.
One more little question, if you don't mind.
ReplyDeleteI've seen both at this article and at GitHub wiki that, for tags, you use something like:
git config svn-remote.svn.tags 'tags/*:refs/tags/*'
What's the reason to keep tags at refs/tags/ instead of keeping them at refs/remotes/svn/tags?
I must admit I don't fully grasp the idea.
Thanks.
fetch = refs/heads/*:refs/remotes/foo/*
ReplyDelete"fetch" tells git what refs to take from the remote (the part before the colon) and save them locally under the name given after the colon. refs/heads/bar on the remote will be visible as refs/remotes/foo/bar locally. Normally, the local branch will only be updated if it is a fast forward (if it is an older version of the remote branch).
fetch = +refs/heads/*:refs/remotes/foo/*
If you put a "+" in front of the "fetch" value, then the local tracking branch will be updated even if it is not a fast-forward. In other words, an older version of the branch on github could overwrite the newer local branch that I got from subversion.
The problem is that normally you dedicate one tracking naming prefix for one remote. It's usually called refs/remotes/[remotename]. In this case I am using the same name for svn and github.
I updated the github wordpress wiki to match this page.
When they are under "refs/tags" then git will know that they are tags ("git tag" will list them, "tig" will show them in pink color, etc). If they are under "remotes/svn/tags" then they are just like any other branch.
ReplyDeleteChutz, thanks for the reply, it really helped clearing the fog, as it confirms most of what I suspected about this particular way of setting up a git repo tracking an SVN repo.
ReplyDeleteReally clever solution.
Thanks for this one too.
ReplyDeleteAs I originally initialized and fetched the SVN repo using an slightly modified .git/config file, I ended up putting branches at "remotes/svn/tags", and as you said, those were seen as branches.
Then, I converted them to real git tags, by running the command on this post
http://beardedmagnum.com/2009/02/15/converting-git-svn-tag-branches-to-real-tags/
Problem was that it seems (hopefully, I'm correct about this) I ended up with two tags for each tag: one lightweight and one annotated.
Luckily, I was able to clean up this mess by editing the .git/packed-refs file and getting rid of the lightweight tags.
An 'git ls-remote .' displayed a nice list of references.
Then, the only remaining thing was to push this new list of tags ('git push [remote] --tags') to a few remotes I've got configured and then, ran "git fetch [remote] --tags" on each cloned repo to update to the cleaned list of tags.
So far, everything seems to be in good shape.