Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set up my git repositories to easily be able to reuse projects in Visual Studio

My problem may be best described with an example.

Assume I have a project "A".

I also have a project "B" which depends on "A".

Another project "C" also depends on "A".

My "main" project depends on "B" and "C". It may also be that it also depends directly on "A".

Looks a bit like the "dreaded diamond of inheritance" when "main" == "D"

dreaded diamond of inheritance

These are my requirements:

  • I'd like to be able to edit the content of projects "A", "B" and "C" in the solution for "main " and submit changes (i.e. I don't want just to include the DLL but also the code). But since "B" and "C" both depend on "A", it should be enforced that they reference the same commit.

  • The projects "A", "B" and "C" will most likely also be referenced by other projects, so I cannot assume ownership of the working directory for project "main".

  • Also it should be possible to sync the repositories for each project with external repositories.

  • The projects "A", "B", "C" and "main" should be

How do I need to set up my repositories to accomplish this?

like image 906
Onur Avatar asked Oct 30 '13 12:10

Onur


2 Answers

Do not (ab)use git or any version control system for this.

Use NuGet.

You don't want to directly include other projects. Instead, pack every dependency into a .nuget package and use that for dependency handling. While submodules seems a solution to the problem, in practice, you are much better off using a proper dependency management instead of just including other projects.

TeamCity and other CI systems, even TFS, allow you to automatically build new nuget packages, and TeamCity can also act as a nuget server.

And if you do not want to use a 'real' NuGet server, you can also just use a shared drive somewhere on your intranet.

like image 145
Wilbert Avatar answered Sep 27 '22 23:09

Wilbert


Using the submodules approach, I would recommend a model which includes a list of dependencies, instead of a hierarchy of dependencies:

Create a "parent" repo, in which you "git submodule add" the submodules for D, C, B and A:

parent
  D
  C
  B
  A

Add any symlink (even in Windows) you need for each project to compile (meaning to find the sources for their dependencies right from within there own structure).

The "parent" repo will reference the exact list of SHA1 representing each dependencies at their exact version needed for the project to compile/run at a specific time in the history of the parent repo.

And, as I explain in "true nature of submodules", you can make any modification you want in A, B, C or D, and push to their respective upstream repo.
But you must not forget to go back to the parent repo, add and commit the SHA1 modifications representing the new state of the dependent repos A, B, C, and D.

This is a component approach, which has the advantage of resolving any overlapping dependency: if B and C need a different version of A, the parent repo will have to chose one (and only one) version of A.

To add to the OP Onur's answer:

Dependencies must be relative

Not necessarily: you can add symlink within a submodule, if it needs to see another with a fixed path.

Create the "user" repository

How do I automatically check out the correct set of libraries, e.g. A and B in the setup above

Once you have determined valid starting version for A and B, you can create and push a branch dedicated for their usage in a "parent" context.
Then you make those submodule follow that branch, meaning any git submodule update --remote will checkout the latest SHA1 of that dedicated branch for submodules A and B.

like image 22
VonC Avatar answered Sep 27 '22 22:09

VonC