Merging the feature branch into develop and staging as separate merges is definitely causing problems. Typically when I see branch names like "develop", "staging" and "preprod" the team is repurposing version control as a means to track what code is deployed in each application environment — this is not a problem version control was meant to solve.
Each feature needs to be integrated with the other changes that will be deployed to production. We want to treat code changes as some sort of conveyor belt where we can indiscriminately pull one feature off the conveyor belt if there are problems. This is ideal, but not reality.
At some point the team just needs to decide that something will be delivered to production. If QA finds problems, developers need to fix it — not revert the change. The team should not commit to delivering something at the QA testing stage unless they believe QA testing and bug squashing can be completed before the next release.
Changing how you use version control is only part of the fix. Some of these issues are workflow problems that must be addressed with the team. For example, merging into develop, another merge into staging, and then a merge from staging into develop forces the team to deal with 3 merges. Each time you merge, you can run into problems:
- Forcing developers to re-solve the same merge conflicts (once in the merge from feature into develop, and the second time from merging feature into staging).
- Each merge invalidates QA testing done on a different branch. This invalidates QA testing for the feature branch as well as integration testing for staging and develop.
Developers will experience the most pain from the first bullet point. From a quality perspective, the second bullet point is more worrisome. If you did QA testing in develop, but then merge the feature branch again into staging, you invalidate all of the QA testing you did on develop. Merging the same branch into two branches is really the cause of your version control problems, and is possibly the reason why features need to get pulled from a release.
There is nothing wrong with basing feature branches on a stable branch. It seems the staging branch serves that purpose on your team. To support frequent releases, your team needs:
- A branch to integrate all work going into the next release.
- A way to accurately pull a feature out of a release.
- A way to track what has been deployed, and to which application environment.
- Good automated test coverage. If the team primarily does manual testing, then the testing effort is simply too labor intensive to support frequent releases.
- Coordination between developers and testers.
- This implies defining a cutoff date and time for new features moving into QA testing.
Even when your process is Kanban, the team needs to plan work. You cannot expect a feature branch merged into develop a day before the release to be fully QA tested, bug squashed and acceptance tested. When I see teams constantly "pulling features out" of a release, it indicates problems with planning and coordinating work. Git cannot fix this.
Work with your team on some of the process problems. Fixing these problems will involve more than changing how you use version control. Even so, consider some of the suggestions below as a part of the solution:
- Create one branch per release based on main.
- Don't merge a feature branch into a release branch until the team can commit to getting it done.
- Work with your team to define what is "ready for production" if this has not been identified.
- Squash commits from a feature branch when merging into the release branch.
- This makes easier to "pull a feature out of a release" because you only need to revert one commit, but you need to retest, so this isn't free. There is still a cost to doing this.
- Note that "pulling a feature out of a release" invalidates all QA testing for that feature up to the present time.
- Adding automated test coverage so regression testing requires less effort.
- This makes it easier to pull a feature out of a release.
- Once a release has been deployed, merge the release branch into main.
- Base all feature branches off of main.
The best place to start is addressing process issues with the team. Tools can only fix so much.