Git Workflow
Also read gitfaq and CONTRIBUTING.md which have other workflows and PHP git tips.
Git does not enforce a certain workflow. For php-src we will use a workflow that is described below.
We will use release branches for the php-src.git repository. We will have branches for actively maintained versions. For example: 7.4, 8.0, 8.1 and master. A patch will be applied to the oldest possible branch. If the Release Manager of 7.4 accepts the change, commit it to the 7.4 branch. We will use regular merging between the release branches. Bigger features can use feature branches, but developers are encouraged to fork php on github and start implementing the feature there on the respective branch.
Bugfix Workflow for Core Developers
Core developers that have access to the php-src.git repository apply changes to the lower possible branch and then merge the change upwards. The repository is prepared in a way, that only new changes will be merged upwards. E.g. Git will not attempt to synchronize the whole 5.6 and 7.0 branch. Only your commit will be merged.
Here is a visualization of a standard Patch Workflow
Let's go through the process of setting it up and doing the merges.
Initial Setup
$ git clone git@github.com:php/php-src.git $ cd php-src $ git config merge.NEWS.name "Keep the NEWS file" $ git config merge.NEWS.driver 'touch %A' $ git config merge.log true
Please refer to Git FAQ for alternative cloning methods via HTTP or the Git Protocol.
Patching a release branch
Patching the PHP 7.4 branch:
$ git checkout PHP-7.4 ... hack hack ... $ git commit <changed files> ... USE A GOOD COMMIT MESSAGE ... ... run tests ... $ git checkout PHP-8.0 $ git merge PHP-7.4 ... run tests ... $ git checkout PHP-8.1 $ git merge PHP-8.0 ... run tests ... $ git checkout PHP-8.2 $ git merge PHP-8.1 ... run tests ... $ git checkout master $ git merge PHP-8.2 ... run tests ... $ gitk master ... review the merges ... $ git push --atomic origin PHP-7.4 PHP-8.0 PHP-8.1 PHP-8.2 master ... push to the official repository ...
When you use 'git push --all origin', make sure there are not any unwanted branches in local repository or set branch.<name>.remote properly via git-config.
Use the '--atomic' flag to ensure that no refs are updated if the update of any of them fails.
Reviewing and closing pull requests
Johannes has created a tool to easily close pull requests. It requires a valid PHP account.
You can also include Closes GH-NNNN.
in the commit message to automatically close a pull request.
Merge a pull request
Preferably, pull requests should not be merged, but rebased onto the target branch. Because it is common that PRs need to be applied to a different branch than the one it was originally created for, the easiest way to do this is using git am
. Patches for use by git am
can be obtained by appending .patch
to the GitHub URL. For example, to apply pull request #1234 onto branch PHP-7.4:
$ git checkout PHP-7.4 $ wget https://github.com/php/php-src/pull/1234.patch $ git am -3 1234.patch $ git commit --am # Adjust commit message to add "Closes GH-1234." ... REVIEW IT ... $ make test .. you better not forget that ... $ git checkout PHP-8.0 $ git merge PHP-7.4 $ make test $ git checkout PHP-8.1 $ git merge PHP-8.0 $ make test $ git checkout master $ git merge PHP-8.1 $ make test $ git push origin PHP-7.4 PHP-8.0 PHP-8.1 master
Additionally, the history of pull requests often requires cleanup. For most pull requests, all commits can be squashed into one.
Note about moving patches from a newer branch
In case you have to merge a commit from a higher branch. E.g from PHP-8.1 into PHP-7.4 make sure you still merge upwards as described above afterward:
$ git checkout PHP-7.4 $ git cherry-pick <SHA1-OF-PATCH-TO-MOVE> $ git checkout PHP-8.0 $ git merge PHP-7.4 $ git checkout PHP-8.1 $ git merge PHP-8.0 $ git checkout master $ git merge PHP-8.1 $ git push
TL;DR: Always try to merge PHP-7.4 into PHP-8.0, then PHP-8.1, and then into master.
Merge patches received per mail
If patches are created with “git format-patch”, you can easily apply them with git's am command:
$ git am 000*
Normal diff-patches can be applied with git apply:
$ git apply <patchfile>
Updating NEWS
If a patch is related to a bug ticket or is worth it a mention otherwise, the NEWS file needs to be updated to reflect the change done. The NEWS entry has to be added manually in every branch, where the patch is applied. Whereby NEWS in master is being updated only for master only patches. More info is available in the corresponding section in README.GIT-RULES.
When merging upwards, you can either commit the NEWS entry separately, or as part of the merge commit. To do that, merge using git merge PHP-8.2 --no-commit
, add the NEWS entry, add it to the staging area, and git merge --continue
.
Feature Workflow for Core Developers
Feature development can take a lot of time. You might not know to which branch the feature will be committed or you want to combine commits before pushing the final bits. Therefore it is advised to use a separate branch while you develop your feature. This approach is called a feature branch:
The workflows aim for a feature to be included into the master branch. So we branch of the master branch first:
$ git checkout -b feature/featurename master .. hack hack hack ... $ git commit
Update your branch regularly so it's up to date:
$ git checkout feature/featurename $ git rebase master
Once the feature is accepted, make sure your branch is up to date (see above) and then fast-forward merge it into master:
$ git checkout master $ git merge --ff-only feature/featurename
Workflow for external contributors
The standard workflow for external contributors:
Fork the php-src to your own github account. Setup your issue branch on your development system:
$ git clone git@github.com:<account>/php-src.git php $ cd php $ git remote add upstream https://github.com/php/php-src.git $ git fetch upstream $ git branch --track issue-<issuenr> origin/PHP-7.4 (or use origin/master) $ git checkout issue-<issuenr>
Do your stuff and add/commit your work accordingly. Optionally, you can rebase your work:
$ git pull --rebase upstream PHP-7.4 (or use upstream master)
Push your branch to your github repository:
$ git push origin issue-<issuenr>
Before you send in your pull request:
- Make sure you have proper (and passing) tests for the change.
- Make sure the pull request message contains a good and precise description what was changed and why.
We accept patches in several ways. We prefer getting pull requests from github:
- Go to your own github PHP repository, select your branch and click the “pull request” button.
- Now you can create a pull request on your github account to the upstream branch (the same version as you branched).
- Add a descriptive pull request message.
- All pull request notifications are sent to the git-pulls@lists.php.net mailinglist.
- Wait for comments.
If you prefer mail use git format-patch and send the created patch using mail:
$ git format-patch origin/PHP-7.4 0001-bug-fix.patch ... 0005-another-commit.patch
These patches can be attached to a bug or emailed, e.g. to internals@lists.php.net
If you don't have an issue-number, just make the branch name self-descriptive (ie: “json_encoding_fix” instead of “branch-001”). As stated before, branch from the lowest version possible. When you want to create a patch that needs to be incorporated into several branches, like a security fix for something in PHP-7.4, PHP-8.0, PHP-8.1, and the master, make sure you checkout a branch from PHP-7.4. You don't need to create separate pull requests for PHP-7.4, PHP-8.0, PHP-8.1, and master.
New Commit Message Format
We propose the following commit message format for PHP:
<max 79 characters short description>\n \n <long description, 79 chars per line> \n
An Example from the git project (commit 2b34e486bc):
pack-objects: Fix compilation with NO_PTHREDS It looks like commit 99fb6e04 (pack-objects: convert to use parse_options(), 2012-02-01) moved the #ifdef NO_PTHREDS around but hasn't noticed that the 'arg' variable no longer is available.
Git commands like log, shortlog, etc support this format and make use of the short description. Please stick to the format.