In a general sense, for long term projects that may have multiple releases during the products life cycle and require support of previous products, what is the best way to handle product versions and branching of the code base?
In a more specific sense, assume that proper distributed version control is in place (i.e. git) and that the teams are small to large in size and that developer may be working on multiple projects at ones. The major issue that is being faced is that there is a contractual obligation to support old versions as they existed at the time which means that new development can not patch old code (Microsoft Office products could be an example of this, you only get patches for the feature year you own).
As a result the current product versioning is a touch convoluted as each main product has multiple dependencies, each with their own versions which may or may change between annual releases. Likewise, while each product has its own repository, most of the work is not done on the main source trunk but rather on a branch for that years product release with a new branch being made when the product is released so that it may be supported. This in turn means that getting a product's code base isn't a simple matter as one might think when using version control.