PHP has moved to git!

Warning: This blogpost has been posted over two years ago. That is a long time in development-world! The story here may not be relevant, complete or secure. Code might not be complete or obsoleted, and even my current vision might have (completely) changed on the subject. So please do read further, but use it with caution.
Posted on 19 Mar 2012
Tagged with:

Good news everybody! PHP has (finally) moved their version control from subversion to git and placed their repository on github. Meaning it just got easier to maintain PHP  but also it makes it easier for external contributors (without any write-access) to create patches and for contributors to merge them. Hopefully this will mean the end of waiting weeks or months before somebody gets around looking at your patch.

So, if you like to contribute you can use the following workflow for now. The most up-to-date workflow should be available on the php.net wiki at https://wiki.php.net/vcs/gitworkflow (the workflow for external contributors section). Make sure you follow those directions if they do not match with these…

Step 1: fork the php-src repo

Assuming you already have created a github account, you must clone the php source repository to your own github account. This can be done by going to the following url: https://github.com/php/php-src, and click on the “fork” button in the top right. This will create a fork of the php source into your own github account.

Step 2: clone your own repository.

Once you have created the repository, you can clone it onto your development machine.

git clone git@github.com:<yourname>/php-src.git php-src

This will take a while, since the repo is around 100MB in size. Just let git do his work for a while.

Step 3: add a remote branch.

Next up, you must add a remote branch. Basically, what you are doing is creating a link between your repository on your development computer and the php-src “master” repository (not your github repository, but from php itself). This is called the “upstream”, and that’s why we name it upstream. Your own github repository is usually called “origin”.

cd php-src
git remote add upstream https://github.com/php/php-src.git

When you check the remotes with the command “git remote -v”, you can actually see both the origin and upstream remotes are available. In my case:

jthijssen@debian-jth:~/php$ git remote -v
origin	git@github.com:jaytaph/php-src.git (fetch)
origin	git@github.com:jaytaph/php-src.git (push)
upstream	https://github.com/php/php-src.git (fetch)
upstream	https://github.com/php/php-src.git (push)

Step 4: create a new (tracking) branch.

Now we can actually create a new “branch” in which we are going to work. Every feature should have its own branch. When you have a issues a bug inside the bug database for PHP, use that number as the branch name:

git branch --track issue-<issuenr> origin/PHP-5.4

Now, a few things are important: first of all, PHP is using tracking-branches, which works a little bit different than local branches. You can read more about that here: http://gitready.com/beginner/2009/03/09/remote-tracking-branches.html.

Secondly, the “issue-" is the branch-name we are using. It might as well have been named "cool-new-awesome-feature", but try to keep it as readable as possible. You are doing your mergers a big favor here.

Another important thing: we are creating an issue for the PHP-5.4 branch here. If you have a feature that isn’t ready for 5.4, or something that needs to be inside 5.3 (like a security fix that also need to be inside 5.4 and the “master” (or trunk as it used to be called)), always use the lowest version. In that case, it would be PHP-5.3. If you don’t know, ask, or use the master branch.

Step 5: switch to the new branch.

Now, we must switch to the new branch, so we can actually work in it:

git checkout issue-<issuenr>

When you look with “git branch”, you will see your (local) branches, and with “git branch -v” you will see some more info:

jthijssen@debian-jth:~/php$ git branch -v
* issue-60742 91f2d38 [ahead 1] Issue-60742: Added FilesystemIterator::OTHER_MODE_MASK
  master      dea5376 Merge branch 'PHP-5.4'

The * in front shows you which is the current branch you are working on. It probably has green color as well.

Step 6: do your stuff.

Now it’s time for the fun part: fixing the code, adding it and committing it.

Every time you want to create a commit, just do a “git add” on the files, following by a “git commit” and enter a log message. Don’t worry about over-committing. That actually doesn’t hurt, under-committing does.

Step 7: rebase your commits in case new commits have been added (optional).

It might be possible that others have committed new stuff to the branch you like to push to. This would be visible in the “upstream” branch, but not in your “origin” branch. There we rebase our commits, basically telling the system to cut away all our commit, update to the latest upstream version and paste our commits to the end. We will do this with the following:

git pull --rebase upstream PHP-5.4

Make sure here that PHP-5.4 is actually the branch name you originated your feature branch from (so it could be PHP-5.3 or probably master as well).

Note though, that rebasing is one of the most difficult things to get right and understand when it comes to git. If you don’t get it working properly, that’s fine and just skip this step. The php developers can just merge your request with others instead, just like in the “old” svn way.

Step 8: push your commits of the new branch to your github.

Now we issue a:

git push origin issue-<issuenr>

This will push our new branch with all the commits to our github repository. When this is done, you can see the new branch on your github account, but you probably have to look for it in the “branches”:

Step 9: issue a pull request.

Now for the most rewarding part: we can finally issue a pull request to the PHP developers. First, switch to the branch you just have pushed to your repository and click on the “pull request” button next to the original “fork” button. You will get a screen like this:

The only thing you need to make sure is that the “base branch” is set to the correct branch. In this case it says “php/php-src @ master”, but it should have been “php/php-src @ PHP-5.4”. Somehow this is not set correctly by default. You need to change this by typing in the correct name, and press “Update Commit Range” button. If everything goes to plan, you will see the number of commits and the actual files that have been changed.

Once done checking, you can press the big green button that submits the pull request to the PHP and hope for the best!