Git and Visual Studio project references

Daniel P. picture Daniel P. · Feb 15, 2014 · Viewed 10k times · Source

Alrighty then, the short version of my question would be:

What is the best way to handle project references in Git when you have projects that are shared across multiple solutions and how should my Git repos be organized?

The long version is:

We are a small dev team(5 developers) and currently we use TFS as our source control and build server and Visual Studio is our IDE of choice. I've always been keen on trying new things and trying to improve our dev environment so I decided to read up on Git to find out if it would be good replacement for the source control part of TFS. We just integrated Jira into our workflow so I decided to try out Stash as our Git environment because of how well it integrates with Jira. I'm now in the process of trying to find out what way to organize the git repos and that is why I'm here. Now I'm going to describe how many of our solutions are organized.

We've got a bunch of solutions. Some are libraries and some are Programs that reference these libraries via Project reference in Visual studio.

So the main thing that confuses me would be how to handle libraries that are referenced in many solutions?

Should we start versioning our libraries and put every library in a separate repo? It seems like this way would involve a lot of extra maintenance when a library receives an update that has to be deployed and that library is being used by 20+ solutions. Am I wrong ? One more downside that I see is that there would be no more Project references in Visual studio and it would make debugging a lot more tedious.

Should I just make on big repo with all our solutions and that way all our references are up to date?

I also thought that maybe I could make our own nuget repository that has all theses libraries and that way it would not be as much of an hassle to update the referenced libraries when needed. This is just an idea and I have not looked into this properly so I'm not sure if this would be of any benefit.

So, are there any people out there that could give me some advice regarding this?

Answer

charleso picture charleso · Feb 15, 2014

This is one of those questions that unfortunately doesn't have a single answer - it depends.

The easiest solution is always to have a single repository. This avoids many of the problems of managing multiple repositories with different versions. But this only really works if you have a single version of everything; it's almost impossible to have different release cycles for two products in the same repository. That way lies madness. As repositories grow to any non-significant size it also doesn't really scale.

As Till points out, one option is Git Submodules. This will allow you to dynamically load the source of one repository in another at a specific commit or branch. Of course this comes with a whole host of problems, some specific so submodules and others are just the nature of linking repositories.*

Some people really like Git Subtree, which is somewhat cheating and lets you repeatedly extract and then import the history of a folder across repositories, and back again.

Finally, you can rely on a dependency management tool, depending on your build environment. I don't know enough about Visual Studio to comment. At Atlassian we (currently) use Maven to solve this. If you were using JS it might be NPM/Bower, on Ruby it's Gems. It can be frustrating to have to release a new version of Library X just to make a trivial change for Program Y, but for the most part it works well enough.

This is really an ongoing problem, and something I know vexes me on a daily basis. I feel like there could be an opportunity for a better solution that combines the best of submodules and dependency management, but I haven't found it yet.

I hope that helps?

* My own biggest gripe with submodules, tooling issues aside, is that it encourages people to check in absolute URLs to other repositories. This works perfectly until you decide to migrate your Git server, or one of the repositories, and now everything is broken. I found out the other day you can use relative paths, which is neat but doesn't solve the problem.