markdown 使用Git和Subversion镜像进行WordPress插件开发

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 使用Git和Subversion镜像进行WordPress插件开发相关的知识,希望对你有一定的参考价值。

**Update:** please note that I have since switched to using a [set of bash scripts](https://github.com/kasparsd/wp-deploy) instead of poluting the Git repository with `git svn`.

# Using Git and GitHub with Subversion (SVN) Mirroring for WordPress Plugin Development

Author: [Kaspars Dambis](http://konstruktors.com)  
[kaspars.net](http://kaspars.net) / [@konstruktors](http://twitter.com/konstruktors)

![Illustration: Using Git with Subversion Mirroring for WordPress Plugin Development](http://konstruktors.com/wp-content/uploads/2012/09/wordpress-git2svn-illustration.png)



## Getting Started

We'll assume that your plugin is already hosted on the official WordPress plugin Subversion repository, and we'll use the [Easy Digital Downloads](http://wordpress.org/extend/plugins/easy-digital-downloads/) plugin as an example.

1. 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 the 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](http://plugins.trac.wordpress.org/log/easy-digital-downloads) to determine the first revision number.

2. 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 stop `git svn clone` from moving into the base folder of the remote SVN repository and going through all plugins (see [git-svn docs](http://schacon.github.com/git/git-svn.html)). 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](http://schacon.github.com/git/git-svn.html)).

3. 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` environment variable before the the command to see a verbose output:

		$ GIT_TRACE=1 git svn fetch
	
	To speed up `git svn fetch` especially with large SVN repositories you can try setting the `--log-window-size` parameter to request more commits per SVN request (read [Experiences of Using Git-Svn on a Large Project](http://blog.leneghan.com/2012/03/experiences-of-using-git-svn-on-large.html)). Increasing it to 10000 should decrease the fetch time significantly:
	
		$ git svn fetch --log-window-size 10000

	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 SVN `/trunk`) into our Git `master` branch (I assume), which is done using:
	
		$ git svn rebase

	Now you should see all the latest plugin files in your local repository.
	
	![List of plugin files](http://konstruktors.com/wp-content/uploads/2012/09/plugin-contents.png)



## Inspecting the Newly Cloned Repository

Let's look at all the branches that were created:

	$ git branch -a

which 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	

<!--
### Converting SVN Folders into Git Branches and Tags

In the list of newly created branches we see that all SVN tags have been turned into regular Git branches. Here is a simple script to convert those *tag* branches into proper Git tags:

	$ git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done

And we can do the same for all other references under `refs/remotes` -- turn them into Git branches like so:

	$ git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done
-->

Inside `.git/config` of 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 Git changes back to the WordPress SVN repository.



## Adding a Remote Git Repository

Let's [create a new GitHub repository](https://github.com/new) which we'll use as the main repository for our plugin developemnt from now on: 

![New repository created on GitHub](http://konstruktors.com/wp-content/uploads/2012/09/new-repo-sample.png)

Once you have created the repository, simply add it as a remote origin of our local Git repository:

	$ git remote add origin git@github.com:kasparsd/wordpress-svn2git-sample.git

and then push our local repository to GitHub:

	$ git push origin --all

Now your GitHub repository should contain all your plugin files as well as all the revision history carried over from the Subversion repository.

![WordPress plugin revision history on GitHub](http://konstruktors.com/wp-content/uploads/2012/09/wp-plugin-on-github.png)



## Working with the Plugin

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"



### Pushing Changes to GitHub

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%)



### Pushing Changes to WordPress Subversion Repository

Once you have switched to using Git as your version control system, you should always use `git svn dcommit` to publish changes to the SVN repository. Otherwise, you must run

	$ 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	



### Tagging Releases

Tagging a release in Git is very simple:

	$ git tag v1.0.2

To create an SVN tag, simply:

	$ git svn tag 1.0.2

This will create `/tags/1.0.2` in the remote SVN repository and copy all the files from the remote `/trunk` into that tag, so be sure to push all the latest code to `/trunk` before creating an SVN tag.


### Updating and Trakcing Plugin Assets

[Assets folder in the WordPress SVN repository](http://wordpress.org/plugins/about/faq/) can be used for storing plugin banners and screenshots. Make sure that the `/assets` folder actually exists in your SVN repository before trying to fetch it. Open this in your web browser:

	http://plugins.svn.wordpress.org/easy-digital-downloads/

where `easy-digital-downloads` is the slug of your plugin, and you should see the root folder of your plugin SVN repository:

	Revision 851441: /easy-digital-downloads

	..
	1.0.4/
	assets/
	branches/
	tags/
	trunk/

Notice that the `/assets` folder is present.

Let's track that folder as a seperate Git branch called `assets`. Every time you need to update the cover image or screenshots you, simply checkout that branch, do the changes and publish it to SVN using the same old `git svn dcommit`.

Add a new SVN remote called `assets`:

	$ git config --add svn-remote.assets.url http://plugins.svn.wordpress.org/easy-digital-downloads/assets

and set it to use the `assets` branch on our remote SVN repository:

	$ git config --add svn-remote.assets.fetch :refs/remotes/assets

This will have appended the following to our `.git/config`:

	[svn-remote "assets"]
   		url = http://plugins.svn.wordpress.org/easy-digital-downloads/assets
    	fetch = :refs/remotes/assets

which means that we can now fetch the `assets` remote at its current HEAD:

	$ git svn fetch -r HEAD assets

and switch to it using:

	$ git checkout remotes/assets
	
	Note: checking out 'remotes/assets'.

	You are in 'detached HEAD' state. You can look around, make experimental
	changes and commit them, and you can discard any commits you make in this
	state without impacting any branches by performing another checkout.

	If you want to create a new branch to retain commits you create, you may
	do so (now or later) by using -b with the checkout command again. Example:

	  git checkout -b new_branch_name

	HEAD is now at 7e5b727... Updated banner image

Let's create a local branch called `assets` to track this remote:

	$ git checkout -b assets

Now you can add and modify plugin assets, commit the changes and then publish the changes to the SVN, using:
	
	$ git svn dcommit



## Suggested Reading

 - http://teleogistic.net/2011/05/revisiting-git-github-and-the-wordpress-org-plugin-repository/
 - http://eamann.com/tech/how-to-publish-a-wordpress-plugin-git/
 - http://ben.lobaugh.net/blog/90633/creating-a-synchronized-github-fork-of-a-wordpress-org-subversion-plugin-repository
 - http://en.hetarena.com/archives/232

	



以上是关于markdown 使用Git和Subversion镜像进行WordPress插件开发的主要内容,如果未能解决你的问题,请参考以下文章

有人在同一台机器上同时使用Tortoise Git和Subversion吗?

从 git 推送到 subversion 存储库

二进制文件的 Git 或 Subversion

markdown Mac上的Subversion(SVN)服务器(OS-X)

如何 git-svn 从 Subversion 存储库克隆最后 n 个修订?

SVN使用