Page tree

Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.


We aren’t going to do anything component wise on the server side at this time. We currently get the PHP version from the client side, allowing us to lookup modules based on the PHP version they were published for (at this time this is mostly for Zended modules).

The Why

Image RemovedImage Added

Image Removed

The repository setup that we use and that works well with this branching model, is that with a central “truth” repo. The central "truth" repo for is Note that this repo is only considered to


The repo at is considered to be the central one (since Git is aDVCS, there is no such thing as a central repo at a technical level). We will refer to this repo as origin, since this name is familiar to all Git users.



Image Added

Each developer pulls and pushes to origin. But besides the centralized push-pull relationships, each developer may also pull changes from other peers to form sub teams. For example, this might be useful to work together with two or more developers on a big new feature, before pushing the work in progress to origin prematurely. In the figure above, there are subteams of Alice and Bob, Alice and David, and Clair and David.


Such terminology can also be used when dealing with github, we normally refer to github as one of our remotes. Everything from mirrors directly to github but pull requests are managed through by assigning a remote to the github remote that wants to do said pull request and applying it on first, which then replicates back to github. This way we are applying patches and fixes directly to our "truth" repo.

The How

The main branches

Image RemovedImage Added

At the core, the development model is greatly inspired by existing models out there. The central repo holds two one main branches branch with an infinite lifetime:

  • master
  • develop

The master branch at origin should be familiar to every Git user. Parallel to the master branch, another branch exists called develop.

We consider origin/master to be the main branch where the source code of HEAD always reflects a production-ready state. In our case it is usually the STABLE branch code and thus is reflected back into weblate.

Example. If there are currently three active releases of FreePBX: 13,14,15, at any time any one of those branches might be mirrored into Master.

This means the code base here in master will directly match the code base of one of the release branches (talked about later in this article)

We consider origin/develop to be the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. Some would call this the “integration branch”. This is where our nightly builds are built from.

When the source code in the develop branch reaches a stable point and is ready to be released, all of the changes should be merged back into master somehow and then tagged with a release number. How this is done in detail will be discussed further on.

Therefore, each time when changes are merged back into master, this is a new production release by definition.


Feature branches

  • May branch off from: developrelease/*
  • Must merge back into: developrelease/*
  • Branch naming convention: feature/*


When starting work on a new feature, branch off from the develop branch.the release branch you want to start from

Code Block
$ git checkout -b myfeature developrelease/13.0
Switched to a new branch "myfeature"

Incorporating a finished feature on develop

Finished features may be merged into the develop branch definitely add them to the upcoming release:

Code Block
$ git checkout develop 
Switched to branch 'develop' 
$ git merge --no-ff myfeature Updating ea1b82a..05e9557 (Summary of changes) 
$ git branch -d myfeature Deleted branch myfeature (was 05e9557). 
$ git push origin develop

The --no-ff flag causes the merge to always create a new commit object, even if the merge could be performed with a fast-forward. This avoids losing information about the historical existence of a feature branch and groups together all commits that together added the feature. Compare:

Image Removed

In the latter case, it is impossible to see from the Git history which of the commit objects together have implemented a feature—you would have to manually read all the log messages. Reverting a whole feature (i.e. a group of commits), is a true headache in the latter situation, whereas it is easily done if the --no-ff flag was used.

Yes, it will create a few more (empty) commit objects, but the gain is much bigger that that cost.

Unfortunately, I have not found a way to make --no-ff the default behavior of git merge yet, but it really should be.

Release branches

May branch off from: developrelease/*
Must merge back into: develop and master
Branch naming convention: release/*


Code Block
$ git checkout -b release/114.2 develop 0 release/13.0 
Switched to a new branch "release/113.2" 
$ ./ 1.2 
Files modified successfully, version bumped to 1.2. 
$ git commit -a -m "Bumped version number to 1.2" 
[release-1.2 74d9424] Bumped version number to 1.2 1 files changed, 1 insertions(+), 1 deletions(-)

After creating a new branch and switching to it, we bump the version number. Here, is a fictional shell script that changes some files in the working copy to reflect the new version. (This can of course be a manual change—the point being that some files change.) Then, the bumped version number is committed.



This new branch may exist there for a while, until the release may be rolled out definitely. During that time, bug fixes may be applied in this branch (rather than on the develop branch). Adding large new features here is strictly prohibited. They must be merged into develop, and therefore, wait for the next big release.


May branch off from: master, release/*
Must merge back into: develop and master and release/*
Branch naming convention: hotfix/*