You seem to assume that developing a feature requires a feature branch. In this case, the canonical branching would look like:
\ \--A--/ \ /
\--B--/ \ /
But what happens if after the merge, adjustments are required for A and B? What if furthermore these appear to be required for C? And what if all those features depends on some other code that evolves with impact on all the three? The longer the feature branching, the more painful it might get.
Let me now challenge your assumption: What if you gave up your feature branching for a continuous integration, e.g. like trunk based development?
Of course this is not hat you're asking for. But it has the advantage of putting dependency management where it belongs: not in git (the tool) but into the team (the people). The team could easily work together to understand the dependency and overcome it in a creative manner, for example:
- Define common interfaces early - as soon as these are ready C could start, and with lower risks of rework
- Start to develop a stub or a mock for A and B, on which C could lean on. Then everybody could concentrate on the independent parts.