We have 5 or 6 web developers that typically work on the same repository, developing independent features. Features are developed, tested and deployed as soon as they're ready; we do not bundle up feature, nor do tagged releases that contain everything slated for production at that time.
Feature branches are built off main and developers code locally. Once a feature is ready for an internal review by non-developers, it's merged into our "development" branch which is deployed to a dev environment. It's entirely possible, and highly likely, this development branch and environment contain multiple in-flight features from other developers who have also reached a point where their project is ready for internal review by non-developers. There are, of course, merge conflicts that are dealt with at the time of the merge. The devs work together to determine how to resolve.
Once a feature has passed internal review and is ready for QA, the feature branch (based on main) is merged into a staging branch and deployed to a QA environment. As with the dev branch/environment, this one will have other in-flight projects that have reached QA - though it is typically fewer features than are residing on dev.
Once a feature has passed QA and ready to be deployed, the feature is merged into main and deployed. This generally results in 0 merge conflicts as the branch was based on main to begin with and, ideally, the developer has periodically merged main into their feature to pull in new production code over the course of their feature development.
This setup has worked really well for us, but a new developer has suggested we build our features off the "develop" branch. The articles I've read that also suggest that approach tend to lean towards tagged releases where multiple features are all bundled together and the entire "develop" branch is merged into main as a release. I just do not see how that is possible with our workflow, given that features are released as they're finished and multiple features are in flight at any one time, all in various stages on development.
Our GitLab setup has the pipeline ID (which is monotonically increasing and disambiguated by gitlab itself) as "the version," which for all intents and purposes is only the docker image tag of the underlying build but is, without a doubt, "the version" of that review environment from the UI's perspective
So, hypothetically, if one wanted to file a bug report against a review environment there is unquestionably a "version" number to populate into the ticket. It could be the git sha of "the deployment," or it could be the version of the UI against which the bug was filed, depending on how widely the organization views "this combination of software should work but does not" ownership
I recognize this word-soup isn't a tl;dr answer to your question, but since this is an Ask HN this is my Answer HN, and I'll draw the reader's attention to https://en.wikipedia.org/wiki/Conway's_law for the ultimate ground truth of any such answer