Your whole argument hinges on "are conflicting with each other". I am confident that in many cases I would be able to put the X stuff in x_lib and the Y stuff in y_lib and link two different binaries for them, from head.
"put the X stuff in x_lib and the Y stuff in y_lib" is exactly what takes 4x amount of time
Also this process can continue. In the next iteration you have will 3 incompatible features with the same or different customers.
If you use different branches you can always to go to branch X and know exactly what is deployed on customer X.
In your case the only way to recreate what customer X has is to find the proper combination of libraries that you have shipped to them so far.
Imagine I am a developer and want to do a hotfix for a specific customer. I can just do git checkout branch-of-customer and start working. Isn't the process more difficult with your approach?
Also this process can continue. In the next iteration you have will 3 incompatible features with the same or different customers.
If you use different branches you can always to go to branch X and know exactly what is deployed on customer X.
In your case the only way to recreate what customer X has is to find the proper combination of libraries that you have shipped to them so far.
Imagine I am a developer and want to do a hotfix for a specific customer. I can just do git checkout branch-of-customer and start working. Isn't the process more difficult with your approach?