Git Fake Submodules
Posted on 20/1/10 by Felix Geisendörfer
Git submodules suck. They are a pain to use, difficult to explain and you cannot check out partial trees. The later is an inherent limitation of git, but I have a fix for the rest.
Meet fake submodules. The idea is simple, instead of using actual submodules, you just trick git into thinking the files belong to the main repository while having the respective sub-dirs remain independent clones. Doing that is simple:
$ cd my-project $ git clone <subproject-url> my-subproject $ git add my-subproject/
The important part is the "/" (slash) at the end of the last command. If you omit that, git will automatically assume you want to add 'my-subproject' as a submodule. But if you don't, git just sees the files in the sub-directory and ignores that fact that its a git-repo of its own.
The cool thing is that you can now update a fake sub-module to the latest version as simple as:
$ cd my-subproject $ git pull
This works because when you are inside
my-subproject, git uses the '.git' folder closest to it which is
my-subproject/.git. If the sub project is your own, you could even push your changes to it upstream without changing projects.
Now as far as collaboration is concerned, none of your collaborators will have a clue about your fake submodules. All they will see is some code in some folder. They will not be able to go into the
my-subproject folder and git pull on it. However, if they need to do that, they can just
rm -rf my-subproject and replace it with a clone themselves.
To me this is a pretty perfect & easy solution. I mostly use it for CakePHP plugins & node.js modules I am working on, but it works just as great with other peoples code you want to depend on. You can even apply hacks against their code, have them in your main repository, and make sure they stay applied on top by using 'git pull --rebase' when updating the sub project.
Let me know what you think!
You can skip to the end and add a comment.
To your point about collaborators not seeing the sub-projects, what about generating a script for them to run that cd's into each sub-project directory and runs the correct git commands (init, remote add, etc.) ? Would that work about the same?
Joel Perras: Seems an aweful more complex for doing the same thing "Fake Submodules" can do. Am I missing something?
Nate Abele: By not "seeing" them, I guess you mean that they don't see them as seperate git repositories? Yes, you could have a script in place that helps people who want to actively use those sub directories as fake sub modules.
I was looking at different solution for a better submodule integration a few days ago, and found this bash script (http://imyousuf-tech.blogs.smartitengineering.com/2008/01/propagating-git-commands-to-its.html) which might interest you.
It looks like an implementation of what Nate proposed in his comment, but I have not tested it yet ...
PS: I tried to embed the link in an "a href" tag, but the system took it as spam :/
@Felix: It's actually very little overhead. The example given at kernel.org is probably the most illustrative:
Commands 1-4 are the ones needed to setup a subtree (which can easily be scripted), and #5 is the only one needed to merge in updates from the 'submodule'.
P.S. Your comment system doesn't seem to let me use 'code' tags.
Joel Perras: That is still much harder to explain to somebody who's not a git nerd. I would consider it if there was some advantages to it, but as far as I can tell its doing the same thing using more commands and a more complex approach.
Perfect. So much easier than submodules. We've been trying to use them for ages and their a major PITA. Hooray for googling "git submodules suck"!
Not only does this trick remove the headache of constructing Git submodules, but people who clone the repository get THE WHOLE THING without needing to enter extra commands (git submodule init, etc).
This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.
Subtree merging is usually the accepted method of 'faking' submodules without using submodules.