2

First of all, let me just say that this question may not fit on SoftwareEngineering.SE even though its similar to a "white-board" question. This question has to do specifically with Git so I figured I would ask it here on SO instead. This is more of a "how do I do it" or "what do I need to be concerned about" question... I also need to ask this question first so that I don't completely wreck one or more of my Git repositories.

Anyway, I have a Git repository for an application that I am currently building. This application has several submodules included, one for each of the libraries that the application depends on. Now, some of my submodules depend on one another. For instance I have a few different implementations in some submodules, that depend on some specific interface in a separate submodule.

I am thinking of making the interface library a submodule of each implementation library... Well, for the sake of this question it doesn't have to be an interface. Let's just say that there are libraries involved that have submodules of their own. Now to the question...

What if in the future I need to support two different implementations in a new application... What happens when I include both implementations as submodules to the application? Especially... What if a common submodule got updated... One implementation needs V1.0 and another implementation needs V2.0? Is there some kind of a conflict?

P.S. What I am really trying to get out of this question... Is a way to have my submodules each have a reference to a certain commit # (for the libraries they depend on) which they need in order to compile... If this isn't the right way, then I'm open to alternatives.

Snoop
  • 1,046
  • 1
  • 13
  • 33

1 Answers1

0

Is a way to have my submodules each have a reference to a certain commit # (for the libraries they depend on) which they need in order to compile

Ideally, those submodule should have submodules of their own.
The very nature of a submodule (that I detailed here) is to be a fixed SHA1 reference of a checked out repository.

The fact that submodule A depends on a common repo C, version 1, and submodule B depends on common C, version 2 only means that A and B have C has a submodule, but reference two different version of C.

However:

I guess I'll have to stick with the submodules until this project is finished. If I were to keep submodules of submodules, I don't really think that would work. I can't have multiple instances of a project in my solution... So projects couldn't include their own "personal" versions of dependencies they need..

In that case, you need to have a flat submodule organization.
That means: even those submodules have submodule of their own, you do not clone them recursively. You only clone the submodules of the parent repo (here: A, B, and the common C, all direct submodules of the main project parent repo)

git submodule update --init

That will checkout those submodules (without initializing/checkout the submodules of those submodules)

