This is an old revision of the document!
Moving to Git FAQ
A good start is the ProGit book, which is available online.
PEAR repositories are in https://github.com/pear. This FAQ does not discuss PEAR.
Also see Git Workflow which discusses the workflow for PHP development.
The Git client is available in most major operating systems. If you don't already have a Git client, this list should be helpful:
- Linux (apt-get)
sudo apt-get install git-core gitk
- Linux (yum)
sudo yum install git gitk
- Mac OS X
Clone URL and Push URL
Read only urls are
Clone/Push URL (always requires password)
Hint: set the push URL (https or git@) with (see also, Quickstart below)
git remote set-url origin --push <URL>
Recommended Git Settings
$ git config --global user.name "FIRSTNAME LASTNAME" $ git config --global user.email email@example.com $ git config merge.log true adds a list of merged commits to the autogenerated commit message $ git config alias.co checkout alias for checkout. you can now use git co to checkout a branch $ git config color.ui true enable colored output for git commands $ git config --add merge.ff false Allows you to omit the "--no-ff" switch in merge. Requires Git 1.7.6 or later. Special cases: $ git config core.filemode false This is useful when you do not need to change files permissions in repository. If you need change file mode (+x for example) you must switch it option to true. $ git config core.autocrlf input This is usefull for web and doc projects. This setup should leave you with CRLF endings in Windows checkouts but LF endings on Mac and Linux systems and in the REPOSITORY. Do not use it if you need differents line endings in files!
Consider setting up sensible .gitignore settings (see also http://help.github.com/ignore-files/)
You can exclude filepatterns without touching the committed .gitignore: Set the config variable core.excludefile to a global exclude file or add the desired pattern to .git/info/exclude on a per-repo base.
$ git clone http://git.php.net/repository/php-src.git $ cd php-src // if you want to push throuh https $ git config remote.origin.pushurl https://git.php.net/push/php-src.git // update repository $ git pull --rebase // will pull the new changes and apply your local changes on top of it. // results in a linear history. make sure you understand what // rebase does!
Committing and Merging
Always commit to the oldest branch. If your commit is good for PHP 5.3 and PHP 5.4, commit to PHP 5.3. Then merge your commit.
$ git clone http://git.php.net/repository/php-src.git .... $ git branch --track 5.3 origin/PHP-5.3 $ git branch --track 5.4 origin/PHP-5.4 $ git branch --track master origin/master $ git checkout 5.3 ... edit Zend/zend.c ... $ git commit Zend/zend.c $ git checkout 5.4 $ git merge --log 5.3 $ git checkout master $ git merge --log 5.4 $ git push
Multiple working copies workflow
That's useful so you can keep checked out branches in several folders without need to do ./vcsclean everytime.
cd git clone firstname.lastname@example.org:php-src.git
or if you're behind firewall
cd git clone https://git.php.net/repository/php-src.git
These both are push-urls, so if you're not a core dev, fork project on github and use pull requests for sending patches (see Workflow for external developers)
Find git-new-workdir script
Find git-new-workdir script, usually located in contrib folder in the git-core package. If you're on Ubuntu like me, you can find it this way:
conf@laptop ~ $ locate git-new /usr/share/doc/git/contrib/workdir/git-new-workdir conf@laptop ~ $
This script creates several working copies sharing the same git repository, just as we need. I.e. if you make some commits in any working copy, they're available in all copies instantly. Read how it works here: http://nuclearsquid.com/writings/git-new-workdir/
Create working copies
Make working copies for 5.3 and 5.4 branch, assume that we use php-src for master:
conf@laptop ~ $ bash /usr/share/doc/git/contrib/workdir/git-new-workdir ./php-src ./php-5.3 PHP-5.3 Already on 'PHP-5.3' conf@laptop ~ $ bash /usr/share/doc/git/contrib/workdir/git-new-workdir ./php-src ./php-5.4 PHP-5.4 Switched to branch 'PHP-5.4' conf@laptop ~ $
Now you have your PHP5.3 branch checked out in ~/php5.3, PHP5.4 in ~/php5.4 and master in ~/php-src.
Make initial fix in 5.3 (better in separate branch):
cd ~/php-5.3 git checkout -b <mybranch> [edit files] git diff git add <new files> git commit -am 'Some really relevant commit message.'
Make sure that release branches are not stale.
cd ~/php-5.3 git fetch # download all remote changes but do not apply them git checkout PHP-5.3 # make sure each working copy is on its release branch git pull # that's easier to write than git merge origin/PHP-5.3, although it calls remote repo one more time
cd ~/php-5.4 git checkout PHP-5.4 git pull
cd ~/php-src git checkout master git pull
If there are any changes in PHP-5.3 branch, rebase our branch against them:
cd ~/php-5.3 git checkout <mybranch> git rebase PHP-5.3
Merge mybranch into PHP-5.3
cd ~/php-5.3 # if you're not here yet git checkout PHP-5.3 git merge --no-ff <mybranch> git diff origin/PHP-5.3 # review changes
Merge upwards to 5.4 and 5.5:
cd ~/php-5.4 git checkout PHP-5.4 git merge --no-ff PHP-5.3 git diff origin/PHP-5.4 cd ~/php-src git checkout master git merge --no-ff PHP-5.4 git diff origin/master
Push the changes
git push origin
To create a tag use the git tag command. Git distinguishes between lightweight and heavyweight tags. To create a heavyweight tag, you have to provide a tag message. Please always create heavyweight tags and use GPG keys to sign the tag.
$ git tag -s PHP-5.3.9 ... GPG passphrase ... ... edit tag message .. $ git push origin PHP-5.3.9
- Add your SSH key to your profile on http://master.php.net/manage/users.php
- you can set multiple keys in separate lines
- if you get the “the ssh key doesn't seem to have the necessary format” error, check that your key has your email address at the end (it is mandatory currently to have an email address there)
- Wait 10 minutes
- Clone from or set new repository to email@example.com:php-src.git
For web git repositories, don't forget the first slash or you'll get an error when commiting (“access denied”, or “there may be no repository at the given path”) :
git config remote.origin.pushurl firstname.lastname@example.org:/web/qa.git
- The git push/commit email notification process is under discussion (Jan 2012). For mail lists see http://php.net/mailing-lists.php
- Feeds are available. For example, http://git.php.net/?p=karma.git;a=history;f=hooks;hb=HEAD where p is the project and f is the directory. To show changes to the date extension you could use http://git.php.net/?p=php-src.git;f=ext/date
- For RSS feeds do something like: http://git.php.net/?p=karma.git;a=rss;f=hooks
Github Pull Requests
If you have commit rights to a mirrored PHP repository you can pull the requests and push it to the official repositories.
You cannot use the Merge button on GitHub for that. The PHP Organization on GitHub will not accept contributors. It's only for mirroring!
See the pull request related sections of the Git Workflow document for more information.
Commit mails are send to the appropriate mailinglist (e.g. email@example.com for commits to php-src). For every push a mail with an overview about the pushed changes will be mailed. Follow up mails for every commit will be send. They will include the patch, a list of changed paths and the commit message. The list of changed paths will also be the subject.
- Can I checkout a subdirectory only? Yes, but it's a rather new and experimental feature. See http://vmiklos.hu/blog/sparse-checkout-example-in-git-1-7
- More questions? Just add them, I will try to answer them.
- What about commits that should not be merged upwards (say, only for 5.3)? Should you still merge them but make it so no changes actually take place? Otherwise, it will the next person merging that will have to deal with the conflict (or worse, the changes will be merged when they shouldn't have been)