The .gitmodule
file only specifies the module repository url. How does git submodule
know which version to download? It seems to be always checking out the latest version. Then, how does developers ensure compatibility between the main project and the sub modules?
Its more accurate to say that git submodules are useful when you want to share code that you also need change along with the consumer of that code. If you're not trying to change the shared code along with the consumer of that code, there are better options for sharing your code.
In most cases, Git submodules are used when your project becomes more complex, and while your project depends on the main Git repository, you might want to keep their change history separate. Using the above as an example, the Room repository depends on the House repository, but they operate separately.
It is stored in Git's object database directly. The tree object for the directory where the submodule lives will have an entry for the submodule's commit (this is the so-called "gitlink").
It automatically pulls in the submodule data assuming you have already added the submodules to the parent project. Note that --recurse-submodules and --recursive are equivalent aliases.
Your submodule is represented as a special entry with a special mode (called a gitlink, see "Nested git repositories without submodules?"):
(See "Checkout past git submodule commit")
new file mode 160000 index 0000000..4c4c5a2
So it isn't checking out the "LATEST" version, but always a specific SHA1, and it does so in a DETACHED HEAD
mode (see "How to make submodule with detached HEAD
to be attached to actual HEAD
?".
That doesn't mean you can't update a submodule, as I explain in "true nature of submodules".
For more on submodules, and on potentially why you might not want to use them(!), read the sobering article "Why your company shouldn’t use Git submodules", from Amber Yust (also on SO).
Just one small extract, for kicks and giggles (emphasis mine):
When you invoke
git submodule update
it looks in the parent repository for a SHA for each submodule, goes into those submodules, and checks out the corresponding SHAs.
As would be the case if you checked out a SHA in a regular repository, this puts the submodule into a detached HEAD state.If you then make changes in the submodule and commit then, Git will happily create the commit… and leave you still with a detached HEAD. See where this is going yet?
Say you merge in some more changes which happen to include another submodule update. If you haven’t committed your own submodule change into the parent project yet, Git won’t consider your new commit in the submodule as a conflict, and if you run
git submodule update
it will happily wipe out your commit without warning, replacing it with that from the branch you just merged in.I hope you had your submodule’s
reflog
enabled or still have the old commit in your terminal scrollback, because otherwise, you just lost all that work you did.
Err... "ouch".
Note that now a submodule can track the latest from a branch: see "git submodule tracking latest".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With