...often there are untested changes waiting in the test branch which delays delivery of hot fixes for critical bugs in production.
Is there a method that allows for easy hot fixes and not introduce the risk of untested differences when having a separate release branch?
Yes, there is. The problem you've encountered is being caused by a bug in the workflow:
feature2 --> test --> release
As you've seen, if the features take time to test thoroughly, they act as a barrier for getting the hot fix through the pipeline. The takeaway there is that if you need to get a release out quickly, there shouldn't be anything in the release pipeline that isn't very close to being ready.
You can prevent that by moving the barrier ahead of the release part of the pipeline so that any delays in testing a change stay with the change:
feature1 --> feature1-test \
feature2 --> feature2-test --> release-test --> release
hotfix1 --> hotfix1-test /
When a change is finished, it goes into a separate branch where it is tested. As long as testing is underway, all work on that change happens between the two branches. After testing has approved it, the tested code is merged into a pre-release testing branch where the full test battery is run once more before release. (In theory, this should be a formality and a non-event; I'll explain why later.) This means you can take a long as you want testing
feature1 without delaying
feature2 or the
One important thing that's frequently overlooked is feedback. Whenever a release happens, that code needs to be merged into all branches where development and testing are being done. If
feature1, you want to find that out in
feature1-test so it can be fixed there and won't stand in the way of a release containing
hotfix2. If the feature integrates the released changes early, there should be fewer surprises in
release-test. This arrangement allows you to treat hotfixes and features the same way from a development perspective and leaves the decision whether to subject a hotfix to the full battery of testing or fast-track it a matter of QA policy. The workflow is the same no matter what, and there isn't a quick branch/merge from/to the
NB: What's described here is a bit of an oversimplification because it doesn't take into account something in
feature1 breaking something in
feature2. This arrangement can be used in more-complex structures where
integration-test and that feeds