Package Manager vs. Git Submodule/Subtree
Asked Answered
A

2

30

Are there any reasons to use a package manager rather than git submodules/subtrees, or vice versa? The git solutions seem to be a lot more hassle than a simple package manager.

Assume that the space-saving benefit of git submodules is not important.

Aloisius answered 10/9, 2018 at 11:7 Comment(4)
I think using some kind of package manager is simpler than git submodules/subtrees... dependencies in languages like C#(nuget), node(npm) or rust(cargo) are never copied, only file with dependency list is in the repoMandiemandingo
I assume your question relates to C/C++ projects here?Mandiemandingo
@Mandiemandingo No, I was asking about package managers in general.Aloisius
Regarding hassle, it can go either way. A package manager may actually be more work if your main goal is just to modularize your code base. You then have to deal with versioning each module.Cantara
W
22

The git solutions seem to be a lot more hassle than a simple package manager.

This is not about hassle.

This is about two different ways to build a project:

  1. through binary dependencies, with a package manager (Nexus, or Conan for C++: you declare your dependencies, and the package manager fetches them and uses them during the compilation.
    That is what a pom.xml or a npm-package.json: just one more file within your unique codebase, which will instruct the compiler to download the relevant dependencies
  2. through source dependencies, with Git submodules or subtrees, where you store references to other source code, import them, and recompile everything.
    For instance, if your system is composed of a front-end GUI sources and a backend sources, you could reference both repositories within one parent project repositories, combining their sources into one code base.

The first is good when building a system, where each part has its own release lifecycle, and you want to depend to pre-built dependencies.

The second is used when the dependencies are more tightly linked to the main program.

Or when there are no binary dependencies (which is the case, for instance, with Go and its modules).

Welfarism answered 22/12, 2018 at 9:37 Comment(7)
What do you mean by more tightly linked?Mandiemandingo
By binary dependencies you mean linking to pre-built static or dynamic libraries?Mandiemandingo
@Mandiemandingo "tightly linked" means: you cannot modify the main project without modifying the dependencies. Recompiling everything is, in that instance, best.Welfarism
@Mandiemandingo yes, pre-built, meaning you can make many evolution to your project but would need the same dependencies: no need to recompile everything in that case. Pre-built artifacts are enough, and can be declared in a small text file, then fetched from an artifact repository, as I mention in the answer.Welfarism
I actually didn't know that some package managers fetch packages during compilation itself! The only ones I've ever had experience with just add packages to the source the second you declare the dependencies.Aloisius
@Welfarism could you please add examples for both scenes? not quite understand the differences and their applicationCooe
@Steve Sure, I have edited the answer to include some links and examples.Welfarism
C
21

"If the technological context allows for packaging and formal dependency management, you should absolutely go this route."

The above is from Mastering Git submodules, which is such a well written and thought out article it deserves to be the top answer for this and many similar Stackoverflow questions.

Let me quote the part that is relevant to this question:

Are they the right tool for the job?

There are a number of situations where the physical presence of module code inside container code is mandated, usually because of the technology or framework being used. For instance, themes and plugins for Wordpress, Magento, etc. are often de facto installed by their mere presence at conventional locations inside the project tree, and this is the only way to “install” them.

In such a situation, going with submodules (or subtrees) probably is the right solution, provided you do need to version that code and collaborate around it with third parties (or deploy it on another machine); for strictly local, unversioned situations, symbolic links are probably enough, but this is not what this post is about.

On the other hand, if the technological context allows for packaging and formal dependency management, you should absolutely go this route instead: it lets you better split your codebase, avoid a number of side effects and pitfalls that litter the submodule space, and let you benefit from versioning schemes such as semantic versioning (semver) for your dependencies.

Chavaree answered 22/5, 2020 at 17:54 Comment(3)
Answer is to the point and gives a nice link for further reading. thanks!Iridosmine
Careful about this article though, it is a bit dated and not everything written in it is still true. For example, git pull learned --recurse-submodules since it was written.Andyane
@Andyane of course, as will be the case for any article on shortcomings of git commands, as git evolves rather rapidly. But the argument it makes that answers the SO question above depends not at all on git flaws, but on fundamental differences between package managers and git submodules/subtrees. That won't change.Chavaree

© 2022 - 2024 — McMap. All rights reserved.