Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Git Submodules as a Package Manager (nesbitt.io)
72 points by ErenayDev 13 hours ago | hide | past | favorite | 15 comments
 help



FYI A submodule doesn't have to use a gitfile and a corresponding `$GIT_DIR/modules/<name>` and there are good reasons not to. As long as the submodule has a '.git' it can be a symlink, or regular .git directory for a self contained embedded repo. You can still use the same gitlink in the parent repo representing it's commit id and git will still manage it.

If I have a 20GB submodule I'd usually just do a `git clone <url> <path> && git submodule add <path>` and it will be treated the same by git. But now I can just delete it and it's purged. And it is more portable less fragile in some ways because it's not de-referencing a gitfile. I prefer my repos to be more bottom-heavy and to not clog my modules folder.

I have a rough script that's the inverse of `git submodule absorbgitdirs` but it's a bit fragile.

It would be cool if there was some plumbing to expose this a bit more.


A lot of the confusion and criticism surrounding submodules comes from people not understanding that you do not need to learn a lot of new commands to use them: you just cd into the submodule and use it as a normal git repo. Then you cd out and commit the submodule hash change if that's what you want to do.

Some things are annoying, like removing them. But in general they're extremely useful and designed basically exactly how you'd want: it's extremely consistent since to a good approximation, a submodule behaves the same as a normal git repo once you're inside it.


I disagree, even when you understand them there are still big problems with them:

1. Git doesn't support them very well. Bugs are disappointing frequent. Try changing a submodule to a directory or vice versa and feel the pain.

2. They are often used to split up projects (especially commercially) but this makes testing much harder and cross-repo changes way way harder. Even changes that only touch the submodule become way more tedious because you have to always do another PR to update the pointer.

3. The submodules are referenced by URL, which means you can't easily move or copy projects that have them because they still point to the old submodule location. Sometimes they're even misconfiguration to always use ssh:// or whatever, breaking unauthenticated clones.

4. Switching branches where submodules have been added/removed is a mess.

5. Having to constantly remember `git submodule update --init --recursive` is a right pain.

6. When used as a crap dependency manager you easily end up with duplicates. A project I worked on had 12 copied of a common submodule via transitive dependencies.

IMO they're almost always the wrong solution.


> Git doesn't support them very well. Bugs are disappointing frequent

I can't remember any "bug" in the submodule machinery. If you find one, report to the Git mailing list, they very receptive.

> Having to constantly remember `git submodule update --init --recursive`

Set this config: `git config submodule.recurse true`

> IMO they're almost always the wrong solution.

Yeah... but sometimes they are the only feasible solution, especially when the dependency needs to be shared across projects that use incompatible dependency managers and Git is the only common denominator between them...


I know it sa toy, but if someone gets the bright idea to do this for real: please learn from npm and dont duplicate packages for every clone of a project. Share them between projects like every sane package manager.

> Share them between projects like every sane package manager.

I'd argue the other extreme is less sane. Pip installs everything system wide and you can't have different versions of the same package without venv.

Even early NPM was much much better than the pre-uv Python situation. (TBH even with uv it still feels hacky at times.)


Before uv there was poetry, and before poetry there was pipenv, before pipenv there was virtualenv. I wish people would stop portraying Python tooling completely wrong like that. uv is not the first tool to solve most problems in this space. It may be the best performing though and may be the best overall currently.

Virtual venv existed before uv. So you could still just generate a virtual venv and then use pip to install packages in the local venv. (2007: virtualenv was released as a third-party tool).

The global repository should support versions obviously.

If you can point a package manager at a git repo and use it like package, this is accidental convenience. Source code repositories should be factored as source code, with a build step to transform them into packages. For some languages that means compilation, for others it means transpiling, minifying, or just copying files. The resulting artifact is a different shape, designed for consumption.

If you use git for packages, then your repo becomes the package boundary. You no longer have the option of producing multiple packages from one repo, or even one package from multiple repos.


> If you use git for packages, then your repo becomes the package boundary. You no longer have the option of producing multiple packages from one repo, or even one package from multiple repos.

What does this even mean?

I'd argue that having the source to build the thing is more important than the artifacts. Release artifacts are more of a convenience. If the thing doesn't build from the source given, what use is it?


Exactly my point. You assume the source is the thing you want to consume, but it isn't. Package registries are much more than a convenience and packages don't necessarily map 1:1 with source code repositories. Nor should they need to. You shouldn't have to build every dependency and care where their source code is.

Sure you want the source available, otherwise it's closed source, but ideally you never need to look at it unless you're a contributor.

git has really conflated the two concepts.


I just have a feeling the developer-experience wouldn't be the same - but that's just a temporary issue perhaps?

I find https://github.com/andrewmcwattersandco/git-fetch-file more useful. It's manifest is nearly the same as a .gitmodules file, but having specific control over what files you want to pull, or what commit or tag, or just the equivalent of latest is way more practical day-to-day.

How does this compare to `git subtree`, which is part of git itself ?



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: