Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
390 views
in Technique[技术] by (71.8m points)

how exactly does git submodule work

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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".


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...