Creating a Git within a Git – aka, the Russian doll git


Using Felix’s technique works great.

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.