Git Branch Structure: Development, Testing and Production

I am working in a company where, until now, I have been the only software developer. The software is a web-based customer portal running on LAMP. The environment consists of 3 versions of the software - dev (, test ( and live ( All development work is done on the dev system  - I work in PHPStorm and that is linked to the dev version on the server. The test version is for users to test out new features and fixes before they go live. Up until now I have managed putting new code to the test and live systems using Beyond Compare. Cherry-picking the elements that need to go across as necessary. Database sync has been done using Navicat.

Now there are 3 developers and so I have decided to implement Git but I have to admit I am struggling to get my head around the best approach, bearing in mind the needs of the company.

We need to keep the structure of test and live systems. When it comes to new features, these will be need to be signed off before being set live. Sometimes this will be a very quick process (e.g. same day), sometimes things will be on the test system for weeks, even months before being signed off and will go through numerous changes.

For the developers we each use PHPStorm as development tool and will be working on numerous different tasks at the same time - features, improvements and bug fixes. These will be assigned to us using Jira Software, which can automatically create branches in BitBucket. We currently have separate versions of a dev system (e.g., and so we can test our own work without seeing each others’ work. Each of these has its own URL, vhost and database.

How can I best set up our Git platform bearing in mind this structure?

One suggestion is that the live (production) system is the master branch, the test is a sub-branch of the master and then we have sub-branches from the test branch for development, but I’m not sure how well that works for tracking issues across the branches.

Another idea is the test branch is the master and the production is kept entirely separate.

I think the main points I am trying to figure out are:

  • If there is a bug to fix (on the live). How would this work, when it would likely exist and therefore need fixing in all branches?
  • How we manage issues across the test and live systems, bearing in mind that there will be some things in test for months and others for only hours.
  • How we can work with our own dev platforms (, etc.) for our own testing purposes.
  • How to handle database structure/data changes (MariaDB).

Finally, how can I migrate our current structure “as is” into Git. Currently there are separate folders and webspaces for each version (3x dev, 1x test, 1x live).

Any and all advice appreciated.

1 Like

All of this is just my opinion. There are going to be tradeoffs for any approach and everyone will choose differently. This is the power and the curse of Git, it is very un-opinionated about how people should organize their workflow which means you can model pretty much any workflow … but with all that freedom you have to make your own choices.

The way that I would organize things is that live is deployed from master and all other environments can be deployed to from any branch. One way to do this is by following the Twelve Factor App design. I’ve never used PHP Storm and it has been literally over a decade since I’ve worked with PHP, so I’m not sure if that is a valid expectation for your environment but it is, in my opinion, an industry best practice at this point.

Any change, whether short-, medium-, or long-term, to your application should be a branch off of master that can then be deployed to any environment for testing. Any branch that lasts longer than a few hours will most likely need to have master merged back into it at regular intervals to ensure that the changes that have been deployed since the branch was created won’t break the changes that are currently being worked on.

How to handle database structure changes is a whole separate conversation in and of itself and, unfortunately, not exactly one that I feel particularly qualified to comment on. You may want to take a look at the design of migrations systems from things like Rails or Phoenix and see if anything like that is available for your environment.

I hope that helps!