Development  »  Git

All development work is done against our Git repositories on GitHub.

You can use the Horde Git repositories as an anonymous user or as a developer.

You can checkout, fork, or install each Git module individually and independently from each other, using standard Git commands and tools. If you want to work with the whole Horde Framework or several Horde applications, it is suggested that you use the Horde Git Tools though. The instructions below focus on these tools.

You will need a Git client, if you don't already have one. Information on Git can be found at http://git-scm.com/.

These command lines should be the bare-bones needed to get you started with Horde and Git; this is not a Git tutorial, however. The standard Git documentation is available here. Additional tips and useful links can be found at git ready and 25 Tips for Intermediate Git Users.

 Horde Git Tools

Getting The Source Code

Use these instructions to install the Horde Git Tools. Make sure to configure the tools correctly for your needs, and read the documentation in the configuration file.

To clone the repositories, use the following command:

horde-git-tools git clone

To update the repositories, use this command:

horde-git-tools git pull

Making Development Repos Web-Accessible

To create a web-accessible development installation, use the following command:

horde-git-tools dev install

Running that script will symlink the base horde package into the web-accessible directory you specified in git-tools/config/conf.php, symlink all other Horde applications within that directory, and will properly set up the necessary include/horde path definitions. Note that all edits should take place within the repository, as the web-accessible directory will be deleted every time the dev install script is run.

Full directory paths will be needed in horde-git/horde/config/registry.php due to the symlinks. The easiest way to setup full paths is to set the $app_fileroot parameter in this file.

Note that unlike a PEAR or Composer install, the Autoloader_Cache package will be enabled by default. If you attempt to use Horde or load the test.php page before all dependencies are installed, you will have to purge the autoloader cache.

You can now follow the procedures in the normal INSTALL document to complete the configuration and database creation.

If, after you have configured Horde, you wish you can manually run the database migrations, you can run these from the checkout directory as so:

./horde/bin/horde-db-migrate [application_name [up|down]]

If installing the framework libraries directly via PEAR, i.e. not with with the Horde Git Tools, you will need to define your horde application directory (i.e. the filesystem directory where the Horde application is installed and accessible to a browser) in your PEAR config. This can be done with the horde/Role package previously installed on your system via:

        pear run-scripts horde/Horde_Role
        

Creating Patches

Please use the Pull Request feature on GitHub to submit patches.

 Developer Git

Write access to the Git repositories as a Horde developer is only available over SSH. You will want to create an SSH key, and you will also need to create an account on GitHub. The following needs to be done:

  1. Create a GitHub account.
  2. Setup your SSH public key.
  3. Join the Horde organization on GitHub (send e-mail to core@horde.org).

Getting The Source Code

Follow the instruction above to install the Horde Git Tools, but create the configuration file from config/conf.php.dev.dist instead of config/conf.php.dist. Then continue with making the repositories web-accessible as described above.

Updating repositories

To update your local repositories, you MUST rebase the changes on top of your local repo copy if using Git manually, i.e. without using the Horde Git Tools. Failure to do so will result in useless, annoying commit merge messages both added to the master repository and sent in the commit e-mails.

To update/rebase the changes, you can use the following command that already rebases automatically, and adds a helpful Git get alias to update your local repositories while seeing changed files and avoiding conflicts.:

horde-git-tools git pull

For more information on rebasing, and the commands needed if conflicts are detected during the rebase/merge, see: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#using-git-rebase and http://jbowes.dangerouslyinc.com/2007/01/26/git-rebase-keeping-your-branches-current/.

Creating commits

First, you should make sure your contact information is correct. The easiest way to do so is to issue the following commands:

        git config user.name "FirstName LastName"
        git config user.email "user@example.com"
        

Go ahead and hack away. When finished, commit the files to your local repo. There are several ways to do this. To add specific files to a commit, use the following commands:

        git add filename [filename2] [filename3...]
        git commit
        

git add has many powerful tools to indicate what files or portions of a file you want to commit: the -i option (interactive mode), and -p option (patch mode) are good examples. Read the man page for further information on these options (and others).

You can also list the files to be committed on the command line to commit:

git commit [filename1] [filename2] ... [filenameX]

If you want to commit all modified files, you can use the following shortcut command:

git commit -a

If you want to commit all modified files, and want a shortcut to also specify the commit message on the command line, use the following command:

git commit -a -m "[commit message]"

The Horde Git Tools allow to do Git commits on all or several repositories at once. Check its documentation for details.