You end up with one project able to compile C, then B and A, then itself (provided that A and B use the same version of C).

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I guess the submodules have to exist within each submodule's respective folder... So there wouldn't be any kind of conflict... But it's kind of weird to reference them in my projects like that. I really wish they could all just go at the same directory (in the application repository folder). Not sure how to go about that. – Snoop May 04 '17 at 13:18
  • @Snoopy I agree, but since those dependencies can be at different version, it is best they remain "duplicated" in their respective parent submodule rather than trying to cram them all in a "common" folder. – VonC May 04 '17 at 13:20
  • You make a really good point... How do you think that fits in with say... a C# project consisting of a bunch of class library projects? – Snoop May 04 '17 at 13:21
  • @Snoopy in a C# project (or a java one, for that matter), the dependencies are *not* expressed in term of *source* dependencies (submodules), but in term of binary dependencies: this is a declarative approach (in a .nuspec https://learn.microsoft.com/en-us/nuget/schema/nuspec, or for Java a pom.xml). It allows the build process to fetch the compiled libraries from an artifact referential (like Nuget, or Nexus) – VonC May 04 '17 at 13:24
  • @Snoopy That means any modification to those fetched libraries are done in their respective repositories, cloned once, compiled, published (to Nuget or Nexus), for other projects to use. – VonC May 04 '17 at 13:25
  • Hmm... Do you mean packages that were pulled in from something external like Nuget or Nexus? I guess those would be binary dependencies... But what is to be done with the dependencies for which we've written all the source code in house? I've always included those in our projects (as submodules) on a regular basis. So I guess I am a little confused by your statement. – Snoop May 04 '17 at 13:27
  • @Snoopy "I guess those would be binary dependencies": yes, exactly what I said: "in a C# project (or a java one, for that matter), the dependencies are not expressed in term of source dependencies (submodules), but in term of **binary dependencies**" – VonC May 04 '17 at 13:28
  • @Snoopy Example of this approach, written yesterday(!): https://www.benday.com/2017/05/03/walkthrough-use-a-package-from-a-private-nuget-server-in-tfs2017/ – VonC May 04 '17 at 13:29
  • @Snoopy "I've always included those in our projects (as submodules) on a regular basis": my point is: you don't have to. This is not the only approach. – VonC May 04 '17 at 13:30
  • "you don't have to. This is not the only approach." - but it is a valid approach right? And that's the approach we're stuck with for now, but I do like the idea of using Nuget... In the mean-time I guess I'll have to stick with the submodules until this project is finished. If I were to keep submodules of submodules, I don't really think that would work. I can't have multiple instances of a project in my solution... So projects couldn't include their own "personal" versions of dependencies they need... – Snoop May 04 '17 at 13:33
  • "but it is a valid approach right": absolutely, and it is one I detail in my answer above. "If I were to keep submodules of submodules, I don't really think that would work. I can't have multiple instances of a project in my solution" I agree. In that case, you need to make sure A and B submodules are using the *same* version of common submodule C. – VonC May 04 '17 at 13:36
  • "you need to make sure A and B submodules are using the *same* version of common submodule C." - So I guess I have one more question before I let you go... Say that A and B both contain the same version of submodule C...a cloned copy of C is sitting inside of both A and B respectively... which "C" gets referenced in the application's solution? And... If I choose one or the other, doesn't that mean either project A or project B will get *modified*? – Snoop May 04 '17 at 13:40
  • @Snoopy In that case, you need a flat organization of those submodules. See my edited answer above. – VonC May 04 '17 at 13:45
  • It is now evident that I didn't mention: I haven't actually made my class libraries have submodules of their own just yet... I was only playing with the idea. This idea of a flat submodule organization is exactly what we're doing now. We just have to be diligent and always update all the class libraries to make sure their most recent versions all work with one another (which is kind of a drag)... Know of any site/forum where I can discuss this idea at length? – Snoop May 04 '17 at 13:50
  • @Snoopy "We just have to be diligent and always update all the class libraries to make sure their most recent versions all work with one another (which is kind of a drag)" you don't have to: you can make those submodule follow their own master branch: http://stackoverflow.com/a/18799234/6309. Then a simple `git submodule update --remote` would be enough to update all your submodules. – VonC May 04 '17 at 13:51
  • @Snoopy "Know of any site/forum where I can discuss this idea at length?" Yes: me: http://stackoverflow.com/tags/git-submodules/topusers ;) – VonC May 04 '17 at 13:52
  • Yeah but I'm sure you're busy with other things, and might not have time to deal with a Git noob like myself... I started reading through stackoverflow.com/a/18799234/6309 and it was just too complicated... I need to understand what *tracking* and some of the other concepts are first... Right now I only really understand commit/push/submodule/clone... nothing more. – Snoop May 04 '17 at 13:56
  • @Snoopy It as a tongue-in-cheek comment ;) Still "might not have time to deal with a Git noob like myself": I have been doing that for the past 8 years. Every day. I mean, *actually* every single day: https://meta.stackexchange.com/q/122976/6309. And compared to http://stackoverflow.com/users/1256452/torek, I consider myself as a noob ;) – VonC May 04 '17 at 13:59
  • @Snoopy you can also read http://stackoverflow.com/a/9189815/6309: `git submodule add -b master [URL to Git repo]` is *all* it take for your submodule to start following its own branch. – VonC May 04 '17 at 14:00
  • Yeah I guess that could be interpreted as tongue-in-cheek... But I meant more along the lines of dealing with one single person at length, in which case you might not have time. But thanks again, for all of the quick responses and addressing this convoluted/confused question. – Snoop May 04 '17 at 14:01