====== Moving to Git FAQ ====== A good start is the [[http://git-scm.com/book|ProGit book]], which is available online. ===== Introduction ===== The PHP git repositories are at https://github.com/php PEAR repositories are in https://github.com/pear. This FAQ does not discuss PEAR. Also, see [[gitworkflow | Git Workflow]] which discusses the workflow for PHP development. ===== Clients ===== 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 * Windows [[http://code.google.com/p/msysgit|Msysgit]] * Mac OS X [[http://code.google.com/p/git-osx-installer/downloads/list?can=3|Git OS X Installer]] ===== Clone URL and Push URL ==== Clone/Push URL https://github.com/php/php-src.git SSH URL git@github.com:php/php-src.git Hint: set the push URL (https or git@) with (see also, Quickstart below) git remote set-url origin --push ===== Mandatory Git Settings ===== The PHP NEWS file has a special notion. It is manually merged and should not be touched. However using merges, git will automatically attempt to merge the NEWS file. To avoid this issue create a custom merge driver for the file. Please use the exact naming as the repository is configured to use this merge driver as a driver for NEWS: $ git config merge.NEWS.name "Keep the NEWS file" $ git config merge.NEWS.driver 'touch %A' ===== Recommended Git Settings ===== Set user details: $ git config --global user.name "FIRSTNAME LASTNAME" $ git config --global user.email username@php.net Add a list of merged commits to the autogenerated commit message $ git config merge.log true Enable colored output for git commands $ git config color.ui true Avoids pushing other branches by accident when using a plain "git push". Git will only push the branch you are on by default. Note this will prevent the "Multiple working copies workflow" steps (shown below) from working: $ git config --global push.default current Consider setting up sensible .gitignore settings (see also http://help.github.com/ignore-files/) You can exclude file patterns 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. ===== Special Case Git Settings ===== Set filemode. This is useful when you do not need to change files permissions in the repository. If you need change file mode (+x for example) you must switch it option to true. $ git config core.filemode false This is useful 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 different line endings in files! $ git config core.autocrlf input If you are behind a firewall set a proxy: $ git config http.proxy your-proxy-host:80 ===== Quickstart ===== $ git clone https://github.com/php/php-src.git $ cd php-src // 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.6 and PHP 7.0, commit to PHP 5.6. Then merge your commit. $ git clone https://github.com/php/php-src.git .... $ git branch --track PHP-5.6 origin/PHP-5.6 $ git branch --track PHP-7.0 origin/PHP-7.0 $ git branch --track master origin/master $ git checkout PHP-5.6 ... edit Zend/zend.c ... $ git commit Zend/zend.c $ git checkout PHP-7.0 $ git merge PHP-5.6 $ git checkout master $ git merge PHP-7.0 $ git push ===== Multiple working copies workflow ====== This workflow allows you to keep checked-out branches in several folders. It removes the need to rebuild PHP every time you change branches. Note: If you're not a core PHP developer, follow the steps in [[vcs:gitworkflow#workflow_for_external_contributors|Workflow for external developers]] instead because the steps below require PHP source karma to push commits. **Clone repository** cd git clone git@github.com:php/php-src.git or if you're behind a firewall: cd git clone https://github.com/php/php-src.git cd ~/php-src ==== Recommended: Git worktree ==== Git version 2.5 or later has [[https://git-scm.com/docs/git-worktree|git worktree]] command. Wortree is better than 'git-new-workdir', so you should use worktree in general. You can keep branch checkouts in different directories and avoid full rebuild when you are working with multiple branches. cd ~/php-src **Creating work trees** Checkout remote branches git checkout PHP-5.6 git checkout PHP-7.0 git checkout PHP-7.1 git checkout master Create work trees for branches. git worktree add ../php-5.6 PHP-5.6 git worktree add ../php-7.0 PHP-7.0 git worktree add ../php-7.1 PHP-7.1 Now you have following work trees for specified branches ~/php-5.6 ~/php-7.0 ~/php-7.1 ~/php-src You can list work trees by git worktree list ==== Obsolete: git-new-workdir ==== **Find the git-new-workdir script** Find the git-new-workdir script, which is usually located in contrib folder in the git-core package: conf@laptop ~ $ locate git-new-workdir /usr/share/doc/git/contrib/workdir/git-new-workdir 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 PHP 5.6 and 7.0 branches, assuming that we use php-src for master: conf@laptop ~ $ bash /usr/share/doc/git/contrib/workdir/git-new-workdir ./php-src ./php-5.6 PHP-5.6 Already on 'PHP-5.6' conf@laptop ~ $ bash /usr/share/doc/git/contrib/workdir/git-new-workdir ./php-src ./php-7.0 PHP-7.0 Switched to branch 'PHP-7.0' ** Using out-of-tree-builds ** Johannes has created a simple script on github https://github.com/johannes/create-php-workdir to setup a structure using multiple working dirs and then multiple build dirs per branch to test different PHP configurations without switching between different configure lines which might require make clean calls and full rebuilds in between. ==== Working with multiple worktree ==== Now you have your PHP-5.6 branch checked out in ~/php-5.6, PHP-7.0 in ~/php-7.0 and master in ~/php-src. ** Make initial fix in 5.6 (better in a separate branch): ** cd ~/php-5.6 git checkout -b [edit files] git diff git add git commit -a Use the [[vcs::gitworkflow#new_commit_message_format|New Commit Message Format]] for your commit message. ** Make sure that release branches are not stale. ** cd ~/php-5.6 git fetch # download all remote changes but do not apply them git checkout PHP-5.6 # make sure each working copy is on its release branch git pull # this is easier to write than git merge origin/PHP-5.6, although it calls the remote repo one more time cd ~/php-7.0 git checkout PHP-7.0 git pull cd ~/php-src git checkout master git pull If there are any changes in PHP-5.6 branch, rebase our branch against them: cd ~/php-5.6 git checkout git rebase PHP-5.6 ** Merge mybranch into PHP-5.6 ** cd ~/php-5.6 # if you're not here yet git checkout PHP-5.6 git merge git diff origin/PHP-5.6 # review changes ** Merge upwards to 7.0 and master: ** cd ~/php-7.0 git checkout PHP-7.0 git merge PHP-5.6 git diff origin/PHP-7.0 cd ~/php-src git checkout master git merge PHP-7.0 git diff origin/master ** Test push ** git push --dry-run origin ** Push the changes ** git push origin ===== Tagging ===== 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.6.9 ... GPG passphrase ... ... edit tag message .. $ git push origin PHP-5.6.9 ===== Using SSH ==== * Add your SSH key to your profile on https://main.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 git@github.com:php/php-src.git For web git repositories, don't forget the first slash or you'll get an error when committing ("access denied", or "there may be no repository at the given path") : git config remote.origin.pushurl git@github.com:php/php-src.git ===== Change Tracking ==== * 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 ===== There is a mailing list called . All pull requests created for the [[http://github.com/php|github.com/php]] user will go to this mailing list. 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 [[gitworkflow#reviewing_and_closing_pull_requests|Git Workflow]] document for more information. ===== Commit Mails ===== Commit mails are send to the appropriate mailing list (e.g. php-cvs@lists.php.net 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 sent. They will include the patch, a list of changed paths and the commit message. The list of changed paths will also be the subject. ====== FAQ ====== - **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]] - **Rebase - What do you mean?** Read [[https://www.atlassian.com/git/tutorials/merging-vs-rebasing]] and [[https://randyfay.com/content/simpler-rebasing-avoiding-unintentional-merge-commits]] - (Awaiting answer) 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) If you have questions, please send them to internals@lists.php.net.