Committing with horde-components

horde-components is a command line tool to help with all kind of developer tasks. To get the full help and all available actions, run:

horde-components help

When using the changed --commit option to update the changelogs, two separate commits are created. The first one only contains the changes to changelog.yml (and any file added earlier to the commit with git add, which is the same across all branches. Thus you can easily cherry-pick this commit from a different branch. The second commit with the same commit message contains changes to the package.xml and CHANGES files that may differ between branches and should not be cherry-picked. To update those files in the other branch, just run horde-components changed without any further arguments again, after cherry-picking the changes to changelog.yml. Such a workflow may look like:

          $ git checkout master
          $ git add changed_file1 directory/changed_file2
          $ horde-components changed --commit "[xyz] Fix this bug."
          [   OK   ] Added new note to version 1.2.3 of /horde/Component/doc/changelog.yml.
          [   OK   ] Updated /horde/Component/package.xml.
          [   OK   ] Updated /horde/Component/doc/Horde/Yaml/CHANGES.
          [master 08c1c38] [xyz] Fix this bug.
           3 files changed, 4 insertions(+)
          [master 409eac9] [xyz] Fix this bug.
           2 files changed, 3 insertions(+)
          $ git checkout FRAMEWORK_5_2
          $ git cp 08c1c38
          [FRAMEWORK_5_2 cc95a99] [xyz] Fix this bug.
           Date: Mon Oct 30 21:54:24 2017 +0100
           3 file changed, 4 insertions(+)
          $ horde-components changed
          [   OK   ] Updated /horde/Component/package.xml.
          [   OK   ] Updated /horde/Component/doc/Horde/Yaml/CHANGES.
        

Pushing commits

Once you finish with your local commits and want to push them to the master repository, use the following command:

git push

When pushing, it is most likely the desired action to ONLY push changes to branches that are currently being tracked on the master server. This is the default git behavior, but the following config verifies that the setting is configured properly:

git config push.default matching

Again, using Horde Git Tools will help to push on several repositories at once.

Stashing

Say you are working in a git tree and have previously made some local commits. You then started working on other code and modified several other files. However, you then decide you want to push the previously made commits to the central repository (e.g. those commits fix a critical bug). However, git will not let you push your commits because your tree is not clean.

In the absence of originally using a branch to do the newer hacking, you can easily create a temporary branch, move the work-in-progress to the temporary branch, push your commits to the server, and then re-apply your work-in-progress to the current branch. Git has a wonderful built-in command that will do all this work for you: stash. To stash all work-in-progress on the current tree, use:

git stash

When you need to pull the changes back, use:

git stash apply

Stash has many more features that won't be explained here - check the documentation (e.g. working with multiple stashes, popping a stash).

Combining commits

It may often happen that you have many local commits that you want to push to the central repository. It may often be that many of these changes are similar (i.e. nits/doc cleanup/whitespace) or that some of the commits fixed things caused by a previous local, non-pushed, commit. In this case, it may be better to clean up the commit list to make the ultimate project history and commit notification e-mails look nicer. Git provides an easy way to manipulate your local commits:

        # origin means edit all commits applied on top of the last pull
        # from the central repository.
        git rebase -i origin
        

Use the 'squash' option to combine multiple commits. Instructions on the edit screen explain the various other features.

Creating/Managing remote branches

It may be useful to share work on a local branch with other developers. For example, a large change that might not yet be ready for primetime, but could benefit for some eyeballs, might be useful to share on a branch rather than the master repo. To create a branch on the master Horde repository, and have your existing topic branch track the remove branch, use the following command:

git push -u origin [localbranch]

Now all users can track this branch by issuing this command:

git checkout -t origin/[remote branch name]

You should keep the topic branch up to date with the main branch during development so that your topic branch only contains the changes related to the work being done in the branch:

        git checkout [topic]
        git merge master
        # resolve conflicts
        git pull --rebase
        git push
        

During a long-lived branch, you will find yourself having to resolve the same conflicts over and over again. The git tool git-rerere is designed to help alleviate this issue. Once it is enabled, it will automatically take note of each conflict, and it's eventual resolution. Next time git comes across the exact same conflict, it will know on it's own how to resolve it. To use this feature you must explicitly enable it:

            git config --global rerere.enabled 1
        

To delete the remote branch, issue this command:

git push origin :[branchname]

To remove stale remote branches from your branch list, issue this command:

git remote prune origin